Created
July 4, 2012 12:57
-
-
Save hrstt/3047215 to your computer and use it in GitHub Desktop.
mastermindゲームの課題回答用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.hrst.sample; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
public class Mastermind { | |
/** 入力サイズ */ | |
private static int BET_SIZE = 4; | |
/** 挑戦回数 */ | |
private static int TRY_COUNT = 10; | |
/** | |
* @param args | |
*/ | |
public static void main(String[] args) throws IOException { | |
// 正解 | |
String ownerBet = ownerBet(); | |
// 入力待ち | |
for(int i = 0; i <= TRY_COUNT; i++ ) { | |
// 入力文字列読み込み | |
BufferedReader r = new BufferedReader(new InputStreamReader(System.in),1); | |
String playerBet = r.readLine(); | |
// 入力文字列の内容確認 | |
while (!validateArgs(playerBet)) { | |
System.out.println("Please, input unique 4-digit number."); | |
} | |
// blow: 正当に含まれる文字の数 | |
int blow = countBlow(playerBet, ownerBet); | |
// hit: 正答と位置が同じ場所に出現した文字の数 | |
int hit = countHit(playerBet, ownerBet); | |
// hit が文字列数と同じならば正解 | |
if (hit == BET_SIZE) { | |
System.out.println("that's right! correct number is" + ownerBet + "."); | |
break; | |
} | |
else { | |
// 回答の回数が制限に達していたら正解を示して終了 | |
if(i == (TRY_COUNT - 1)) { | |
System.out.println("game over! correct number is" + ownerBet + "."); | |
break; | |
} | |
// hit とblow の数をヒントにして与える | |
System.out.println("hits: " + hit +", blow: " + blow + "! try again."); | |
} | |
} | |
} | |
/** | |
* 挑戦者(入力)の文字列とオーナー(プログラム)の文字列を比較して, | |
* 同じ位置に同じ文字が出現した回数を返す | |
* | |
* @param playerBet | |
* @param ownerBet | |
* @return hit | |
*/ | |
private static int countHit(String playerBet, String ownerBet) { | |
int hit = 0; | |
int length = playerBet.length(); | |
for(int i = 0; i < length; i++ ) { | |
if(playerBet.charAt(i) == ownerBet.charAt(i) ) { | |
hit += 1; | |
} | |
} | |
return hit; | |
} | |
/** | |
* 挑戦者(入力)の文字列とオーナー(プログラム)の文字列を比較して, | |
* 順番は関係なく同じ文字が出現した回数を返す | |
* | |
* @param playerBet | |
* @param ownerBet | |
* @return blow | |
*/ | |
private static int countBlow(String playerBet, String ownerBet) { | |
int blow = 0; | |
int length = playerBet.length(); | |
for(int i = 0; i < length; i++) { | |
if(ownerBet.indexOf(playerBet.charAt(i)) != -1) { | |
blow += 1; | |
} | |
} | |
return blow; | |
} | |
/** | |
* 挑戦者の入力した文字列の内容の妥当性を図る | |
* 4桁の数字で,かつ,同じ文字を使っていなければ妥当. | |
* | |
* @param s | |
* @return | |
* @throws NumberFormatException | |
*/ | |
private static Boolean validateArgs(String s) throws NumberFormatException { | |
// 数値以外をInteger.perseInt() の成否で検討 | |
try{ | |
Integer.parseInt(s); | |
int length = s.length(); | |
// 4桁以上であれば不当 | |
if (length > BET_SIZE) { | |
return false; | |
} | |
// 同じ文字が含まれていれば不当 | |
// 4文字目は比較しない | |
for(int i = 0; i < length - 1; i++ ) { | |
// 調べる文字が,それ以降の場所に出現するか確認 | |
if(s.indexOf(s.charAt(i), i+1) != -1) { | |
return false; | |
} | |
} | |
return true; | |
} catch(NumberFormatException e) { | |
// キャッチした例外は処理せず「不当」扱いとしてfalseだけ返す | |
return false; | |
} | |
} | |
/** | |
* オーナー(プログラム)の選択した4桁の数値を返す | |
* 4桁の中に同じ数値は含ませない | |
* | |
* @return bet | |
*/ | |
private static String ownerBet() { | |
// 選択対象の数値をlist型で用意しておく | |
List<String> slot = new ArrayList<String>(); | |
slot.addAll(Arrays.asList("0","1","2","3","4","5","6","7","8","9")); | |
// ランダムで抜き出すためにlistの大きさより一つ小さい値をランダムの最大値とする | |
int slot_size = slot.size() - 1; | |
// 文字列の大きさの分だけ,listからランダムに抜き出す | |
// 非復元抽出とするため,remove で抜き出す. | |
// 抜き出すためのランダムの最大値は繰り返すごとに1つずつ小さくなる. | |
String bet = ""; | |
for(int i = 0; i < BET_SIZE; i++) { | |
bet += slot.remove((int)(Math.random()*(slot_size - i))); | |
} | |
return bet; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment