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

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

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

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

Q&A

2回答

3771閲覧

NEW Java ブラックジャックを作成しています。

thx1139

総合スコア4

Java

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

0グッド

0クリップ

投稿2020/04/15 09:41

編集2020/04/17 08:21

前提・実現したいこと

Javaでブラックジャックを作成しています。
・トランプの絵柄は今回無視しています。
・エースは1と11がありますが、1で固定しています。
ゲームの流れ
・ディーラーがカードを2枚引く
・ディーラーは手札の合計が17以上になるまでカードを引き続ける。
・ユーザーがカードを2枚引く。
・ディーラーは手札の合計が17以上になるまでカードを引き続ける。
・ディーラーとユーザーのスコアを比べる。
・ユーザーのバースト、勝ち、負け、いずれかの結果を発表する。

発生している問題

・ディーラーがバストしたとき、ディーラーがもう一枚カードを引いている。
・ディーラーがバストしたとき、ユーザーはバストしていないのに、負け判定になる。
・ディーラーとユーザーは17以上になるまでカードを引き続けるようにしたいが、3枚目を引いた時点で終了してしまう。(この点は恐らくループ処理を用いるべきだと考えています。)

※初めての質問で大変恐縮ですが、質問の仕方、入力場所等に誤りがあるかもしれませんが、その際は遠慮なくご指摘ください。

java

1package home; 2import java.util.ArrayList; 3abstract class Human { 4 ArrayList<Integer> myCards = new ArrayList<>(); //両プレイヤーの手札の情報 5 6 7 abstract protected int open(); //手札の合計値を計算 8 abstract protected void setCard(ArrayList<Integer>drawnCards); //引いたカードを手札に追加 9 abstract protected boolean checkSum(); //まだカードを引くべきか判断する 10} 11//Human,User,Dealerクラスにおいて、全てのメソッドにpublic,全てのフィールドにprotected. 12//ディーラーが3枚引いて終了してしまう.

java

1package home; 2import java.util.ArrayList; 3 4public class User extends Human { 5 6 protected int total=0; 7 @Override 8 public int open() { //手札の合計値を計算 9 int result =0; 10 for(int i =0;i<myCards.size();i++) { 11 result+= myCards.get(i); 12 } 13 return result;//戻り値は手札の合計値 14 } 15 16 @Override//引いたカードを手札に追加するメソッド 17 public void setCard(ArrayList<Integer>drawnCards) { 18 myCards.addAll(drawnCards); 19 } 20 21 @Override 22 public boolean checkSum() { 23 if(total<17) { 24 return true; 25 }else { 26 return false; 27 } 28 } 29}

java

1package home; 2import java.util.ArrayList; 3import java.util.Collections; 4 5public class Dealer extends Human { 6 ArrayList<Integer> cards = new ArrayList<>(); //山札のデッキ 7 protected int total=0; 8 @Override //手札の合計値を計算 9 public int open() { 10 int result =0; 11 for(int i =0;i<myCards.size();i++) { 12 result+= myCards.get(i); 13 } 14 return result;//戻り値は手札の合計値 15 } 16 @Override //引いたカードを手札に追加するメソッド 17 public void setCard(ArrayList<Integer> drawnCards) { 18 myCards.addAll(drawnCards); 19 } 20 @Override 21 public boolean checkSum() { 22 if(total<=17) { 23 return true; 24 }else { 25 return false; 26 } 27 } 28 //コンストラクタ 29 //山札に全カードを追加 30 //最後に山札をシャッフル 31 public Dealer() { 32 for (int m =1;m<=4;m++) { 33 for(int n =1;n<=13;n++) { 34 cards.add(n); 35 } 36 } 37 Collections.shuffle(cards); 38 } 39 //山札から2枚引き、引いたカードを戻り値にする 40 //引いたカードを山札からremoveする 41 public ArrayList<Integer> deal() { 42 ArrayList<Integer> drawnCards = new ArrayList<>();//両プレイヤーの引いたカード// 43 drawnCards.add(cards.get(0)); 44 cards.remove(0); 45 drawnCards.add(cards.get(1)); 46 cards.remove(1); 47 return drawnCards; 48 } 49 //山札から1枚引き、ひいたカードを戻り値とする。 50 public ArrayList<Integer> hit() { 51 ArrayList<Integer> hit= new ArrayList<>(); 52 hit.add(cards.get(0)); 53 cards.remove(0); 54 return hit; 55 } 56}

java

1package home; 2 3public class BlackJack { 4 public static void main(String[] args) { 5 User user1 = new User(); 6 Dealer dealer1 = new Dealer(); 7 System.out.println("ブラックジャックを始めます。"); 8 user1.setCard(dealer1.deal()); 9 dealer1.setCard(dealer1.deal()); 10 System.out.println("ディーラーのカードは"+dealer1.myCards.get(0)+","+dealer1.myCards.get(1)+"です。"); 11 if(dealer1.checkSum()==true) { 12 System.out.println("ディーラーはもう一枚引きます。"); 13 dealer1.setCard(dealer1.hit()); 14 System.out.println("ディーラーの引いたカードは"+dealer1.myCards.get(0)+","+dealer1.myCards.get(1)+","+dealer1.myCards.get(2)+"です。"); 15 System.out.println("ディーラーのスコアは合計で"+dealer1.open()+"です。"); 16 }else { 17 System.out.println("ディーラーのスコアは確定しました。"); 18 } 19 System.out.println("あなたのカードは"+user1.myCards.get(0)+","+user1.myCards.get(1)+"です。"); 20 if (user1.checkSum()==true) { 21 System.out.println("あなたはもう一枚引きます。"); 22 user1.setCard(dealer1.hit()); 23 }else { 24 System.out.println("あなたのスコアは確定しました。"); 25 } 26 System.out.println("ディーラーの合計スコアは"+dealer1.open()+"です。"); 27 System.out.println("あなたの合計スコアは"+user1.open()+"です。"); 28 if(user1.open()>21) { 29 System.out.println("あなたはバーストしました。あなたの負けです。"); 30 }else if (user1.open()>dealer1.open()) { 31 System.out.println("あなたの勝ちです。"); 32 }else { 33 System.out.println("あなたの負けです。"); 34 } 35 } 36}

java

1ブラックジャックを始めます。 2ディーラーのカードは6,12です。 3ディーラーはもう一枚引きます。 4ディーラーの引いたカードは6,12,9です。 5ディーラーのスコアは合計で27です。 6あなたのカードは4,13です。 7あなたはもう一枚引きます。 8ディーラーの合計スコアは27です。 9あなたの合計スコアは19です。 10あなたの負けです。

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

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

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

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

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

gentaro

2020/04/15 09:43

> ※初めての質問で大変恐縮ですが、質問の仕方、入力場所等に誤りがあるかもしれませんが、その際は遠慮なくご指摘ください。 「タイトルには要件を書きましょう」 https://teratail.com/help/question-tips#questionTips3-1 タイトル読んだだけだと「おう、頑張ってね」で終わっちゃう。
swordone

2020/04/15 09:59

このコードでコンパイルエラーなく動くはずがありません。 動かしたときのコードをそのまま掲載してください。
m.ts10806

2020/04/15 13:56

画像で提示されてもこちらで動作確認困難です。
jimbe

2020/04/15 14:04

なぜコードから画像にされたのかと思いましたら, swordone さんの「そのまま掲載」というコメントを勘違いされたのでしょうか. コードは(修正される前のように) ``` で囲った状態のご提示にしてください. 回答する際にそのコードをコピペして再現テストをしたりしますので, 画像では全て手入力しなければならず, その段階で入力間違いがあっては元も子もありません. swordone さんが仰るのは, 「問題が発覚してから YamatoKogushi さんのほうで原因究明等の為にコードを色々弄ってみたりされているでしょうけれども, 元の(エラー無くコンパイルでき, 実行すると問題が再現できる)コードをご提示ください」ということかと思います.
thx1139

2020/04/17 08:22

的確で丁寧なご指摘をどうもありがとうございました。 再度コードを修正しましたので、お手すきの際にアドバイスを頂ければ幸いです。
jimbe

2020/04/17 09:38

こちらは Q&A のサイトで, Q&A を蓄積することで、以後同じ問題に遭遇した方が解決策を得られるようにという目的があります. 進捗があるのは良いことですが, 質問内容をどんどん変えてしまうと, 回答との齟齬が発生しますし, 以前に発生していた問題が分からなくなります. (編集履歴は残りますが, 恐らく検索には掛からないでしょう.) コードはともかく, ご質問内容はなるべく追加するようにして頂いたほうが宜しいかと思います. さらには, 「回答のサポート」はともかく「開発のサポート」もまた趣旨に合わないように思います. もちろん, コードも仕様もそれを作る人も多種多様であって, 発生する問題も同様であることは大前提ですが,「不具合→解決→不具合→解決...という開発時に普通にあるサイクル」を QAサイトの 質問→回答→次の質問→さらに回答...という展開にするのは, 如何でしょうか. 「少しでも趣旨に合わないことはするな」というつもりはありませんし, 自身そんなに厳密に条件を決めて teratail に関与しているわけでもありませんが, 「そんな意見もあるのね」的にでもご理解頂けると幸いです.
thx1139

2020/04/17 10:04

ご回答ありがとうございます。コードと質問内容を大幅に変更した理由は、自身が理解できていないままに、質問してしまった点、また、改善点が多すぎてかえって参考にならないと私が判断したことによります。 teratailの趣旨を確認したところ、「プログラミングに関わる問題を皆で正しあい、切磋琢磨できる環境を作る。」というものでした。 その観点から、私は別段、趣旨に合わないとは判断していません。また、teratailの推奨していない質問にも該当しないと私は判断しました。 しかしながら、jimbeさんのおっしゃる通り、何度も変更することは他の方の情報資産にならないので、今後は慎みたいと思います。貴重なご意見ありがとうございます。
m.ts10806

2020/04/17 11:27

元の質問を残して追記すれば良かったのでは。 既に回答やコメントがついている以上、指摘内容の反映ならともかく、大幅改変するときには関わっている人への確認(相談)は不可欠と思います。
jimbe

2020/04/18 07:18

> ※初めての質問で大変恐縮ですが ~ ということでしたが > teratailの趣旨を確認 されたということですので(元よりですが)判断はお任せです. 失礼しました. 個人的には, コードの変容は即ち作者である YamatoKogushi さんのプログラミング技術の変化の現れですので, 変容を見てみたくもあり, 失礼な例えですが「二軍の野球選手の話でも(未来のスターの卵たりえる)野球少年の役には立つかもしれない」ような感覚でいます.
guest

回答2

0

ディーラーがバストしたとき、ディーラーがもう一枚カードを引いている。

こちら意味が分からないのですが, バーストはもう一枚引いた為に発生するのではないでしょうか.
引かずにバーストはしないと思うのですが.

実行例で 6,12 と合計 18 なのにもう一枚引いているということでしょうか.
checkSum で使用している total 変数が全く計算されていない( 0 のまま)為かと思います.

ディーラーがバストしたとき、ユーザーはバストしていないのに、負け判定になる。

勝敗判定にディーラーがバーストしている場合という判定( if 文)がありません.

ディーラーとユーザーは17以上になるまでカードを引き続けるようにしたいが、3枚目を引いた時点で終了してしまう

仰る通り, ループしなければならないでしょう.

なお, 「ディーラーとユーザーは17以上になるまで」とされていますが, コード上では Dealer と User で checkSum が異なっています.
また, checkSum が同じコードとなるのであれば, Dealer/User 双方で checkSum を定義する必要は無く, Human に定義しては如何でしょうか.
(これは現状でも内容が同じ open や setCard にも言えます.)

投稿2020/04/17 09:48

編集2020/04/17 09:51
jimbe

総合スコア12632

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

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

thx1139

2020/04/17 10:08

ご回答ありがとうございます。こちらは本来のブラックジャックであれば起こりえないのであまり参考にはならないかもしれませんが、11,12,13をそのままの数字でカウントする仕様になっているので、最初の二枚がそれらだと生じてしまうエラーとなっています。 他のご指摘に関してはアドバイス通り修正を試みようと思います。 どうもありがとうございます。
jimbe

2020/04/17 11:11 編集

あぁ、確かに, open は今は 11 以上をそのまま計算しているのでしたね. すいません失念していました. でも checkSum の total 変数に値が入っていない点では同じようです.
guest

0

java

1 b.setCard(b.deal());

まずここの実行を考えます。b.deal()の実行により、b.drawnCardsb.cards.get(0)b.cards.get(1)の結果が追加されます。これが1と13だとすると、b.drawnCardsの中身が[1,13]になります。その結果がsetCardによってb.myCardsに移され、b.myCardsの中身が[1,13]になります。

java

1 a.setCard(b.deal());

次にここの実行を考えます。再びb.deal()が実行されますが、**b.drawnCardsの中身はそのまま残っています。**すでにあった[1,13]に再び1と13が追加され、b.drawnCardsの中身は[1,13,1,13]となります。setCardによって、これがそっくりそのままa.myCardsに移され、a.myCardsの中身が[1,13,1,13]になります。
その後、○○のカードは~の出力に入りますが、どちらも最初の2枚しか出力しないため、ここでの見た目は変わらないように見えます。この状態で合計を取れば、aの方は同じカードセットを2回分持っているわけですから、当然倍になります。

本題に関係ないですが、「もう一枚引きます」とだけ出力して、実際には何もしていないです。
それを含めて、設計に大いに難ありです。

投稿2020/04/15 10:33

swordone

総合スコア20651

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

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

thx1139

2020/04/15 11:41

ご回答いただきありがとうございます。 ご回答により、ユーザーの値が常に2倍になることは理解できました。 しかし、それをどのように克服すればよいかが分かりません。 差し支えなければご教授くださいますようよろしくお願いします。
jimbe

2020/04/16 06:04

「中身がそのまま残っている」から remove メソッドをお考えになったようですが, 肝心の『どの段階で』残っているのが問題なのかを回答から読み取れておられないようです. 必要な個所に必要な処理を入れるためには, プログラムのどの段階でどの変数がどのような意味を持ってどのような値になってる必要があるかをイメージ出来なければなりません. swordone さんはそのイメージに沿って説明・回答されていますので, 再度イメージを持って確認されては如何でしょうか.
thx1139

2020/04/17 08:25

アドバイスを頂きありがとうございました。jimbeさんのおっしゃる通り、どこにremoveを入れればよいかという認識を記載していませんでした。現状では中身がそのまま残っているという問題は解決しました。 しかし、上記のように、ゲームを進めるうえでの修正が新たに必要なので、もしよろしければ助言を頂けると幸いです。
jimbe

2020/04/17 09:04

remove を追加されましたが, > drawnCards.add(cards.get(0)); > cards.remove(0); > drawnCards.add(cards.get(1)); > cards.remove(1); remove(0) した時点でcards の中身は1つ減り, 2枚目だったものが1枚目に, 3枚目だったものが2枚目に...と移動しています. その状態で get(1)/remove(1) をしては, その時点で1枚目にあるものを抜かしていることになります. ゲームとしてはどちらでも変わらないとは思いますが...
thx1139

2020/04/17 10:24

ご回答ありがとうございます。こちらのご回答が良く理解できていないので、詳細にお教えいただけると幸いです。removeを用いるタイミングが適切でないということでしょうか?
jimbe

2020/04/17 11:08

cards に 52 枚のカード, 分かり易く 1,2,3,4,... が入っているとします. get(0), remove(0) で先頭の一枚, "1" が取り出され, 削除されます. この時点で, cards には 51 枚のカード 2,3,4,... が残ります. もう一枚得るのであれば, また先頭, すなわちもう一度 get(0), remove(0) を行えば "2" が取り出され, cards には 50 枚のカード 3,4,... が残ることになります.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問