Javaでじゃんけんプログラムを作る (その1)

Javaでじゃんけんをするプログラムを作成してみます。第 1 回は、実行することを順に main メソッドに記述してゆくスタイルです。

じゃんけん実行の流れは、次のようになります。この流れを終了が入力されるまで繰り返します。

  1. あなたが出す手を読み込みます。
  2. コンピュータが出す手を乱数で生成します。
  3. あなたが出す手とコンピュータが出す手を表示します。
  4. 勝ち、負け、あいこを判断して表示します。
  5. 終了するか継続するかを読み込み、その指定に応じて実行します。

プログラムの最初は、プログラムを説明するコメントと使用するクラスライブラリのインポートです。

// Janken_1 --
//    じゃんけんプログラムの第 1 バージョンです。
//    あなたとコンピュータでじゃんけんをします。

// 使用するクラスライブラリをインポートし、パッケージ名なしでクラス名だけで使えるようにします。
// java.io からは複数のクラスを使うので、'*' ですべてインポートします。
import java.io.*;
import java.util.Random;

次は、クラスの定義とmainメソッドです。このプログラムでは、例外は処理しません。そのため、発生する可能性のある例外を throws に続けて記述します。

// じゃんけんするクラスを定義します。クラス名は Janken_1 にします。
public class Janken_1 {
	
	// main メソッドを定義します。処理せずに呼び出し元にまかせる例外を記述します。
	// このプログラムで例外が発生した場合、処理していないので、プログラムは実行を終了します。
	public static void main(String[] args)
			throws IOException, NumberFormatException {

じゃんけんで出す手は整数値を使い、グーは 0、チョキは 1、パーは 2 で表すことにします。乱数発生のときに指定する境界値として HAND_BOUND を定義します。これらは値を変更しないので final を指定します。

		// グー、チョキ、パーの値と乱数発生の境界値 HAND_BOUND を定義します。
		// final を指定したので、これらの値は変更できません。
		final int GU = 0;
		final int CYOKI = 1;
		final int PA = 2;
		final int HAND_BOUND = 3;

プログラムの実行に必要な変数を宣言し、初期化します。使用する変数は、入力した内容を読み取るもの、乱数を発生させるもの、および終了するかどうかを保持するものがあります。値を変更しないものは final を指定します。

		// 入力した内容を読み取る InputStreamReader と  BufferedReader クラスの
		// インスタンスを作成します。これらの値は今後変更しないので、final にします。
		final InputStreamReader isr = new InputStreamReader(System.in);
		final BufferedReader br = new BufferedReader(isr);

		// 乱数を発生する Random クラスのインスタンスを作成します。この変数も final です。
		final Random rand = new Random();
		
		// じゃんけんを終了するかどうかを保持する変数 exitJanken を宣言します。
		// この変数の値は、入力した内容に応じて設定します。
		boolean exitJanken;

開始のメッセージを表示し、do ... while の繰り返しを始めます。

		// 開始のメッセージを表示します。
		System.out.println("じゃんけんしましょう。");

		// 終了するまで、じゃんけんを繰り返します。少なくとも 1 回は中身を実行するため
		// do ... while ループにします。
		do {

あなたが出す手を読み込みます。グー、チョキ、パーを表わす値の 0、1、2 のいずれかが入力されるまで繰り返します。

			// あなたが出す手の値を格納する変数 yourHand を宣言します。この変数の値は、
			// 入力の内容に応じて設定します。
			int yourHand;
			
			// あなたが出す手を読み込みます。グー、チョキ、パーのいずれかが入力されるまで繰り返します。
			for ( ; ; ) {
				// 入力を促す文字列 prompt を作成して表示します。
				final String prompt = String.format(
						"なにを出しますか (%d:グー、%d:チョキ、%d:パー)? ",
						GU, CYOKI, PA);
				System.out.print(prompt);
				
				// 入力された <Enter> までの 1 行の文字列を読み込み、変数 yourInput に代入します。
				// 次に yourInput を整数として解釈し、その値を変数 yourHand に代入します。
				// yourInput は、値を設定したあとは参照するだけなので、final にします。
				final String yourInput = br.readLine();
				yourHand = Integer.parseInt(yourInput);
				
				// yourHand が GU あるいは CYOKI あるいは PA ならば、繰り返しを終了します。
				if (yourHand == GU || yourHand == CYOKI || yourHand == PA) {
					break;
				}
				
				// 入力された値に問題があることを示すメッセージを作成し表示します。
				final String errorMessage = String.format(
						"'%s' が入力されました。%d、%d、%d のいずれかを入力してください。",
						yourInput, GU, CYOKI, PA);
				System.out.println(errorMessage);
			}

コンピュータが出す手を生成します。乱数を使います。

			// 乱数を使ってコンピュータの出す手を決めます。Random.nextInt(int bound) メソッドは、
			// 0 以上 bound-1 以下の値を無作為に生成します。
			final int computerHand = rand.nextInt(HAND_BOUND);

あなたの手とコンピュータの手を表示します。

			// あなたの手とコンピュータの手を表示します。
			System.out.println("あなたの手:    " + yourHand);
			System.out.println("コンピュータの手: " + computerHand);

勝ち、負け、あいこを判断します。このプログラムでは if ... else if ... else ... でそれぞれの場合を分けて、結果を表示します。

			// 勝ち、負け、あいこを判断します。
			// あなたの手は グー、チョキ、パーの 3 種類。それらに対してコンピュータの手が
			// グー、チョキ、パー の 3 種類あります。あなたの手とコンピュータの手の組み合わせは
			// 3 x 3 = 9 通りになります。それぞれの場合を if .. else if ... else で
			// 場合分けして処理します。
			if (yourHand == GU) {
				if (computerHand == GU) {
					// 場合 1 -- あなた: グー、コンピュータ: グー
					System.out.println("あいこです。");
				}
				else if (computerHand == CYOKI) {
					// 場合 2 -- あなた: グー、コンピュータ: チョキ
					System.out.println("あなたの勝ちです。");
				}
				else {
					// 場合 3 -- あなた: グー、コンピュータ: パー
					System.out.println("コンピュータの勝ちです。");
				}
			}
			else if (yourHand == CYOKI)  {
				if (computerHand == GU) {
					// 場合 4 -- あなた: チョキ、コンピュータ: グー
					System.out.println("コンピュータの勝ちです。");
				}
				else if (computerHand == CYOKI) {
					// 場合 5 -- あなた: チョキ、コンピュータ: チョキ
					System.out.println("あいこです。");
				}
				else {
					// 場合 6 -- あなた: チョキ、コンピュータ: パー
					System.out.println("あなたの勝ちです。");
				}
			}
			else {
				if (computerHand == GU) {
					// 場合 7 -- あなた: パー、コンピュータ: グー
					System.out.println("あなたの勝ちです。");
				}
				else if (computerHand == CYOKI) {
					// 場合 8 -- あなた: パー、コンピュータ: チョキ
					System.out.println("コンピュータの勝ちです。");
				}
				else {
					// 場合 9 -- あなた: パー、コンピュータ: パー
					System.out.println("あいこです。");
				}
			}

プログラムを終了するか継続するかを入力してもらい、入力された内容に応じて判断します。

			// 終了するか継続するか尋ねるメッセージを表示し、ユーザの入力を読み込みます。
			// 入力された文字列が "y" で始まっていれば、変数 exitJanken の値を True に、
			// それ以外で始まっていれば False に設定します。
			System.out.print("終了しますか (y:終了、それ以外:継続)? ");
			final String exitInput = br.readLine();
			exitJanken = exitInput.startsWith("y");
			
		// 変数 exitJanken の値が True でない間、ループを繰り返します。
		} while (!exitJanken);

最後に、プログラムの終了メッセージを表示します。

		// 終了のメッセージを表示します。
		System.out.println("じゃんけんを終了します。");
	}
}

プログラムを実行したときの画面表示は、次のようになります。

じゃんけんしましょう。
なにを出しますか (0:グー、1:チョキ、2:パー)? 0
あなたの手:    0
コンピュータの手: 2
コンピュータの勝ちです。
終了しますか (y:終了、それ以外:継続)? 
なにを出しますか (0:グー、1:チョキ、2:パー)? 3
'3' が入力されました。0、1、2 のいずれかを入力してください。
なにを出しますか (0:グー、1:チョキ、2:パー)? 2
あなたの手:    2
コンピュータの手: 2
あいこです。
終了しますか (y:終了、それ以外:継続)? y
じゃんけんを終了します。