質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

1回答

965閲覧

Java ブラックジャックの不具合について

ganogano

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2020/06/08 07:29

前提・実現したいこと

プログラミングを初めて約一ヶ月です。現在Javaでブラックジャックを作成中です。
Aは1ポイントの扱い,ダブルダウン・スプリット・サレンダーなどの特殊ルールは無し。

とあるサイトを参考にしつつ作成し機能を拡張していたところBlackjackClassのstartメソッドが長いので分割せよとのご指摘を受けたのでいくつかのメソッドに分割をしてみたのですがゲーム2週目になるとプレイヤーの合計ポイントが30など大きな数字になってしまいゲームが破綻してしまいます。
分割前のコードまたは分割後のゲーム1週目は特におかしな動きはないです。
こちらの解決策もしくは他の分割方法があれば教えていただきたいです。

ご助力宜しくお願い致します。
今回初めての投稿なのでその他何かご指摘あればいただけると幸いです。

該当のソースコード

Mainクラス

java

1import java.util.Scanner; 2 3public class Main { 4 5 6 public static void main(String[] args) { 7 8 System.out.println("ブラックジャックを開始します"); 9 10 System.out.println("手持ちのチップ10枚からのスタートです"); 11 12 //ゲームを続けるか決める変数を定義 13 boolean continueTo = false; 14 15 BlackjackClass2 blackjack = new BlackjackClass2(); 16 //ゲームを開始、最後の選択次第で何回も続けられるようにする 17 do { 18 blackjack.start(); 19 blackjack.drawCard(); 20 blackjack.saidPoint(); 21 blackjack.battlePhase(); 22 23 if (blackjack.getTip() <= 0) { 24 System.out.println("チップを使い切りました"); 25 System.out.println("GEME OVER"); 26 break; 27 } 28 while (true) { 29 System.out.println("ゲームを続けますか? Yes:y or No:n"); 30 31 Scanner scan = new Scanner(System.in); 32 String str = scan.next(); 33 if (str.equals("y")) { 34 continueTo = true; 35 break; 36 } else if (str.equals("n")) { 37 continueTo = false; 38 System.out.println("最終所持チップ枚数は" + blackjack.getTip() + "枚でした"); 39 System.out.println("ゲームを終了します"); 40 break; 41 } else { 42 System.out.println("入力が間違っています。yかnを入力してください"); 43 } 44 } 45 } while (continueTo); 46 } 47} 48

Blackjackクラス

java

1import java.util.ArrayList; 2import java.util.InputMismatchException; 3import java.util.List; 4import java.util.Scanner; 5 6public class BlackjackClass { 7 8 //ゲームの勝敗を記録する 9 private int win = 0; 10 private int lose = 0; 11 private int draw = 0; 12 13 //賭けに使う所持チップ数とベット数 14 private int tip = 10; 15 private int bet = 0; 16 17 //山札の進行状況を記録する変数deckCountを定義 18 int deckCount = 4; 19 20 //プレイヤーの手札枚数を記録する変数playerHandsを定義 21 int playerHands = 2; 22 int dealerHands = 2; 23 24 int playerPoint = 0; 25 int dealerPoint = 0; 26 27 public int getTip() { 28 return this.tip; 29 } 30 31 public void setTip(int tip1) { 32 this.tip = tip1; 33 } 34 35 Deck deck = new Deck(); 36 Card card = new Card(); 37 38 //プレイヤー・ディーラーの手札リストを生成 39 List<Integer> player = new ArrayList<>(); 40 List<Integer> dealer = new ArrayList<>(); 41 42 //ゲームを開始するメソッド 43 public void start() { 44 45 Scanner scan = new Scanner(System.in); 46 while (true) { 47 try { 48 System.out.println("掛け金を設定して下さい。現在所持チップ" + this.tip + "枚"); 49 this.bet = scan.nextInt(); 50 if (this.bet > 0 && this.bet <= this.tip) { 51 break; 52 } 53 System.out.println("入力を間違えています。1~所持チップ枚数内で入力してください"); 54 } catch (InputMismatchException e) { 55 System.out.println("入力を間違えています。整数で入力してください"); 56 //入力バッファ初期化の為、読み捨てる 57 scan.next(); 58 } 59 } 60 //デッキクラスのメソッドを呼び出し 61 deck.createDeck(); 62 } 63 64 public void drawCard() { 65 66 //プレイヤー・ディーラーがカードを2枚引く 67 player.add(deck.getDeck().get(0)); 68 player.add(deck.getDeck().get(1)); 69 dealer.add(deck.getDeck().get(2)); 70 dealer.add(deck.getDeck().get(3)); 71 } 72 73 public void saidPoint() { 74 //プレイヤー・ディーラーの手札のポイントを表示 75 System.out.println("あなたの1枚目のカードは" + card.toDescription(player.get(0))); 76 77 System.out.println("ディーラーの1枚目のカードは" + card.toDescription(dealer.get(0))); 78 79 System.out.println("あなたの2枚目のカードは" + card.toDescription(player.get(1))); 80 81 System.out.println("ディーラーの2枚目のカードは秘密です"); 82 83 //プレイヤー・ディーラーのポイントを集計 84 playerPoint = CardUtil.sumPoint(player); 85 dealerPoint = CardUtil.sumPoint(dealer); 86 System.out.println("あなたの現在のポイントは" + playerPoint + "です"); 87 } 88 89 public void battlePhase() { 90 91 //プレイヤーがカードを引くフェーズ 92 while (true) { 93 System.out.println("カードを引きますか? Yes:y or No:n"); 94 95 //キーボードの入力を受け付けて、変数strに代入する 96 Scanner scan = new Scanner(System.in); 97 String str = scan.next(); 98 99 if ("n".equals(str)) { 100 break; 101 } else if ("y".equals(str)) { 102 //手札の追加とバーストチェック 103 104 //山札から一枚追加 105 player.add(deck.getDeck().get(deckCount)); 106 107 //山札と手札を一枚進める 108 deckCount++; 109 playerHands++; 110 111 System.out.println("あなたの" + playerHands + "枚目のカードは" + card.toDescription(player.get(playerHands - 1))); 112 playerPoint = CardUtil.sumPoint(player); 113 System.out.println(""); 114 System.out.println("現在のポイントは" + playerPoint + "です"); 115 if (CardUtil.isBusted(playerPoint)) { 116 System.out.println("残念、バーストしてしまいました。あなたの負けです。"); 117 this.lose++; 118 this.tip -= this.bet; 119 System.out.println("--------------------------------------------------"); 120 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 121 System.out.println("所持チップ枚数 " + this.tip); 122 System.out.println("--------------------------------------------------"); 123 return; 124 } 125 126 } else { 127 System.out.println("入力を間違えています。yかnを入力してください"); 128 } 129 } 130 131 System.out.println("ディーラーの2枚目のカードは" + card.toDescription(dealer.get(1)) + "でした"); 132 133 //ディーラーが手札を17以上にするまでカードを引くフェーズ 134 while (true) { 135 if (dealerPoint >= 17) { 136 break; 137 } 138 dealer.add(deck.getDeck().get(deckCount)); 139 deckCount++; 140 dealerHands++; 141 142 //ディーラーのポイント合計を算出 143 dealerPoint = CardUtil.sumPoint(dealer); 144 145 System.out.println("ディーラーの" + dealerHands + "枚目のカードは" + card.toDescription(dealer.get(dealerHands - 1))); 146 147 //ディーラーのバーストチェック 148 if (CardUtil.isBusted(dealerPoint)) { 149 System.out.println(""); 150 System.out.println("ディーラーのポイントは" + dealerPoint); 151 System.out.println("ディーラーがバーストしました。あなたの勝ちです。"); 152 this.win++; 153 this.tip += this.bet; 154 System.out.println("--------------------------------------------------"); 155 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 156 System.out.println("所持チップ枚数 " + this.tip); 157 System.out.println("--------------------------------------------------"); 158 return; 159 160 } 161 } 162 163 //ポイントを比較する 164 System.out.println(""); 165 System.out.println("あなたのポイントは" + playerPoint); 166 System.out.println("ディーラーのポイントは" + dealerPoint); 167 if (playerPoint == dealerPoint) { 168 this.draw++; 169 System.out.println("引き分けです"); 170 } else if (playerPoint > dealerPoint) { 171 this.win++; 172 this.tip += this.bet; 173 System.out.println("勝ちました!"); 174 } else if (playerPoint < dealerPoint) { 175 this.lose++; 176 this.tip -= this.bet; 177 System.out.println("負けました・・・"); 178 } 179 System.out.println("--------------------------------------------------"); 180 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 181 System.out.println("所持チップ枚数 " + this.tip); 182 System.out.println("--------------------------------------------------"); 183 184 } 185 186} 187

デッキクラス

java

1import java.util.ArrayList; 2import java.util.Collections; 3import java.util.List; 4 5public class Deck { 6 7 //デッキの入れ物でありこの中に数字を入れる 8 private ArrayList<Integer> deck; 9 10 11 public ArrayList<Integer> getDeck() { 12 return this.deck; 13 } 14 15 16 public void setDeck(ArrayList<Integer> deck1) { 17 this.deck = deck1; 18 } 19 20 //デッキに1-52の数を入れシャッフルし値を返す 21 public List<Integer> createDeck() { 22 this.deck = new ArrayList<>(52); 23 24 //山札をシャッフル 25 this.shuffleDeck(this.deck); 26 return this.deck; 27 } 28 29 //山札(deck)に値を入れ、シャッフルするメソッド 30 private void shuffleDeck(List<Integer> deck1) { 31 32 // リストに1-52の連番を代入 33 for (int i = 1; i <= 52; i++) { 34 this.deck.add(i); 35 } 36 37 //山札をシャッフル 38 Collections.shuffle(deck1); 39 } 40 41} 42

カードクラス

java

1import java.util.ArrayList; 2import java.util.Collections; 3import java.util.List; 4 5public class Card { 6 7 //カードのスート(ハートやスペードなどのマーク) 8 private String suit; 9 //カードのランク(AやJ,Q,K) 10 private String rank; 11 //デッキの入れ物でありこの中に数字を入れる 12 private ArrayList<Integer> deck; 13 14 15 public ArrayList<Integer> getDeck() { 16 return this.deck; 17 } 18 19 public void setDeck(ArrayList<Integer> deck1) { 20 this.deck = deck1; 21 } 22 23 public List<Integer> createDeck() { 24 this.deck = new ArrayList<>(52); 25 26 //山札をシャッフル 27 this.shuffleDeck(this.deck); 28 return this.deck; 29 } 30 31 //山札(deck)に値を入れ、シャッフルするメソッド 32 private void shuffleDeck(List<Integer> deck1) { 33 34 // リストに1-52の連番を代入 35 for (int i = 1; i <= 52; i++) { 36 this.deck.add(i); 37 } 38 39 //山札をシャッフル 40 Collections.shuffle(deck1); 41 42 } 43 44 //カード番号をランク(AやJ,Q,K)に変換するメソッド 45 public String toRank(int number) { 46 47 String rank1 = null; 48 49 switch (number) { 50 51 case 1: 52 rank1 = "A"; 53 break; 54 55 case 11: 56 rank1 = "J"; 57 break; 58 59 case 12: 60 rank1 = "Q"; 61 break; 62 63 case 13: 64 rank1 = "K"; 65 break; 66 67 default: 68 String str = String.valueOf(number); 69 rank1 = str; 70 71 } 72 this.rank = rank1; 73 return this.rank; 74 75 } 76 77 //山札の数をスート(ハートやスペードなどのマーク)に置き換えるメソッド 78 public String toSuit(int cardNumber) { 79 80 String suit1 = null; 81 82 switch ((cardNumber - 1) / 13) { 83 84 case 0: 85 suit1 = "クラブ"; 86 break; 87 88 case 1: 89 suit1 = "ダイヤ"; 90 break; 91 92 case 2: 93 suit1 = "ハート"; 94 break; 95 96 case 3: 97 suit1 = "スペード"; 98 break; 99 100 default: 101 suit1 = "例外です"; 102 103 } 104 this.suit = suit1; 105 return this.suit; 106 107 } 108 109 //山札の数を(スート)の(ランク)の文字列に置き換えるメソッド 110 public String toDescription(int cardNumber) { 111 String rank1 = this.toRank(CardUtil.toNumber(cardNumber)); 112 String suit1 = this.toSuit(cardNumber); 113 114 return suit1 + "の" + rank1; 115 } 116 117}

計算クラス

java

1import java.util.List; 2 3public class CardUtil { 4 5 //山札の数をカードの数に置き換えるメソッド 6 public static int toNumber(int cardNumber) { 7 int number = cardNumber % 13; 8 if (number == 0) { 9 number = 13; 10 } 11 12 return number; 13 } 14 15 // 手札がバーストしているか判定するメソッド 16 public static boolean isBusted(int point) { 17 if (point <= 21) { 18 return false; 19 } 20 return true; 21 22 } 23 24 //現在の合計ポイントを計算するメソッド 25 public static int sumPoint(List<Integer> list) { 26 int sum = 0; 27 28 for (int i = 0; i < list.size(); i++) { 29 sum = sum + toPoint(toNumber(list.get(i))); 30 } 31 32 return sum; 33 } 34 35 //トランプの数字を得点計算用のポイントに変換するメソッド.J/Q/Kは10とする 36 public static int toPoint(int num) { 37 if (num == 11 || num == 12 || num == 13) { 38 num = 10; 39 } 40 41 return num; 42 } 43 44} 45

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

繰り返し実行したいのであれば、doブロックの中にblackjackインスタンスの生成を持っていくか、Blackjackクラスのstartメソッド辺りで改めて初期化をしてやる必要があります。(多分前者の方が楽だと思います)

投稿2020/06/08 07:36

kuuote

総合スコア705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kuuote

2020/06/08 07:57

カードクラスのtoRankやtoSuit内でクラス変数に代入しているのが気になりました。何か意図があって代入しているのであれば、メソッド名をsetRankもしくはupdateRankのようにしておくと後々見やすいかなと思います。
ganogano

2020/06/08 08:00 編集

回答していただきありがとうございます。 doブロックの中でインスタンスを生成すると残しておきたい勝敗やチップなどの変数も初期化されてしまったので startメソッドの中でint playerPoint = 0; int dealerPoint = 0; としたのですが同じように合計ポイントが大きくなってしまいます・・・ 一応確認の為BlackjackクラスのsaidPointの頭にprintlnでplayerPointを表示させてみたところ2週目でもその時点ではポイント数は0になっておりました。
kuuote

2020/06/08 08:07

正常にゲームを動かしたいのであれば、保存したい変数以外全部初期化する必要があるかと。(合計ポイントの算出に直接関係ありそうなのは手札リストかな)
ganogano

2020/06/10 00:58

手札リストをゲームの最初に初期化するようにしたところ無事に動きました! どうやら分割するにあたって手札リストをstartメソッドの外に置いたのが原因のようです。 toRankやtoSuitも見づらかった為メソッド名を変更致しました。 とても参考になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問