import java.util.Random;
import java.util.Scanner;
public class Hand  implements Comparable<Hand> {
    public static final int ROCK =      0;
    public static final int PAPER =     1;
    public static final int SCISSORS =  2;
    public static final int HANDS =     3;
    private final int form; // Possible values: ROCK, PAPER or SCISSORS
    public static final int WINS =      1;
    public static final int TIES =      0;
    public static final int LOOSES =   -1;
    private static final Random randomGenerator;
    private static final Scanner in;
    static { // Static Initialization Block
        // Executed statically only once (when the class is loaded)
        randomGenerator = new Random();
        in = new Scanner(System.in);
    }
    { // Instance  Initialization Block
        // Executed non-statically every time an object instance is constructed
        // It is executed before the code in the constructor method
        // Therefore, the form attribute hasn't been set yet.
        System.out.println("Hand ready!");
    }
    public Hand(int form) {
        this.form = form;
    }
    public Hand() {
        this.form = randomGenerator.nextInt(HANDS);
    }
    public static Hand randomHand() {
        return new Hand(randomGenerator.nextInt(HANDS));
        // Don't forget the "new" keyword. Otherwise:
        // "Cannot find symbol. Symbol: method Hand(int)"
    }
    public static Hand askHand() {
        String form;
        char c;
        do {
            System.out.println("Form? [r]ock, [p]aper or [s]cissors");
            form = in.nextLine();
            c = form.charAt(0);
        } while (c != 'r' && c != 'p' && c != 's');
        switch (c) {
            case 'r':
                return new Hand(ROCK);
            case 'p':
                return new Hand(PAPER);
            case 's':
            default:
                return new Hand(SCISSORS);
        }
    }
    @Override
    public int compareTo(Hand other) {
        /*
            | R| P| S| <- this          | R| P| S| <- this 
          --+--+--+--+                --+--+--+--+         
        o  R| 0| 1| 2| this.form-   o  R| T| W| L| this:   
        t --+--+--+--+ other.form   t --+--+--+--+ - Wins  
        h  R|-1| 0| 1|              h  R| L| T| W| - Looses
        e --+--+--+--+              e --+--+--+--+ - Ties  
        r  R|-2|-1| 0|              r  R| W| L| T|         
          --+--+--+--+                --+--+--+--+         
        */
        switch (this.form - other.form) {
            case 1:
            case -2:
                return WINS;
                // break; // If present "unreachable statement"
            case 2:
            case -1:
                return LOOSES;
            case 0: // Obviously not needed
            default: // If not present "missing return statement"
                return TIES;
        }
    }
    @Override
    public String toString() {
        switch (form) {
            case ROCK:
                return "rock";
            case PAPER:
                return "paper";
            case SCISSORS:
            default:
                return "scissors";
        }
    }
}
