前回カードをRubyプログラム中の データとして保持する方法として3つの方式を考えた。
ハートの"A"からジョーカーまでを、0から始まる通し番号で管理する。 長さ53の配列に格納する。
[0] | [1] | [2] | ………… | [50] | [51] | [52] |
0 | 1 | 2 | ………… | 50 | 51 | 52 |
この図では添字と、格納されている通し番号が一致しているが シャッフルしたあとは通し番号のほうは順序がでたらめになる。
53個の配列を用意し、各要素に [スート, 数
]
を格納していく。
[0] | [1] | [2] | ………… | [51] | [52] |
["ハート", "A"] | ["ハート", "2"] | ["ハート", "3"] | ………… | ["クラブ", "K"] | ["その他", "JOKER"] |
これもシャッフルしたあとは、要素(下段)は並びが変わる。
1枚のカードをハッシュで管理する。"suit"というkeyのvalue としてそのカードのスートを、"n"というkeyのvalueとしてそのカー ドの数を代入したハッシュを53個作る。それを長さ53の配列に入れる。
0 | 1 |
…… |
51 | 52 |
||||||||||||||||
|
|
…… |
|
|
前回検討した3つのデータ格納形式のうち、使いやすいものを選んで実際にカー ドゲームを作ってみよう。カードの種類から持ち点を計算するときにもっとも簡 単なのはカードの数をそのまま足したものを持ち点とするゲームだろう。そのよ うな仲間のものとしてここではブラックジャックを取り上げよう。
公式ルールに則って人間同士が行なうブラックジャックには駆け引きの要素 を高めるルールがいくつかあるが、それらを忠実に再現するととても複雑なプログ ラムになってしまう。ここでは、単純に持ち点の大きさだけを比較して勝敗を決 める簡略化ルールを決めて、そのとおりに動くものを作ってみよう。
【簡略版ブラックジャック】
ジョーカーを除いた52枚のカードを利用する。基本的に各カードのスートは 関係なく、数だけを計算に利用する。カードの点数は以下のとおり。
- A・・・・・・・・1点、または11点
- 2-9・・・・・・・数と同じ点数(2〜9)
- 10, J, Q, K・・・・10点
プレイヤー(子)はコンピュータ(親)から2枚カードをもらう。コンピュータも 2枚カードを引くのだが、そのうち1枚は表向きになっている(プレイヤーが知る ことができる)。
点数の合計が21点に近い方が勝ちとなる。ただし、21点を超えると負けにな る。プレイヤーは、手持ちのカードを見て、もう一枚引くか、やめるかを選択で きる。コンピュータは、手持ちの合計が16以下ならばもう一枚引き、17以上なら引 かない。手持ちのカードに、Aがある場合は、1または11の都合のよい方で計算して よい。コンピュータとプレイヤーが同点だった場合はコンピュータの勝ちとなる。
実際には、同じ21点のときでも、2枚だけで21になったとき(Aと10点カード) は「ブラックジャック」といい、それ以外の21点より強くなったりするなどの例 外的ルールがいくつかあるが、ここでは単純に引き分けとして扱うことにしよう。
ゲームを開始すると、以下のような流れでゲームが進む。
プログラムを起動するとカードが配られる
「もう一枚引きますか」という問合せにNOを入力するまでくり返す
YESのときは、自分側にさらに一枚カードが配られ 2に戻る
コンピュータは最初の二枚の合計に応じて
コンピュータがもう引かなくなったところで両者の合計点を比較
実行画面をイメージすると以下のようになるだろう。
% ./blackjack.rb ゲーム開始 わたしの手: [ ??? ] ハートのK あなたの手: ダイヤの3 クラブのK もう一枚引きますか?(yかnで) y あなたの手: ダイヤの3 クラブのK ハートの7 もう一枚引きますか?(yかnで) n 勝負! わたしの手: ダイヤの8 ハートのK あなたの手: ダイヤの3 クラブのK ハートの7 わたし 18 : 20 あなた で、あなた の勝ちです!