今回は受講生が作ったJava問題の中から良問をピックアップします。

*******借金返済ゲーム(S氏作)*******
多重債務を抱えた夫婦が返済をして行くゲーム。
設定がとてもシュールだがJavaの基礎力が試される良問。

Java問題: ATMゲーム
トメは闇金に手を出してしまい、借金返済の為に夫婦の共有財産に手を付けてしまいました。
口座の残高は3000万円。1回の出金額はランダムで100~1000万円(100万円区切り)です。
ただし、トメは計算が苦手なので、1回で出金した預金を全額返済してしまいます。(余剰金は返ってきません)
口座残高が0円以下になる前に借金返済が完了すればクリア。
口座残高が0円以下になると家族会議が開かれてゲームオーバーです。

[***実行例1***]
[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:300万円
*預金残高は3000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは600万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>1
ときめき銀行へ600万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:900万円
さわやか銀行:300万円
*預金残高は2400万円です。

引き出しますか(はい:y いいえ:n)>y
トメは100万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>2
さわやか銀行へ100万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:900万円
さわやか銀行:200万円
*預金残高は2300万円です。

引き出しますか(はい:y いいえ:n)>y
トメは300万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>2
さわやか銀行へ300万円返済しました。
さわやか銀行への借金返済が完了した!!

[借入額]
鳥肌銀行:500万円
ときめき銀行:900万円
*預金残高は2000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは1000万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 )>1
ときめき銀行へ1000万円返済しました。
ときめき銀行への借金返済が完了した!!

[借入額]
鳥肌銀行:500万円
*預金残高は1000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは500万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 )>0

鳥肌銀行へ500万円返済しました。
鳥肌銀行への借金返済が完了した!!

全ての借金返済が完了した!!

[***実行例2***]
[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:300万円
*預金残高は3000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは100万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>2
さわやか銀行へ100万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:200万円
*預金残高は2900万円です。

引き出しますか(はい:y いいえ:n)>y

トメは200万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>2
さわやか銀行へ200万円返済しました。
さわやか銀行への借金返済が完了した!!

[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
*預金残高は2700万円です。

引き出しますか(はい:y いいえ:n)>y
トメは1000万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 )>1
ときめき銀行へ1000万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:500万円
*預金残高は1700万円です。

引き出しますか(はい:y いいえ:n)>y

トメは300万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 )>1
ときめき銀行へ300万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:200万円
*預金残高は1400万円です。

引き出しますか(はい:y いいえ:n)>y
トメは400万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 )>0
鳥肌銀行へ400万円返済しました。

[借入額]
鳥肌銀行:100万円
ときめき銀行:200万円
*預金残高は1000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは1000万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 )>0
鳥肌銀行へ1000万円返済しました。
鳥肌銀行への借金返済が完了した!!

預金がなくなった!!
ヒロシ「トメ、なんてことをしてくれたんだ!!」
ゲームオーバー

[***実行例3***]
[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:300万円
*預金残高は3000万円です。

引き出しますか(はい:y いいえ:n)>y
トメは100万円の引き出しに成功した!!
何処に返済しますか?(鳥肌銀行:0 ときめき銀行:1 さわやか銀行:2 )>2
さわやか銀行へ100万円返済しました。

[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:200万円
*預金残高は2900万円です。

引き出しますか(はい:y いいえ:n)>n
…夢だった。最初からやり直し!!

[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:300万円
*預金残高は3000万円です。

引き出しますか(はい:y いいえ:n)>
もう一度やりますか(はい:y いいえ:n)>y
[借入額]
鳥肌銀行:500万円
ときめき銀行:1500万円
さわやか銀行:300万円
*預金残高は3000万円です。
引き出しますか(はい:y いいえ:n)>

解答例)
銀行クラスを作ってそれをリストで管理する方針をとりました。


import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Tome {
	static final int INITIAL_AMOUNT=3000;//最初の所持金
	static List<Bank> banks=new ArrayList<>(); //借金のある銀行を管理するリスト
	static int amount;//現在の所持金
	static Scanner scan=new Scanner(System.in);
	static Random rand=new Random();
	
	/**
	 * メインメソッド
	 * @param args
	 */
	public static void main(String[] args) {
		do{
			init(); //初期化処理
			//メインルーチン
			while(true){
				showInfo();//借金がある銀行一覧表示
				/****夢かどうかの判定***/
				System.out.print("引き出しますか(はい:y いいえ:n)>");
				String select=scan.next();
				if(select.equals("n")){
					System.out.println("...夢だった。最初からやり直し!!");
					break;
				}
				int money=(rand.nextInt(10)+1)*100;//引き出し金額をランダムに決定(100~1000)
				amount-=money;//現在の所持金から引く
				//引き出せたか?
				if(amount>=0){
					System.out.printf("トメは%d万円の引き出しに成功した!!%n", money);
				}else{
					//引き出せなかったら終了
					endMessage(String.format("%d万円引き出したが口座がマイナスになった!!%n",money));
					break;
				}
				repayment(money);//返済処理
				//返済結果(借金がある銀行が0か?)
				if(banks.isEmpty()){
					//成功メッセージ
					System.out.println("全ての借金返済が完了した!!");
					break;
				}else{
					//銀行が残っているの所持金が0になったら終了
					if(amount==0){
						endMessage("預金がなくなった!!");
						break;
					}
				}	
			}
		}while(isRetry());//もう一回やるか?
		System.out.println("アプリケーションを終了します。");
	}
	/**
	 * 各値を初期化する処理
	 */
	static void init(){
		amount=INITIAL_AMOUNT;
		banks.clear();
		banks.add(new Bank("鳥肌銀行",500));
		banks.add(new Bank("ときめき銀行",1500));
		banks.add(new Bank("さわやか銀行",300));
	}
	/**
	 * 現在のステータスを一覧する処理
	 */
	static void showInfo(){
		System.out.println("[借入額]");
		for(Bank b:banks){
			System.out.println(b);
		}
		System.out.printf("*預金残高は%d万円です。%n",amount);
	}
	/**
	 * もう一度やるかを決める処理
	 * @return もう一回やるか?
	 */
	static boolean isRetry(){
		System.out.print("もう一度やりますか(はい:y いいえ:n)>");
		String select=scan.next();
		return select.equals("y");	
	}
	
	/**
	 * 引数で受け取った文言を出力してから
	 * 定型文を出力
	 * @param msg
	 */
	static void endMessage(String msg){	
		System.out.println(msg);
		System.out.println("ヒロシ「トメ、なんてことをしてくれたんだ!!」");
		System.out.println("ゲームオーバー");
	}
	
	/**
	 * 銀行を選択肢、引数で受け取った金額を返済する。
	 * その銀行の借金がなくなったらリストから削除
	 * @param money 返済額
	 */
	static void repayment(int money){
		/***返済リストの文字列作成***/
		String restbanks="";
		for(int i=0;i<banks.size();i++){
			restbanks+=String.format("%s:%d ", banks.get(i).name,i);
		}
		//メッセージ表示
		System.out.printf("何処に返済しますか?("+restbanks+")>");
		int index=scan.nextInt();
		//返す銀行(selectedBank)
		Bank selectedBank=banks.get(index);
		//返済処理
		selectedBank.pay(money);
		System.out.printf("%sへ%d万円返済しました。%n",selectedBank.name,money);
		//返済後残高が0以下だったら返済完了
		if(selectedBank.rest <= 0){
			System.out.printf("%sへの借金返済が完了した!!%n", selectedBank.name);
			//銀行リストから削除
			banks.remove(index);
		}
	}
}

/**
 * 銀行クラス(借金先)
 */
class Bank{
	String name; //銀行名
	int rest; //借金残高
	
	public Bank(String name, int rest) {
		this.name = name;
		this.rest = rest;
	}
	/**
	 * 引数の金額を残高から減らす
	 * @param money
	 */
	public void pay(int money){
		this.rest-=money;
	}

	@Override
	public String toString() {
		return String.format("%s:%d万円", this.name,this.rest);
	}	
}