オブジェクト指向でじゃんけん

## はじめに
最近Javaを勉強し始めたので、オブジェクト指向で何かを作ってみたかった。

## 流れ
①名前を入力する。(相手の名前はランダムに決まる。)
②出す手を選ぶ。(相手の手はランダムに決まる。)
③結果を出力する。
④終わり。(今回は一回だけの勝負です。)

## クラスたち

①Janken.java
メインの関数です。

```java:Janken.java
public class Janken {
    public static void main(String[] args) {
        Player you   = new You();
        Player enemy = new Enemy();

        System.out.print("おなまえを入力して下さい。： > ");
        you.setName();
        enemy.setName();
        String yourName  = you.getName();
        String enemyName = enemy.getName();
        System.out.println("あなたの　なまえは　" + yourName);
        System.out.println("あいての　なまえは　" + enemyName);

        Hand yourHand  = you.nextHand();
        Hand enemyHand = enemy.nextHand();

        System.out.println(yourName   + "は　" + yourHand  +  "  をだした。");
        System.out.println(enemyName  + "は　" + enemyHand +  "  をだした。");

        if (yourHand.winTo(enemyHand)) {
            System.out.println(yourName + "　のかち！");
        } else if (yourHand.loseTo(enemyHand)) {
            System.out.println(yourName + "　のまけ…");
        } else {
            System.out.println("あいこです。");
        }
    }
}
```
②Player.java
プレイヤーの大雑把な情報を持つ抽象クラスです。
このクラスを継承して、あなたと相手のクラスを作ります。

```java:Player.java
public abstract class Player {
    protected String name;

    public String getName(){
        return this.name;
    }

    public abstract void setName();

    public abstract Hand nextHand();
}
```

③you.java

```java:You.java
import java.util.*;
public class You extends Player {
    @Override
    public void setName() {
        Scanner scanner = new Scanner(System.in);
        String name = scanner.nextLine();
        this.name = name;
    }

    @Override
    public Hand nextHand() {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.print("何を出しますか? グー:0 チョキ:1 パー:2  > ");
            try {
                int hand_number = Integer.parseInt(scanner.nextLine());
                if (0 <= hand_number && hand_number <= 2) {
                    return Hand.fromInt(hand_number);
                } else {
                    System.err.println("範囲外の数字が入力されています。");
                }
            } catch (NumberFormatException e) {
                System.err.println("数字以外が入力されています");
            }
        }
    }
}
```

④Enemy.java

```java:Enemy.java
public class Enemy extends Player {
    private final String[] names = {"安倍", "小泉", "麻生", "菅"};

    @Override
    public void setName() {
        String enemyName = names[(int) (Math.random() * names.length)];
        this.name = enemyName;
    }

    @Override
    public Hand nextHand() {
        return Hand.fromInt((int) (Math.random() * 3));
    }
}
```

⑤Hand.java
列挙型のクラスを使いました。

```java:Hand.java
public enum Hand {
    Rock,
    Scissors,
    Paper;

    @Override
    public String toString() {
        switch (this) {
            case Rock     : return "グー";
            case Scissors : return "チョキ";
            case Paper    : return "パー";
        }
        throw new IllegalStateException();
    }

    public static Hand fromInt(int n) {
        switch (n) {
            case 0 : return Rock;
            case 1 : return Scissors;
            case 2 : return Paper;
        }
        throw new IllegalArgumentException(Integer.toString(n));
    }

    public boolean winTo(Hand hand) {
        switch (this) {
            case Rock     : return hand == Scissors;
            case Scissors : return hand == Paper;
            case Paper    : return hand == Rock;
        }
        throw new IllegalStateException();
    }

    public boolean loseTo(Hand hand) {
        return this != hand && !this.winTo(hand); 
    }
    
}
```

以上。
敵いっぱい作ってトーナメント戦やったり、作戦クラスを作ってみるのも面白そうですね。
改善点あればよろしくお願いいたします。