#今回の進捗
前回からの続きです。
- カードの一枚を"ダイヤのA","ダイヤの2"..."クローバーのK"という風に文字列に変更
- トランプを一枚ずつ格納する配列billsをfor文を使って作成
- 得点計算を行うために、HashMapを利用して["ダイヤのA",1],["ダイヤの2",2]...["クローバーのK",10]という連想配列を、billsを作成するFor文の中で作成(今回はAを1点とだけ判定するようにしています。)
- 山札billsをゲーム開始時にCollections.shuffleを利用してランダム化
- プレイヤーの手札をArrayListを利用してhandCardというリストに格納するように設定(ディーラーの分はhandCard_dealerに)
- 手札の得点を格納する変数cardPointsを設定(ディーラーの分はcardPoints_dealerに)
- cardPointsを参照してBlackJack(以降BJ)したかBurstしたかの判定を行うためにJUDGEクラスを作成
- JUDGEクラスの中でグローバル変数resultを定義して条件に応じてゲームを終了できるように設定
- 両者の手札がそろった後、プレイヤーがHitするかStandするかを選択
- カードを引いた時もBJかBurstかの判定を行う
- 一連の流れをWhile文でループさせてプレイヤーがStandするか、BJするかBurstするまでHitを繰り返すように設定
ちょっと多いですね。
細かい内容は次の項目からです。
#内容
##カード1枚の表現と得点計算
- カード1枚を文字列に。
- トランプを格納する配列billsを作成
- 得点計算を行うために、HashMapを利用して連想配列を作成
- 山札をシャッフルさせた
前回までは得点計算のことも考えて、["ダイヤ","A"],["ダイヤ","2"]...["クローバー","K"]という配列で表現していました。
そこで、得点計算をHasMapを利用して行うことに。カードを連想配列のキーとして用いることで、カード1枚を"ダイヤのA","ダイヤの2"という文字列に変更しました。
山札となる配列billsと、得点計算用連想配列のPointsをFor文でまとめて作成することに。
ゲーム開始時に山札をシャッフルしてランダム化するためにCollection.shuffleを使いました。
//山札リスト
List<String> bills = new ArrayList<String>();
//得点計算用ハッシュマップ
HashMap<String, Integer> points = new HashMap<String, Integer>();
//カード生成用配列
String[] strMark={"ダイヤ","ハート","スペード","クローバー"};
String[] strNumber={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
//For文でカード1枚を作成し、山札リストに追加
//カードと点数をハッシュマップに追加
for (int i=0;i<strMark.length;i++){
for (int j=0;j<strNumber.length;j++){
String card = strMark[i]+"の"+strNumber[j];
bills.add(card);
if(j>9) {
points.put(card, 10);
}else {
points.put(card, j+1);
}
}
}
//山札のシャッフル
Collections.shuffle(bills);
##手札の表現
- 手札のカードをArrayListを利用して配列として表現
- 手持ちの得点をint型の変数cardPointsに格納
カードを引いた時に、billsから一枚ずつ抜き出す関係上、引いたカードをプールさせるためにArrayListを用いてhandCardというリストに格納するようにしました。配列ではなくリストを使ったのは、何枚カードを引くことになるか不確定だからです。
また、pointsから手札のカードを用いて得点を計算し、プールしておくためにint型の変数cardPoitnsを定義しました。
こちらどちらもディーラーように"_dealer"を追加したリスト・変数も定義しています。
//ゲームの開始
//プレイヤーの手札
ArrayList<String> handCard =new ArrayList<String>();
handCard.add(bills.get(0));
System.out.println("あなたの1枚目のカードは["+handCard.get(0)+"]です");
int cardPoints = points.get(bills.get(0));
bills.remove(0);
handCard.add(bills.get(0));
System.out.println("あなたの2枚目のカードは["+handCard.get(1)+"]です");
cardPoints += points.get(bills.get(0));
bills.remove(0);
System.out.println("あなたの手札は"+handCard+"です");
System.out.println("あなたの得点は"+cardPoints+"点です");
//ディーラーの手札
ArrayList<String> handCard_dealer = new ArrayList<String>();
handCard_dealer.add(bills.get(0));
System.out.println("ディーラーの1枚目のカードは["+handCard_dealer.get(0)+"]です");
int cardPoints_dealer = points.get(bills.get(0));
bills.remove(0);
handCard_dealer.add(bills.get(0));
System.out.println("ディーラーの2枚目のカードはわかりません");
cardPoints_dealer += points.get(bills.get(0));
bills.remove(0);
##BJかBurstかの判定
- cardPointsを参照してBJしたかBurstしたかの判定を行うためにJUDGEクラスを作成
- JUDGEクラスの中でグローバル変数resultを定義してゲームを終了できるように条件分岐
BJしたかBurstしたかの判定は、プレイヤーとディーラーがカードを引くたびに判定を行いたいので、JUDGEクラスを作成してメソッドとして利用できるようにしました。
さらに、JUDGEクラスの中でグローバル変数resultを定義して、条件に応じてゲームを終了できるようにしました。
public class JUDGE {
public static String result = "";
public static void judge(int cardPoints,int cardPoints_dealer) {
if(cardPoints>=22) {
System.out.println("----Burst!!!----");
System.out.println("----あなたの負けです----");
result="lose";
} else if(cardPoints==21){
System.out.println("☆★☆★☆★☆★BLACKJACK!!!☆★☆★☆★☆★");
System.out.println("----あなたの勝利です----");
result="win";
} else if(cardPoints_dealer>=22) {
System.out.println("----DEALER'S Burst!!!----");
System.out.println("ディーラーの点数が"+cardPoints_dealer+"点なのでバーストしました");
System.out.println("----あなたの勝ちです----");
result="win";
} else if(cardPoints_dealer==21){
System.out.println("☆★☆★☆★☆★DEALER'S BLACKJACK!!!☆★☆★☆★☆★");
System.out.println("----あなたの負けです----");
result="lose";
}
} //judge method締め
} //class締め
//BlackJackかBurstかの処理
JUDGE.judge(cardPoints,cardPoints_dealer);
if(JUDGE.result!="") {
return;
}
##Hitするか?standするか?
- 両者の手札がそろった後、プレイヤーがHitするかStandするかを選択
- カードを引いた時もBJかBurstかの判定を行う
- 一連の流れをWhile文でループさせて繰り返すように設定
ここからは実際にプレイヤーが行動を選択する部分になります。得点に応じてHit(カードを1枚引く)か、Stand(カードを引かずにディーラーにターンを渡す)するかを選択します。
Hitを選択したら、billsから一枚取り出しhandcard加え、引いたカードの分の得点もcardPointsに加算するようにしました。その後上記のjudgeメソッドを使って判定も行っています。
最後に、行動の選択とHitの動作をWhile文でループさせています。
//Hit?Stand?
Scanner scanner = new Scanner(System.in);
int PlayerRoop = 0;
while(PlayerRoop==0) {
int choice_roop =0;
String choicePlay ="";
while (choice_roop==0) {
System.out.print("Hitしますか?Standしますか?(H/S?)>");
String choice = scanner.next();
if (choice.contains("H") || choice.contains("h")) {
System.out.println("Hitを選択しました");
choice_roop+=1;
choicePlay="Hit";
}else if(choice.contains("S") || choice.contains("s")){
System.out.println("Standを選択しました");
choice_roop+=1;
choicePlay="Stand";
}else {
System.out.println("HitかStandかを選択してください");
}
} //while文締め
//行動選択結果
if (choicePlay.contains("Hit")) {
handCard.add(bills.get(0));
System.out.println("引いたカードは["+handCard.get(handCard.size()-1)+"]です");
cardPoints += points.get(handCard.get(handCard.size()-1));
bills.remove(0);
System.out.println("現在の点数は"+cardPoints+"点です");
System.out.println("あなたの手札は"+handCard+"です");
JUDGE.judge(cardPoints,cardPoints_dealer);
if(JUDGE.result != "") {
return;
}
}else {
System.out.println("ディーラーのターンに移ります");
PlayerRoop+=1;
} //if文締め
} //while文締め
#今後
あとはディーラーの行動を追加しておしまいかなーなんて考えてます。
#終わりに
コードはかなり長くなっちゃいましたが、終わりが見えてきて一安心といった感じです。
今回は更新内容多すぎてかなり長文になっちゃいましたが、アドバイスなどありましたらお聞きしたいです。