NEW Java ブラックジャックを作成しています。
- 評価
- クリップ 0
- VIEW 772
前提・実現したいこと
Javaでブラックジャックを作成しています。
・トランプの絵柄は今回無視しています。
・エースは1と11がありますが、1で固定しています。
ゲームの流れ
・ディーラーがカードを2枚引く
・ディーラーは手札の合計が17以上になるまでカードを引き続ける。
・ユーザーがカードを2枚引く。
・ディーラーは手札の合計が17以上になるまでカードを引き続ける。
・ディーラーとユーザーのスコアを比べる。
・ユーザーのバースト、勝ち、負け、いずれかの結果を発表する。
発生している問題
・ディーラーがバストしたとき、ディーラーがもう一枚カードを引いている。
・ディーラーがバストしたとき、ユーザーはバストしていないのに、負け判定になる。
・ディーラーとユーザーは17以上になるまでカードを引き続けるようにしたいが、3枚目を引いた時点で終了してしまう。(この点は恐らくループ処理を用いるべきだと考えています。)
※初めての質問で大変恐縮ですが、質問の仕方、入力場所等に誤りがあるかもしれませんが、その際は遠慮なくご指摘ください。
package home;
import java.util.ArrayList;
abstract class Human {
ArrayList<Integer> myCards = new ArrayList<>(); //両プレイヤーの手札の情報
abstract protected int open(); //手札の合計値を計算
abstract protected void setCard(ArrayList<Integer>drawnCards); //引いたカードを手札に追加
abstract protected boolean checkSum(); //まだカードを引くべきか判断する
}
//Human,User,Dealerクラスにおいて、全てのメソッドにpublic,全てのフィールドにprotected.
//ディーラーが3枚引いて終了してしまう.
package home;
import java.util.ArrayList;
public class User extends Human {
protected int total=0;
@Override
public int open() { //手札の合計値を計算
int result =0;
for(int i =0;i<myCards.size();i++) {
result+= myCards.get(i);
}
return result;//戻り値は手札の合計値
}
@Override//引いたカードを手札に追加するメソッド
public void setCard(ArrayList<Integer>drawnCards) {
myCards.addAll(drawnCards);
}
@Override
public boolean checkSum() {
if(total<17) {
return true;
}else {
return false;
}
}
}
package home;
import java.util.ArrayList;
import java.util.Collections;
public class Dealer extends Human {
ArrayList<Integer> cards = new ArrayList<>(); //山札のデッキ
protected int total=0;
@Override //手札の合計値を計算
public int open() {
int result =0;
for(int i =0;i<myCards.size();i++) {
result+= myCards.get(i);
}
return result;//戻り値は手札の合計値
}
@Override //引いたカードを手札に追加するメソッド
public void setCard(ArrayList<Integer> drawnCards) {
myCards.addAll(drawnCards);
}
@Override
public boolean checkSum() {
if(total<=17) {
return true;
}else {
return false;
}
}
//コンストラクタ
//山札に全カードを追加
//最後に山札をシャッフル
public Dealer() {
for (int m =1;m<=4;m++) {
for(int n =1;n<=13;n++) {
cards.add(n);
}
}
Collections.shuffle(cards);
}
//山札から2枚引き、引いたカードを戻り値にする
//引いたカードを山札からremoveする
public ArrayList<Integer> deal() {
ArrayList<Integer> drawnCards = new ArrayList<>();//両プレイヤーの引いたカード//
drawnCards.add(cards.get(0));
cards.remove(0);
drawnCards.add(cards.get(1));
cards.remove(1);
return drawnCards;
}
//山札から1枚引き、ひいたカードを戻り値とする。
public ArrayList<Integer> hit() {
ArrayList<Integer> hit= new ArrayList<>();
hit.add(cards.get(0));
cards.remove(0);
return hit;
}
}
package home;
public class BlackJack {
public static void main(String[] args) {
User user1 = new User();
Dealer dealer1 = new Dealer();
System.out.println("ブラックジャックを始めます。");
user1.setCard(dealer1.deal());
dealer1.setCard(dealer1.deal());
System.out.println("ディーラーのカードは"+dealer1.myCards.get(0)+","+dealer1.myCards.get(1)+"です。");
if(dealer1.checkSum()==true) {
System.out.println("ディーラーはもう一枚引きます。");
dealer1.setCard(dealer1.hit());
System.out.println("ディーラーの引いたカードは"+dealer1.myCards.get(0)+","+dealer1.myCards.get(1)+","+dealer1.myCards.get(2)+"です。");
System.out.println("ディーラーのスコアは合計で"+dealer1.open()+"です。");
}else {
System.out.println("ディーラーのスコアは確定しました。");
}
System.out.println("あなたのカードは"+user1.myCards.get(0)+","+user1.myCards.get(1)+"です。");
if (user1.checkSum()==true) {
System.out.println("あなたはもう一枚引きます。");
user1.setCard(dealer1.hit());
}else {
System.out.println("あなたのスコアは確定しました。");
}
System.out.println("ディーラーの合計スコアは"+dealer1.open()+"です。");
System.out.println("あなたの合計スコアは"+user1.open()+"です。");
if(user1.open()>21) {
System.out.println("あなたはバーストしました。あなたの負けです。");
}else if (user1.open()>dealer1.open()) {
System.out.println("あなたの勝ちです。");
}else {
System.out.println("あなたの負けです。");
}
}
}
ブラックジャックを始めます。
ディーラーのカードは6,12です。
ディーラーはもう一枚引きます。
ディーラーの引いたカードは6,12,9です。
ディーラーのスコアは合計で27です。
あなたのカードは4,13です。
あなたはもう一枚引きます。
ディーラーの合計スコアは27です。
あなたの合計スコアは19です。
あなたの負けです。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
b.setCard(b.deal());
まずここの実行を考えます。b.deal()
の実行により、b.drawnCards
にb.cards.get(0)
とb.cards.get(1)
の結果が追加されます。これが1と13だとすると、b.drawnCards
の中身が[1,13]
になります。その結果がsetCard
によってb.myCards
に移され、b.myCards
の中身が[1,13]
になります。
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回分持っているわけですから、当然倍になります。
本題に関係ないですが、「もう一枚引きます」とだけ出力して、実際には何もしていないです。
それを含めて、設計に大いに難ありです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
>ディーラーがバストしたとき、ディーラーがもう一枚カードを引いている。
こちら意味が分からないのですが, バーストはもう一枚引いた為に発生するのではないでしょうか.
引かずにバーストはしないと思うのですが.
実行例で 6,12 と合計 18 なのにもう一枚引いているということでしょうか.
checkSum で使用している total 変数が全く計算されていない( 0 のまま)為かと思います.
>ディーラーがバストしたとき、ユーザーはバストしていないのに、負け判定になる。
勝敗判定にディーラーがバーストしている場合という判定( if 文)がありません.
>ディーラーとユーザーは17以上になるまでカードを引き続けるようにしたいが、3枚目を引いた時点で終了してしまう
仰る通り, ループしなければならないでしょう.
なお, 「ディーラーとユーザーは17以上になるまで」とされていますが, コード上では Dealer と User で checkSum が異なっています.
また, checkSum が同じコードとなるのであれば, Dealer/User 双方で checkSum を定義する必要は無く, Human に定義しては如何でしょうか.
(これは現状でも内容が同じ open や setCard にも言えます.)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.22%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
gentaro
2020/04/15 18:43
> ※初めての質問で大変恐縮ですが、質問の仕方、入力場所等に誤りがあるかもしれませんが、その際は遠慮なくご指摘ください。
「タイトルには要件を書きましょう」
https://teratail.com/help/question-tips#questionTips3-1
タイトル読んだだけだと「おう、頑張ってね」で終わっちゃう。
swordone
2020/04/15 18:59
このコードでコンパイルエラーなく動くはずがありません。
動かしたときのコードをそのまま掲載してください。
m.ts10806
2020/04/15 22:56
画像で提示されてもこちらで動作確認困難です。
jimbe
2020/04/15 23:04
なぜコードから画像にされたのかと思いましたら, swordone さんの「そのまま掲載」というコメントを勘違いされたのでしょうか.
コードは(修正される前のように) ``` で囲った状態のご提示にしてください. 回答する際にそのコードをコピペして再現テストをしたりしますので, 画像では全て手入力しなければならず, その段階で入力間違いがあっては元も子もありません.
swordone さんが仰るのは, 「問題が発覚してから YamatoKogushi さんのほうで原因究明等の為にコードを色々弄ってみたりされているでしょうけれども, 元の(エラー無くコンパイルでき, 実行すると問題が再現できる)コードをご提示ください」ということかと思います.
YamatoKogushi
2020/04/17 17:22
的確で丁寧なご指摘をどうもありがとうございました。
再度コードを修正しましたので、お手すきの際にアドバイスを頂ければ幸いです。
jimbe
2020/04/17 18:38
こちらは Q&A のサイトで, Q&A を蓄積することで、以後同じ問題に遭遇した方が解決策を得られるようにという目的があります.
進捗があるのは良いことですが, 質問内容をどんどん変えてしまうと, 回答との齟齬が発生しますし, 以前に発生していた問題が分からなくなります. (編集履歴は残りますが, 恐らく検索には掛からないでしょう.)
コードはともかく, ご質問内容はなるべく追加するようにして頂いたほうが宜しいかと思います.
さらには, 「回答のサポート」はともかく「開発のサポート」もまた趣旨に合わないように思います.
もちろん, コードも仕様もそれを作る人も多種多様であって, 発生する問題も同様であることは大前提ですが,「不具合→解決→不具合→解決...という開発時に普通にあるサイクル」を QAサイトの 質問→回答→次の質問→さらに回答...という展開にするのは, 如何でしょうか.
「少しでも趣旨に合わないことはするな」というつもりはありませんし, 自身そんなに厳密に条件を決めて teratail に関与しているわけでもありませんが, 「そんな意見もあるのね」的にでもご理解頂けると幸いです.
m.ts10806
2020/04/17 18:51
NEW と書かれましても。
https://teratail.com/help/question-tips
YamatoKogushi
2020/04/17 19:04
ご回答ありがとうございます。コードと質問内容を大幅に変更した理由は、自身が理解できていないままに、質問してしまった点、また、改善点が多すぎてかえって参考にならないと私が判断したことによります。
teratailの趣旨を確認したところ、「プログラミングに関わる問題を皆で正しあい、切磋琢磨できる環境を作る。」というものでした。
その観点から、私は別段、趣旨に合わないとは判断していません。また、teratailの推奨していない質問にも該当しないと私は判断しました。
しかしながら、jimbeさんのおっしゃる通り、何度も変更することは他の方の情報資産にならないので、今後は慎みたいと思います。貴重なご意見ありがとうございます。
m.ts10806
2020/04/17 20:27
元の質問を残して追記すれば良かったのでは。
既に回答やコメントがついている以上、指摘内容の反映ならともかく、大幅改変するときには関わっている人への確認(相談)は不可欠と思います。
jimbe
2020/04/18 16:18
> ※初めての質問で大変恐縮ですが ~
ということでしたが
> teratailの趣旨を確認
されたということですので(元よりですが)判断はお任せです.
失礼しました.
個人的には, コードの変容は即ち作者である YamatoKogushi さんのプログラミング技術の変化の現れですので, 変容を見てみたくもあり, 失礼な例えですが「二軍の野球選手の話でも(未来のスターの卵たりえる)野球少年の役には立つかもしれない」ような感覚でいます.