Javaでブラックジャックを作成してみた(betあり, splitあり, double downあり, 8デック)_概要編

# はじめに(ソース編と同じ内容)
コンソールで遊ぶブラックジャックです。

Qiitaで参考になる記事を検索しました。hit,stay(stand)のみの記事はいっぱいあったのですが、
以下内容のブラックジャック記事は見つけきれませんでした。多分まだ無いです。
　-> ブラックジャックで検索すると186件ぐらいあったのに。。(2022/03/06現在の情報)

ルール内容は、以下の通りです。

|項目 |内容 |補足 |
|---|---|---|
|デッキ数 |8デッキ(計416枚) |１デッキ＝52枚(１～13のトランプ、ジョーカー抜き)|
|カードのシャッフルタイミング |総数の50%を消費した場合 |ゲーム途中の交換は不自然なため、交換タイミングはゲームの切れ目|
|ベッティング| あり|ベットベルの種類 -> 1～1000(ベル)|
|ディーラーの行動原則 |17以上になるまでhit|-|
|プレイヤーのできる行動 |hit, stand, double down, split|-|
|double down|最初の行動でのみ選択可能 |-|
|double down後 |追加は、1枚のみ |ベットベル2倍|
|split |同じ数字が最初の手札で揃った場合のみ選択可能 |10, J, Q, Kは同じ数字(10)のため可能|
|split後 |double downは禁止 |手札を2つに分けるためベットベルが2倍|
|プレイヤーが21で勝ち |1.5倍の配当 |端数は切り捨て|

無いなら作りましょうということで、作りました。

1からちゃんと作成したのですが、完成までにかかった時間は
実装・リファクタリング・簡易テストで、多分20時間ぐらい!?
ながら作成とはいえ、結構時間かかりました。
特にsplitの手札分ける処理の設計を考えて実装するのが1番時間かかった箇所です。

リファクタリングしたりコメント書いたりと、
新人プログラマ向けに見やすいように作成したつもりです。
いいなと思ったらLooks Good To Meをくれると作者が喜びます。。
ぜひよろしくお願いします =)

<strong><font color="red">
プログラム内容は、ソース編参照してください！
</strong></font>
[Javaでブラックジャックを作成してみた(betあり, splitあり, double downあり, 8デッキ)_ソース編](https://qiita.com/copper_dog/items/05320b7ebceac3335d6a/)


# なぜブラックジャックなのか

[プログラミング入門者からの卒業試験は『ブラックジャック』を開発する](https://qiita.com/hirossyi73/items/cf8648c31898216312e5)
のがお勧めだそうなので、どのくらい綺麗に書けるか実装してみました。
上記リンク(hirossyi73さん記事)に記載がある通り、納得のいく内容でした。
　・基本ルールがシンプル(split、double downを抜いた場合)
　・かつ、戦術が複数あるので、さらなる高みを目指せる
　・ディーラー（CPU）のカードを引くルールは絶対的

色々機能(split, double down, betting, 複数デッキ)を抜くと確かにルールがsimpleなのですが。
うーん。基本ルールのみだと遊んでて楽しく無いですよね。

ということで[**はじめに**]に記載があるように、基本ルールに色々機能追加してます。

# パッケージ配置

パッケージエクスプローラーは、以下のように作成。
![スクリーンショット 2022-03-07 140049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508154/b12cce37-7f8c-e43a-ac30-5eba4af9c967.png)

# クラス設計
全然UMLとかでは無いので、理解しづらいかもしれませんが、
「頭の中のクラス設計を図にしたら」ってのが、以下のイメージです。
![スクリーンショット 2022-03-09 011347.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508154/059d6d54-260d-8c6c-5998-bb775ccc0fe2.png)


詳細は、ソース編をご覧ください。

# 使い方と結果

まずは、実際にどんな感じになったか見てみましょう。

1 : **開始してみましょう**
　1-1 システム起動の挨拶
　1-2 ゲーム開始の挨拶
　1-3 プレイヤーの軍資ベルを表示
　1-4 ベットベルを促すメッセージを表示
　1-5 ユーザーに入力をしてもらう

```console:開始時
****************************************
****************************************
    ブラックジャックへようこそ!!    
****************************************
-----------------------------------
    ゲーム開始!!    
-----------------------------------
  Playerの所持ベル  ->  1000

ベットするベルを入力してください(end -> 終了)
  >
```

2 : **ベットしてみよう**
　2-1 強制終了してみよう(endと入力)
　　-> 強制終了できました！ 終了する際に、残りの所持ベルと儲けを表示します。
```console:ベットしてみよう1
  >end
  Playerの所持ベル  ->  1000
  0ベル勝ちました。 

  copper_dog「Thank you for playing!! :)」
```

　2-2 所持ベル以上のベルを入力してみよう(1001と入力)
　　-> エラーとなって、再入力をお願いしています。
```console:ベットしてみよう2
  >1001

    Error : ベルがたりません。もう一度入力してください    


ベットするベルを入力してください(end -> 終了)
  >
```

　2-3 ベットしてみよう(10)
　　-> 10ベルをベットでき、ゲームが始まりました。
```console:ベットしてみよう3
  >10
DEALER  (10): (♠K )  (??)
Player  (11): (♠8 )  (♥3 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >
```

3 : **遊んでみよう**
　3-1 hitしてみよう(バーストするまでhit後、続けて遊ばないを選択)
　　hを入力することで、ヒットができてますね。
　　バーストしたので、負けてます。所持ベルも減ってます。
```console:遊んでみよう1
  >10
DEALER  (10): (♠K )  (??)
Player  (11): (♠8 )  (♥3 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >h
DEALER  (10): (♣10)  (??)
Player  (14): (♠8 )  (♥3 )  (♦3 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay
  >h
DEALER  (23): (♣10)  (♣2 )  (♣4 )  (♦7 )
Player  (23): (♠8 )  (♥3 )  (♦3 )  (♥9 )
-----------------------------------
DEALER「You are lose.」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >n

****************************************

  Playerの所持ベル  ->  990
  10ベル負けました。 

  copper_dog「Thank you for playing!! :)」    
```

　3-2 stay(stand)してみよう(1回hitした後、stayする。その後、続けて遊ばないを選択)
　　1回hitした後に、standすることで、結果表示が出てますね。
　　勝ちましたので、所持ベルも増えてます。
　　(♠A )の値が、11から1(計21を超えると1)に変化するところも見れました！
```console:遊んでみよう2
  >10
DEALER  (5): (♦5 )  (??)
Player  (13): (♠A )  (♥2 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >h
DEALER  (5): (♦5 )  (??)
Player  (13): (♠A )  (♥2 )  (♣10)
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay
  >s
DEALER  (23): (♦5 )  (♦8 )  (♥J )
Player  (13): (♠A )  (♥2 )  (♣10)
-----------------------------------
DEALER「congratulation. You are win」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >n

****************************************

  Playerの所持ベル  ->  1010
  10ベル勝ちました。

  copper_dog「Thank you for playing!! :)」
```

　3-3 double downしてみよう
　　初手のみdouble downできます。
　　結果がちょっと複雑なのですが、以下のような動きなので正常です。

|行動 |ベット額 |所持ベル |リターン額 |
|---|---|---|---|
|10ベルベット |10ベル |990ベル|-|
|double down(ベットベル2倍　ただし、もうhitできない) |20ベル |980ベル|-|
|21で勝利 |- |980ベル|(20 * 2.5)|

　　結果　-> 所持ベル 1030(980 + 50)ベル となります。

```console:遊んでみよう3
  >10
DEALER  (10): (♣J )  (??)
Player  (18): (♥A )  (♦7 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >d
DEALER  (18): (♣J )  (♥8 )
Player  (21): (♥A )  (♦7 )  (♦3 )
-----------------------------------
DEALER「congratulation. You are BLACK JACK!!」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >n

****************************************

  Playerの所持ベル  ->  1030
  30ベル勝ちました。 

  copper_dog「Thank you for playing!! :)」 
```

　3-4 splitしてみよう
　　初手のみ かつ 手札2枚が同じ時のみsplitできます。
　　①splitして手札が分かれる
　　②PlayerRの行動選択で、stayを選択
　　③PlayerLに切り替わり、hitを選択
　　④PlayerLで、stayを選択
　　⑤結果は、両方負けましたので20ベル負けてます

```console:遊んでみよう4
  >10
DEALER  (2): (♠2 )  (??)
Player  (20): (♠J )  (♠J )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down  p:split
  >p
DEALER  (2): (♠2 )  (??)
PlayerR (20): (♠J )  (♠J )
PlayerL (13): (♠J )  (♦3 )
-----------------------------------
PlayerRの行動を選択してください。
  h: hit  s:stay
  >s
PlayerLの行動を選択してください。
  h: hit  s:stay
  >h
DEALER  (2): (♠2 )  (??)
PlayerR (20): (♠J )  (♠J )
PlayerL (19): (♠J )  (♦3 )  (♠6 )
-----------------------------------
PlayerLの行動を選択してください。
  h: hit  s:stay
  >s
DEALER  (21): (♠2 )  (♥A )  (♥3 )  (♦K )  (♦5 )
PlayerR (20): (♠J )  (♠J )
PlayerL (19): (♠J )  (♦3 )  (♠6 )
-----------------------------------
DEALER「PlayerR is lose.」
DEALER「PlayerL is lose.」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >n

****************************************

  Playerの所持ベル  ->  980
  20ベル負けました。 

  copper_dog「Thank you for playing!! :)」
```
4 : **2回連続で遊んでみよう**
　デッキの中身と、ベットベルが引き継がれます。
　2回とも10ベルかけて、勝ったので1020ベルの手持ちになるというだけです。
```console:2回連続で遊んでみよう
****************************************
****************************************
    ブラックジャックへようこそ!!    
****************************************
-----------------------------------
    ゲーム開始!!    
-----------------------------------
  Playerの所持ベル  ->  1000

ベットするベルを入力してください(end -> 終了)
  >10
DEALER  (5): (♣5 )  (??)
Player  (19): (♠9 )  (♠Q )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >s
DEALER  (18): (♣5 )  (♠5 )  (♦8 )
Player  (19): (♠9 )  (♠Q )
-----------------------------------
DEALER「congratulation. You are win」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >y

****************************************

-----------------------------------
    ゲーム開始!!    
-----------------------------------
  Playerの所持ベル  ->  1010

ベットするベルを入力してください(end -> 終了)
  >10
DEALER  (8): (♠8 )  (??)
Player  (13): (♦9 )  (♣4 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay  d:double down
  >h
DEALER  (8): (♠8 )  (??)
Player  (20): (♦9 )  (♣4 )  (♣7 )
-----------------------------------
Playerの行動を選択してください。
  h: hit  s:stay
  >s
DEALER  (18): (♠8 )  (♠J )
Player  (20): (♦9 )  (♣4 )  (♣7 )
-----------------------------------
DEALER「congratulation. You are win」

****************************************

もう一回、遊べるドン。
  y: yes  n:no
  >n

****************************************

  Playerの所持ベル  ->  1020
  20ベル勝ちました。 

  copper_dog「Thank you for playing!! :)」    
```

5 : **実際のコンソールは!?**
　こんな感じです。結果は以上です。

:::note warn
修正  -> 黒く塗りつぶしている箇所は、ベルという文字となっております。
:::

![スクリーンショット 2022-03-09 140043.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2508154/bec94300-6fa8-830d-870b-13d58ad86574.png)


# 最後に
hitとstandだけのブラックジャック実装より、難易度は確かに上がった気がします。
新人プログラマー向けのいい教材だと思うので、皆さんも実装して、周りに勧めてみて下さいね！

ボリュームあるのですがソース編も余裕があったら見てくれると嬉しいです。