【Java】じゃんけんアプリをつくろう⑥～後出しじゃんけん～

前回は3人でじゃんけんするアプリをつくりました。次は、お題に沿ってじゃんけんの出し手を変える後出しじゃんけんをつくってみましょう。条件を少し追加して、難易度を上げています。

# じゃんけんアプリをつくろう！
:::note info
問題：「後出しじゃんけんじゃんけんポン！」と標準出力されると同時にPCの手が表示される。次のメッセージで、PCの手に対するユーザーのお題（勝って！負けて！あいこ！）が表示される。そして、ユーザがコンソールにじゃんけんの手（0,1,2）を入力すると、じゃんけんの結果（ユーザの手、PCの手、お題、ユーザの勝ち負けあいこ）が標準出力されるプログラムをJavaで記載せよ。」
:::

:::note info
条件：  
・ユーザーとCPの1対1のじゃんけんであること
・PCの手はランダムであること
・お題はランダムに選ばれること
・じゃんけんの手は次のように数字で扱うこと グー：0,チョキ：1,パー：2
・お題にそった手をユーザーが選べていれば勝ち、お題と違った手を選べば負けと判定する
・0,1,2以外の数値が入力された場合は、「0,1,2のどれかの数字を入力してください。」とメッセージを表示し、じゃんけんの手を再入力できるようにすること
・じゃんけんポンの掛け声、PCの手、お題が表示されたときから、じゃんけんの手を入力したときまでの時間が3秒以内かどうか判定し、じゃんけんの結果とともに「かかった時間」と制限時間内かどうかのメッセージ（制限時間内の回答です！/制限時間をオーバーしました。）を標準出力すること
:::

# 解答例
解答例を用意しましたので、見ていきましょう。

```java:JankenMatch.java
package com.example.demo.controller;

import java.util.Calendar;
import java.util.Random;
import java.util.Scanner;

public class JankenMatch {

	public static void main(String[] args) {

		//お題を準備
		Random random = new Random();
		int themeIndex = random.nextInt(3);
		String[] themes = { "【勝って！】", "【負けて！】", "【あいこ！】" };
		
		// PCのじゃんけんの手を準備
		int pcHands = random.nextInt(3); 
		String[] hands = { "グー", "チョキ", "パー" };
		
		//お題とPCの手の表示
		System.out.println("後出しじゃんけん！じゃんけんポン  PCの手　【" + hands[pcHands] + "】");		
		System.out.println("後出しじゃんけんお題は" + themes[themeIndex]);		
		System.out.println("ポン！(グー：0，チョキ：1、パー：2　どれかの数字をいれてください。)");
		
		//制限時間の開始
		Calendar calStartTime = Calendar.getInstance();
		long startTime = calStartTime.getTimeInMillis();
		
		//ユーザーの手を読み取る
		Scanner stdin = new Scanner(System.in);
		int userHands = stdin.nextInt();

        // 入力チェック
        while (userHands < 0 || userHands > 2) {
            System.out.println("グー：0,チョキ：1,パー：2　どれかの数字をいれてください。");
            userHands = stdin.nextInt();
        }
        
		//制限時間の判定
		Calendar calEndTime = Calendar.getInstance();
		long endTime = calEndTime.getTimeInMillis();
		long sumTime = (endTime - startTime) / 1000;

		// 結果判定
		String result = null;
		//お題が「勝って！」のとき
		if(themeIndex == 0) {
			if((userHands == 0 && pcHands == 1) || (userHands == 1 && pcHands == 2) || (userHands == 2 && pcHands == 0)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
			//お題が「負けて！」のとき
		} else if(themeIndex == 1) {
			if((userHands == 0 && pcHands == 2) || (userHands == 1 && pcHands == 0) || (userHands == 2 && pcHands == 1)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
			//お題が「あいこ！」のとき
		}else if(themeIndex == 2) {
			if((userHands == pcHands)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
		}
        		
		// 判定結果の表示
		System.out.println("ユーザーの手:" + hands[userHands] + ",PCの手:" + hands[pcHands] + ",お題:" + themes[themeIndex]);
		System.out.println("結果：" + result);
		System.out.println("かかった時間は"+sumTime+"秒でした");
		if(sumTime <= 3) {
			System.out.println("制限時間内の回答です！");
		}else {
			System.out.println("制限時間をオーバーしました。");
		}
				
		// Scannerをクローズ
		stdin.close();
	}	
}
```


## 解説
```java
		//お題を準備
		Random random = new Random();
		int themeIndex = random.nextInt(3);
		String[] themes = { "【勝って！】", "【負けて！】", "【あいこ！】" };

```
お題はPCのじゃんけんの手を準備するのと同じ要領で作成します。

＊
```java
		// 結果判定
		String result = null;
		//お題が「勝って！」のとき
		if(themeIndex == 0) {
			if((userHands == 0 && pcHands == 1) || (userHands == 1 && pcHands == 2) || (userHands == 2 && pcHands == 0)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
			//お題が「負けて！」のとき
		} else if(themeIndex == 1) {
			if((userHands == 0 && pcHands == 2) || (userHands == 1 && pcHands == 0) || (userHands == 2 && pcHands == 1)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
			//お題が「あいこ！」のとき
		}else if(themeIndex == 2) {
			if((userHands == pcHands)) {
				result = "ユーザーの勝ちです！";
			}else {
				result = "ユーザーの負けです。";
			}
		}
```
結果判定は「お題」の条件をじゃんけんの結果判定に足したら、OKです。今回は、じゃんけんの手を書き出す方のパターンで作成してみました。

＊
```java
		//制限時間の開始
		Calendar calStartTime = Calendar.getInstance();
		long startTime = calStartTime.getTimeInMillis();

		//省略

		//制限時間の判定
		Calendar calEndTime = Calendar.getInstance();
		long endTime = calEndTime.getTimeInMillis();
		long sumTime = (endTime - startTime) / 1000;

		//省略

		System.out.println("かかった時間は"+sumTime+"秒でした");
		if(sumTime <= 3) {
			System.out.println("制限時間内の回答です！");
		}else {
			System.out.println("制限時間をオーバーしました。");
		}
```
制限時間の実装は、Calendarクラスを使用しました。Calendarクラスは現在時刻など時間に関する処理をしたいときに使えます。Calendarオブジェクトを生成するのに、newではなく、getInstance()を使っています。これは、getInstance()の戻り値にstaticがついているためです。

最初の文言が表示したタイミングとじゃんけんの手を入力したタイミングで現在時刻を取得し、差を計算して判定しています。また、getTimeInMillis()メソッドはミリ秒単位で現在時刻を取得するので、1000で割っています。

時間制限をつけないと、ゲームとして難易度が低いな…と思って条件を足してみました。3秒だとちょっと難しいですが…

やる気がある方は、時間制限とお題通りにじゃんけんの手を選べているかの両方で結果判定するようにカスタマイズしてもいいですね。（上記回答例は、時間制限とお題通りかは独立して判定しているので。）

＊

いろんな書き方があるので、一例ととらえてもらえると嬉しいです。
解説は以上です！

＊
「習うより慣れよ」ということで、8種類題材を作成してみました！
[【Java】じゃんけんアプリをつくろう①～シンプルなじゃんけん～](https://qiita.com/aki_number16/items/89b3c0803c2bc235e0c9 "【Java】じゃんけんアプリをつくろう①～シンプルなじゃんけん～")
[【Java】じゃんけんアプリをつくろう②～あいこの場合はもう一度～](https://qiita.com/aki_number16/items/2c13747e1e89bd1a110b "【Java】じゃんけんアプリをつくろう②～あいこの場合はもう一度～")
[【Java】じゃんけんアプリをつくろう③～3回じゃんけんをしてみよう～](https://qiita.com/aki_number16/items/a0d79dbfe252c6b566dd "【Java】じゃんけんアプリをつくろう③～3回じゃんけんをしてみよう～")
[【Java】じゃんけんアプリをつくろう④～先に3勝した方が勝ち～](https://qiita.com/aki_number16/items/a58308affbf3bbe18168 "【Java】じゃんけんアプリをつくろう④～先に3勝した方が勝ち～")
[【Java】じゃんけんアプリをつくろう⑤～3人でじゃんけん～](https://qiita.com/aki_number16/items/38ed393c8cc39c3a6bf4 "【Java】じゃんけんアプリをつくろう⑤～3人でじゃんけん～")
[【Java】じゃんけんアプリをつくろう⑥～後出しじゃんけん～](https://qiita.com/aki_number16/items/59fe0b0b8323c3650d43 "【Java】じゃんけんアプリをつくろう⑥～後出しじゃんけん～")
[【Java】じゃんけんアプリをつくろう⑦～両手じゃんけん～](https://qiita.com/aki_number16/items/8e70be194ab64676f116 "【Java】じゃんけんアプリをつくろう⑦～両手じゃんけん～")
[【Java】じゃんけんアプリをつくろう⑧～あっちむてほい～](https://qiita.com/aki_number16/items/deb5c9b87e59e5dc77b4 "【Java】じゃんけんアプリをつくろう⑧～あっちむてほい～")

最後まで読んでいただいた方、ありがとうございました。