ブラックジャックをjavaで実装しようとしたのですが、結果が以下のように途中まで表示されるのですが、それ以降の表示がされません。どのように修正すれば良いでしょうか?
初学者で手探りでコードを書いています。的外れなことを書いているかもしれませんが、ご教授お願いします。
表示される実行結果↓
ブラックジャックを始めます.
カードを配ります.
BlackJack.java
1public class BlackJack { 2 3 /** 4 * ブラックジャック開始 5 * @param args 6 * 引数 7 */ 8 public static void main(String[]args) { 9 10 Dealer dealer = new Dealer(); 11 User user = new User(); 12 13 System.out.println("ブラックジャックを始めます."); 14 System.out.println("カードを配ります."); 15 16 dealer.setCards(dealer.deal());/* ディーラーにカードを配る*/ 17 user.setCards(dealer.deal());/* プレイヤーにカードを配る*/ 18 19 dealer.checkSum();/* 合計値の確認 */ 20 21 /** 22 * ディーラーの手札の合計が16以下だった場合(true)ディーラーはヒットする 23 */ 24 while (dealer.checkSum() == true) { 25 dealer.hit(); 26 dealer.setCards(dealer.myCards); 27 break; 28 } 29 System.out.println("ディーラーの手札はこちらです."); 30 31 32 while (user.checkSum() == true) { 33 dealer.hit(); 34 dealer.setCards(dealer.myCards); 35 break; 36 } 37 38 System.out.println("あなたの手札はこちらです."); 39 40 /** 41 * 合計値を確認する 42 * @return 手札の合計が16以下ならtrue,17以上ならfalse 43 */ 44 user.checkSum(); 45 46 System.out.println("ディーラーは"+ dealer.myCards); 47 System.out.println(dealer.open()); 48 System.out.println("あなたは"+ user.myCards); 49 System.out.println(user.open()); 50 51 /** 52 * 勝ち負けの条件 53 */ 54 if(user.open() == 21) { 55 System.out.println("ブラックジャック!あなたの勝ちです."); 56 }else if(user.open() < 21 && dealer.open()<user.open() || dealer.open()>21){ 57 System.out.println("あなたの勝ち"); 58 }else if(user.open() > 21){ 59 System.out.println("バースト!あなたの負け"); 60 }else if(dealer.open() ==21 || dealer.open() <=21 && user.open()<dealer.open()){ 61 System.out.println("あなたの負け"); 62 }else if(user.open() == dealer.open() || user.open()>21 && dealer.open()>21){ 63 System.out.println("引き分け"); 64 } 65 } 66} 67
Human.java
1import java.util.ArrayList; 2 3public abstract class Human { 4 5 protected ArrayList<Integer> myCards = new ArrayList<Integer>(); 6 7 /** 8 * 手札の値を出す 9 */ 10 abstract public int open(); 11 12 /** 13 * 自分の手札に引いたカードの数だけ加える 14 * @param drawCard 15 * 引いたカード 16 */ 17 abstract public void setCards(ArrayList <Integer> drawCard); 18 19 /** 20 * 合計値を確認する 21 * @return 手札の合計が16以下ならtrue,17以上ならfalse 22 */ 23 abstract public boolean checkSum(); 24 25 } 26
Dealer.java
1 2import java.util.ArrayList; 3import java.util.Collections; 4 5public class Dealer extends Human { 6 7 CardDeck deck = new CardDeck(); 8 9 /** 10 * 山札を作る 11 * @param cards 12 * 山札 13 */ 14 protected ArrayList <Integer> cards = new ArrayList<Integer>(); 15 16 /** 17 * フルデッキ(52枚)を作成する 18 * デッキをシャッフルする 19 */ 20 public Dealer() { 21 for(int n=1; n<=4; n++) { 22 for(int i=1; i<=13; i++) { 23 cards.add(i); 24 } 25 } 26 Collections.shuffle(cards); 27 } 28 29 /** 30 * 手札にカードを2枚加える 31 * @param setCards 32 * 手札 33 * @return 手札 34 */ 35 36 public ArrayList<Integer> deal(){ 37 ArrayList<Integer> setCards = new ArrayList<Integer>(); 38 setCards.add(cards.get(0)); 39 setCards.add(cards.get(1)); 40 cards.remove(0); 41 cards.remove(0); 42 return setCards; 43 } 44 45 /** 46 * 自分の手札に引いたカードの数だけ加える 47 * @param drawCard 48 * 引いたカード 49 */ 50 public void setCards(ArrayList<Integer> drawCard) { 51 for(int i= 0; i<drawCard.size(); i++){ 52 myCards.add(drawCard.get(i)); 53 } 54 } 55 56 /** 57 * 手札の値を出す.絵柄なら10を渡す 58 * @param total 59 * 手札の合計 60 * @return 合計の値を返す 61 */ 62 public int open() { 63 int total = 0; 64 for(int i=0; i<=myCards.size(); i++) { 65 if(0<= myCards.get(i)) { 66 total += 10; 67 }else { 68 total += myCards.get(i); 69 } 70 } 71 return total; 72 } 73 74 75 /** 76 * カードを山札から取る 77 * @param setCards 78 * 手札 79 * @return カード 80 */ 81 public ArrayList<Integer> hit(){ 82 ArrayList<Integer>setCards = new ArrayList<Integer>(); 83 setCards.add(cards.get(0)); 84 cards.remove(0); 85 return cards; 86 } 87 88 /** 89 * 合計値を確認する 90 * @return 手札の合計が16以下ならtrue,17以上ならfalse 91 */ 92 public boolean checkSum() { 93 if (open() < 17 ) { 94 return true; 95 }else{ 96 return false; 97 } 98 } 99}
User.java
1import java.util.ArrayList; 2 3public class User extends Human { 4 /** 5 * 山札を作る 6 * @param cards 7 * 山札 8 */ 9 protected ArrayList<Integer> cards = new ArrayList<Integer>(); 10 11 /** 12 * 自分の手札に引いたカードの数だけ加える 13 * @param drawCard 14 * 引いたカード 15 */ 16 public void setCards(ArrayList<Integer> drawCard) { 17 for(int i= 0;i<drawCard.size();i++){ 18 myCards.add(drawCard.get(i)); 19 } 20 } 21 22 /** 23 * 手札の値を出す 24 * @param total 25 * 手札の合計 26 * @return 合計の値を返す 27 */ 28 public int open() { 29 int total = 0; 30 for(int i =0; i<myCards.size(); i++) { 31 if(10 <= myCards.get(i)) { 32 total += 10; 33 }else { 34 total += myCards.get(i); 35 } 36 } 37 return total; 38 } 39 40 /** 41 * 合計値を確認する 42 * @return 手札の合計が16以下ならtrue,17以上ならfalse 43 */ 44 public boolean checkSum() { 45 if (open() < 17) { 46 return true; 47 }else{ 48 return false; 49 } 50 51 } 52} 53
使おうとして結局使わなかったコード
CardDeck.java
1 2import java.util.ArrayList; 3import java.util.Collections; 4import java.util.List; 5 6public class CardDeck { 7 private ArrayList<Card> cards = new ArrayList<Card>(); 8 9 /** 10 * 空のカードデッキを生成する 11 */ 12 public CardDeck() { 13 super(); 14 } 15 16 /** 17 * フルデッキ(52枚)を作る 18 */ 19 public void createFullDeck() { 20 for(int i=0; i<=3; i++) { 21 for(int j=1; j<=13; j++) { 22 Card c = new Card(i, j); 23 cards.add(c); 24 } 25 } 26 } 27 28 /** 29 * 空デッキをにする 30 */ 31 public void clear() { 32 cards.clear(); 33 } 34 35 /** 36 * デッキををシャッフルする 37 */ 38 public void shuffle() { 39 Collections.shuffle(cards); 40 } 41 42 /** 43 * デッキの一番最後に,任意のカードcardを追加する 44 * @param card 45 * カード 46 */ 47 public void addCard(Card card) { 48 cards.add(card); 49 } 50 51 /** 52 * デッキの i 番目に,任意のカードcardを追加する 53 * 54 * @param i 55 * 追加する場所 56 * @param card 57 * カード 58 */ 59 public void addCard(int i, Card card) { 60 cards.add(i-1, card); 61 } 62 63 /** 64 * デッキの一番上のカードを取る 65 * 66 * @return カード 67 */ 68 public Card takeCard() { 69 Card c = cards.get(0); 70 cards.remove(0); 71 c.show(); 72 return c; 73 } 74 75 /** 76 * デッキの i 番目から,カードを抜き取る 77 * 78 * @param i 79 * 抜き取る場所 80 * @return 81 * カード 82 */ 83 public Card takeCard(int i) { 84 Card c = cards.get(i-1); 85 cards.remove(i-1); 86 c.show(); 87 return c; 88 } 89 90 /** 91 * デッキのi番目にあるカードを見る 92 * 93 * @param i 94 * 見る場所 95 * @return 96 * カード 97 */ 98 public Card seeCard(int i) { 99 Card c = cards.get(i-1); 100 System.out.println(i + "番目のカード:" + c.getString(c.getSuit(), c.getNumber())); 101 return c; 102 } 103 104 /** 105 * カードがデッキの何番目にあるかを調べる 106 * @param suit 107 * 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 108 * @param number 109 * 数字 (1-13) 110 * @return カードの場所 111 */ 112 public int searchCard(int suit, int number) { 113 Card c = new Card(suit, number); 114 return cards.indexOf(c) + 1; 115 } 116 117 /** 118 * 現在のデッキが空かどうか,判定する 119 * @return 空ならtrue,空でないならfalse 120 */ 121 public boolean isEmpty() { 122 return cards.isEmpty(); 123 } 124 125 /** 126 * 現在デッキにあるカード枚数を返す( 127 * 128 * @return デッキにあるカード枚数 129 */ 130 public int size() { 131 return cards.size(); 132 } 133 134 /** 135 * 現在のすべてのカードを画面に表示する 136 */ 137 public void showAllCard() { 138 System.out.println("------------現在の山を表示します.-----------"); 139 for(int i=1; i<=size(); i++) { 140 seeCard(i); 141 } 142 System.out.println("------------ここまで-----------"); 143 } 144 145 /** 146 * 現在デッキにある全てのカードを返す 147 * @return 現在デッキにある全てのカード 148 */ 149 public List<Card> getAllCards() { 150 return cards; 151 } 152}
Card
1public class Card { 2 private int suit; // 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 3 private int number; // 数字 (1-13) 4 5 /** 6 * 絵柄と数字を指定してカードを生成する 7 * 8 * @param suit 9 * 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 10 * @param number 11 * 数字 (1-13) 12 */ 13 public Card(int suit, int number) { 14 super(); 15 this.suit = suit; 16 this.number = number; 17 } 18 19 /** 20 * そのカードの絵柄を取得する 21 * 22 * @return 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 23 */ 24 public int getSuit() { 25 return suit; 26 } 27 28 /** 29 * そのカードの数字を取得する 30 * 31 * @return 数字 (1-13) 32 */ 33 public int getNumber() { 34 return number; 35 } 36 37 /** 38 * そのカードの整数表現を取得する 39 * 40 * @return 整数表現 (0-51) 41 */ 42 public int toIndex() { 43 //自身の絵柄,数字で,staticメソッドから得る 44 return getIndex(getSuit(), getNumber()); 45 } 46 47 /** 48 * そのカードの文字列表現を取得する 49 * 50 * @return 文字列表現 (スペードA, スペード2, ...) 51 */ 52 public String toString() { 53 //自身の絵柄,数字で,staticメソッドから得る 54 return getString(getSuit(), getNumber()); 55 } 56 57 /** 58 * そのカードの文字列表現を画面に表示する 59 */ 60 public void show() { 61 System.out.println(toString()); 62 } 63 64 /** 65 * 与えられた絵柄,数字から整数表現を計算して返す.すべてのカードで共通 66 * 67 * @param suit 68 * 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 69 * @param number 70 * 数字 (1-13) 71 * @return カードの整数表現 (0-51) 72 */ 73 public static int getIndex(int suit, int number) { 74 int index; 75 index = suit * 13 + number; 76 77 return index; 78 79 } 80 81 /** 82 * 与えられた絵柄,数字から文字列表現を決定して返す.すべてのカードで共通 83 * 84 * @param suit 85 * 絵柄 (0:スペード,1:ダイヤ,2:ハート,3:クラブ) 86 * @param number 87 * 数字 (1-13) 88 * @return カードの文字列表現 (スペードA, スペード2, ...) 89 */ 90 public static String getString(int suit, int number) { 91 String suitStr, numStr; // 絵柄文字列,数字文字列 92 93 String[] sLabel = { "スペード", "ダイヤ", "ハート", "クラブ" }; 94 95 if (2 <= number && number <= 10) { 96 // 通常の数字の場合 97 suitStr = sLabel[suit]; 98 numStr = Integer.toString(number); 99 } else { 100 // 特別な数字表現の場合 101 suitStr = sLabel[suit]; 102 switch (number) { 103 case 1: 104 numStr = "A"; 105 break; 106 case 11: 107 numStr = "J"; 108 break; 109 case 12: 110 numStr = "Q"; 111 break; 112 case 13: 113 numStr = "K"; 114 break; 115 default: 116 numStr = "存在しないカード"; 117 } 118 } 119 // 絵柄文字列と数字文字列を連結して返す 120 return suitStr + numStr; 121 } 122}
プログラムがどこまで動いているのか確認されましたでしょうか。
このコードで『ディーラーの手札はこちらです.』にたどり着けないのが不思議でしょうがない。
エラー出てるのに質問文で省略したりしてませんか?
自身が書いたコードはどの程度理解されているのでしょうか。
ある程度理解はしているのですが、様々な教材やサイトを引用しながら書いたので、コードが表すものがわかっても完全に意味は理解できていないとこがあるかもしれません。
public int open() {
int total = 0;
for(int i =0; i<myCards.size(); i++) {
if(10 <= myCards.get(i)) {
total += 10;
}
この部分は別のサイトを参照したのですが、絵柄の11,12,13が10になると思っていたのですが、 i<myCards.size() の部分の意味がよくわかりません。
わかる方教えていただけませんか?
myCards に 9,10,11 の3枚が入っていたとして、ループする毎にどの変数がどのような値になるか、ご自身がコンピュータになったつもりで、一行ずつ"実行"してみては如何でしょうか。
そこだけ見てても理解はできないので機能としてみましょう。
forの2番目はループ回数を定義するものです。
とりあえず、「コードとして書いた部分の内容を」、「事細かく説明」してくれませんか?
質問者さんの力量がどのくらいなのかを測るためです。
質問本文に「追記」してください。(質問内容はそのままで)
https://teratail.com/questions/347801
が参考になるのでは。
> https://teratail.com/questions/347801
> が参考になるのでは。
、、、(全部見てませんが)ほぼ同じ? 何でこんなことになるんでしょうかね。
まともに動かないコードをこれ動くぜなんてふうに公開する人がいるからでは。
基本文法をちゃんと学んで一から自分で作り直した方が話が早いし身にもなるんですけどねぇ。オブジェクト指向辺りが分からなければ無理して使う必要無いはずだし。「課題消化の為なので、理解できなくていいからとにかく答えが欲しい」ならそう書いてもらった方がそれも話が早くていいでしょう。(もちろんteratailではNGで、低評価集めるだけですけど)
返信ありがとうございます。また基本文法から考えてみたいと思います。
それで、この質問はどこかに提出する課題なのでしょうか。
いえ、提出はしない予定です
ほぼ同じと思われるそのコードの質問の投稿が去年2021年の7月なので、もしかしたら同じ学校の課題なのかもしれませんね。こういうの多いですね。
そうかもしれないです。

回答1件
あなたの回答
tips
プレビュー