カードゲーム「ブラックジャック」を Ruby で実装する

Qiita を見ていたら「初心者はブラックジャックを実装してみるといいよ」とかいう記事があったので、おもしろそうだと Ruby で実装してみました。

とりあえず実行例を見て下さい。

$ ruby blackjack.rb
カードをシャッフルします

コイン: 10000 点   ベットは?(enter = 1000):
  ベットは 1000 点です
=== カードを配ります ====
ディーラーの一枚は ♠6 です
プレイヤーの二枚は ♣Q と ♢9 です
Hit or Stand? (H or S): s
勝負です:
ディーラーのもう一枚は ♡7 です
  ディーラーはもう一枚引きます
ディーラーの引いたのは ♡8 です
ディーラーの合計は 21、プレイヤーの合計は 19 です
ディーラーの勝ちです
** コインは 9000 点です

コイン: 9000 点   ベットは?(enter = 1000):4000
=== カードを配ります ====
ディーラーの一枚は ♢10 です
プレイヤーの二枚は ♣3 と ♡3 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♢2 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♠10 です
Hit or Stand? (H or S): s
勝負です:
ディーラーのもう一枚は ♡J です
ディーラーの合計は 20、プレイヤーの合計は 18 です
ディーラーの勝ちです
** コインは 5000 点です

コイン: 5000 点   ベットは?(enter = 1000):2000
=== カードを配ります ====
ディーラーの一枚は ♣5 です
プレイヤーの二枚は ♢3 と ♠8 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♡K です
Hit or Stand? (H or S): s
勝負です:
ディーラーのもう一枚は ♣7 です
  ディーラーはもう一枚引きます
ディーラーの引いたのは ♠J です
ディーラーの合計は 22、プレイヤーの合計は 21 です
プレイヤーの勝ちです
** コインは 7000 点です

コイン: 7000 点   ベットは?(enter = 1000):5000
=== カードを配ります ====
ディーラーの一枚は ♡9 です
プレイヤーの二枚は ♣J と ♠4 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♡10 です
プレイヤーはバーストです
ディーラーの勝ちです
** コインは 2000 点です

コイン: 2000 点   ベットは?(enter = 1000):1000
=== カードを配ります ====
ディーラーの一枚は ♣A です
プレイヤーの二枚は ♣4 と ♡4 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♣8 です
Hit or Stand? (H or S): s
勝負です:
ディーラーのもう一枚は ♡A です
  ディーラーはもう一枚引きます
ディーラーの引いたのは ♣10 です
  ディーラーはもう一枚引きます
ディーラーの引いたのは ♣2 です
  ディーラーはもう一枚引きます
ディーラーの引いたのは ♢J です
ディーラーの合計は 24、プレイヤーの合計は 16 です
プレイヤーの勝ちです
** コインは 3000 点です

コイン: 3000 点   ベットは?(enter = 1000):2000
=== カードを配ります ====
ディーラーの一枚は ♡6 です
プレイヤーの二枚は ♠K と ♢4 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♡Q です
プレイヤーはバーストです
ディーラーの勝ちです
** コインは 1000 点です

コイン: 1000 点   ベットは?(enter = 1000):
  ベットは 1000 点です
=== カードを配ります ====
ディーラーの一枚は ♠7 です
プレイヤーの二枚は ♡2 と ♢5 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♢6 です
Hit or Stand? (H or S): h
  Hitしました
プレイヤーのひいたカードは ♠2 です
Hit or Stand? (H or S): s
勝負です:
ディーラーのもう一枚は ♠Q です
ディーラーの合計は 17、プレイヤーの合計は 15 です
ディーラーの勝ちです
** コインは 0 点です

コインがなくなりました

 
こんなのですけれど、実際に遊んでみて、これはマジで結構アツいです! いやあ、ブラックジャック、おもしろいじゃないですか。

ルールはWikipediaどおりです。簡単にだけいうと、

  • 合計の点数が大きい方が勝ち。ただし、21 を超えると負け
  • J, Q, K は 10
  • A(エース)は 1 か 11 か、都合の良いほう
  • 最初はディーラーもプレーヤーも 2枚のカードが配られる。ディーラーの一枚はプレーヤーに見えている
  • プレーヤーは配られたカードを見て、もう一枚もらう(Hit)かもらわない(Stand)か、どちらかを選択できる。Hit は何度してもよいが、合計が 21 を超えた時点で負け(バースト)
  • ディーラーは合計が 17 以上になるまで引き続けないといけない

プレイヤーが「ナチュラル21」(最初に配られた二枚で 21)を出して勝った場合、ベットの2.5倍の点が払い戻されます。また、カードは最初に52枚すべてがシャッフルされ、何度かプレイしてデッキの枚数が15枚より少なくなるごとに、シャッフルし直します。なので、高度な戦略を練る場合はそれまで出たカードを覚えていて、それをもとに決めることも可能です。


コードは以下にあります。もし実行されるなら、コピペするよりも「Download ZIP」をポチリの方ががラクだと思います。
カードゲーム「ブラックジャック」の実装 · GitHub
長い長い関数でありまして、典型的な「叱られるクソコード」(笑)かもしれません。いやでも、ゲームは楽しいからよいことにしちゃいましょう。Ruby によるコーディングも楽しい!


Linux Mint 18.3, Ruby 2.3.3 と Windows 8.1, Ruby 2.2.2p95 (2015-04-13 revision 50295) [i386-mingw32] で動作確認しました。


※追記
まずないと思いますが、ゲームの途中でカードの山がなくなった場合に対応しました。また、ベットの入力でマイナス値を入れるとそこで終了するようにしました。勝ち逃げしたい方はどうぞ(笑)。

スート(スペードなどのカードの種類)の表示を機種依存文字から絵文字に替えました。