今回は、トランプの定番中の定番である「七並べ」をなでしこで作ってみましょう。カードゲームを作るポイントは、カードをどのようなデータ形式で扱うかという点です。そのコツさえ掴んでしまえば、いろいろなトランプゲームを作れるようになります。七並べを例にして考察しましょう。
ゲーム開発はデータの表現方法で決まる
ゲームを作ろうと思った時、ゲームの画面やゲームの仕組みを考えるのは楽しいものです。そして、作りたいゲームが形になってきたら、どのようにゲーム内で扱うデータを表現したら良いかを考えると良いでしょう。データの表現方法が決まれば、一気にゲームが現実に動くようになります。
それでは、今回作るトランプの七並べはどうでしょうか。トランプをプログラミング言語で扱うとき、いくつかの表現方法が考えられます。
比較的実際のトランプに近い形式で扱うことを想定するなら、カードを辞書型データで次のように表現できるでしょうか。
カード一覧 = [
{"絵柄": "♣", "番号": "A"},
{"絵柄": "♣", "番号": "2"},
{"絵柄": "♣", "番号": "3"},
{"絵柄": "♣", "番号": "4"}
]
カード一覧[2]["番号"]を表示。
1枚のカードを {"絵柄": "♥", "番号": "A"}のように表現するのです。この方法のメリットは、データを表示してみると一目瞭然でそれが分かるという点にあります。
しかしデメリットもあります。トランプの絵柄と番号を文字列で表現している点です。七並べでは数字が隣り合っているかどうかを確認したいのですが、文字列のままでは、「A」の次が「2」だということが分かりづらくなります。そこで、A→1、J→11、Q→12、K→13と、普通の連番の数値である、1から13の数字で表すようにすると比較的分かりやすくなります。
カード一覧 = [
{"絵柄": "♣", "番号": 1},
{"絵柄": "♣", "番号": 2},
{"絵柄": "♣", "番号": 3},
{"絵柄": "♣", "番号": 4}
]
カード一覧[2]["番号"]を表示。
トランプのカードを通し番号で表現してみよう
さらに、この考え方を推し進めて、トランプのカード全てを番号で表現してしまうという方法が考えられます。
以下の図のように、0番を「♣A」、1番を「♣2」、2番を「♣3」...13番を「♠A」、14番を「♠2」...49番を「♦J」、50番を「♦Q」、51番を「♦K」と見なすようにするのです。
都合が良いことに、トランプでは絵柄ごとに13枚のカードがあるので、カード番号を13で割れば、絵柄と番号が求められるのです。例えば、Nをカード番号と見なした場合、次のような式で絵柄と番号を求めることが可能です。
N=33
絵柄=INT(N÷13)
番号=N % 13 + 1
「カード番号({N})=絵柄:{絵柄}/番号:{番号}」を表示。
上記のプログラムを実行すると「カード番号(33)=絵柄:2/番号:8」と表示されます。
また、以下のような変換配列を用意すると、より簡単に「カードの通し番号」からトランプの絵柄と番号に変換できることが分かるでしょう。
# 絵柄と番号を得る変換配列
カード絵柄=["♣","♠","♥","♦"]
カード番号=["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
# カード番号からカードに変換
N=33
絵柄=INT(N÷13)
番号=N % 13
「カード番号({N})={カード絵柄[絵柄]}{カード番号[番号]}」を表示。
上記プログラムを「なでしこ3簡易エディタ」で実行してみましょう。すると、次のように分かりやすくカード番号33が「♥8」に変換であることが分かります。
通し番号で表現できるメリットは他にもあります。全52枚のカードを作るのが簡単です。「繰り返す」文を使うとあっという間に52枚のトランプカードを作成できます。
以下のプログラムを実行すると、52枚のカードを作成し、シャッフルして、全部表示します。
# 絵柄と番号を得る変換配列
カード絵柄=["♣","♠","♥","♦"]
カード番号=["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
# 全52枚のカードを作成
カード一覧=[]
Nを0から51まで繰り返す
カード一覧[N] = N
ここまで。
# カードをシャッフル
カード一覧を配列シャッフル。
# カード全部を表示
カード一覧を反復
絵柄=INT(対象÷13)
番号=対象% 13
「{カード絵柄[絵柄]}{カード番号[番号]}」を表示。
ここまで。
実行してみましょう。プログラムを実行するたびに異なる順番でカードが表示されるのを確認できるでしょう。
ここまでの部分で、カードをシャッフルして表示しただけですが、それだけでもゲームが始まる予感がします。
なお、今回は処理を簡略化するためジョーカーのカードを考えないことにしています。ジョーカーを加える場合、上記0番から51番までの数字カードの後ろ、52番をジョーカーにすれば良いでしょう。
参加者4人にカードを配る処理
次に参加者4人に52枚のカードを配る処理を作ってみましょう。上記と同じ手順で52枚のカードを配列に入れたらシャッフルし、参加者4人に割り振っていきます。ここでは、参加者4人の手札を「参加者」という配列変数に入れることにしましょう。
# 絵柄と番号を得る変換配列
カード絵柄=["♣","♠","♥","♦"]
カード番号=["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
# 全52枚のカードを作ってシャッフル
カード一覧=[]
52回、カード一覧に(回数-1)を配列追加。
カード一覧を配列シャッフル。
# 参加者4人にカードを配る
参加者=[[], [], [], []] # 手札を空で初期化
Iを0から51まで繰り返す
参加者[I%4]にカード一覧[I]を配列追加。
ここまで。
# カード全部を表示
誰を0から3まで繰り返す
S=「」
参加者[誰]を反復
変数[絵柄,番号]=[INT(対象÷13),対象% 13]
S=S&「{カード絵柄[絵柄]}{カード番号[番号]},」
ここまで。
「参加者{誰}: {S}」を表示。
ここまで。
プログラムを実行すると、以下のようにカードを配ることができました。プログラムを実行するたびに配られるカードが変化します。
カードが隣り合っているか判定しよう
そして、七並べを作る時に大切となるのが、出したカードが隣り合っているかという点です。七並べでは机上に並べられたカードに対して、隣り合ったカードのみ参加者の手札から出すことができます。
ここでは、机上を表す変数「机」を用意し、そこに52枚のカードが出されたかどうかを判定できるように、要素番号0から51に-1を代入しておきます。つまり、変数「机[通し番号]」の値を確認して、-1であれば、そこは空であるとします。
そのため、例えばカード番号3(♣4)を出すことができるか確かめたいときは、その位置の左側、変数「机」の要素4(♣5)の位置を確認すれば良いことになります。また、カード番号が6以上であれば、右側のカードが空かを確かめます。判定プログラムは以下のようになります。
●(Nを)机配置可能とは
絵柄=INT(N/13)
番号=N%13
もし番号>6ならば
(机[絵柄][番号-1]≧0)で戻る。# 左側を確認
違えば
(机[絵柄][番号+1]≧0)で戻る。# 右側を確認
ここまで。
ここまで。
ゲームを完成させよう
以上、トランプゲームを作る仕組みを考えたところで、ゲームを完成させてみましょう。プログラムの全体は少し長くなってしまったので、なでしこ3貯蔵庫に配置しました。貯蔵庫にアクセスしたら、「実行」ボタンを押してみてください。以下のように七並べが始まります。
なお、今回、プログラムの動きが分かりやすくなるように、グラフィックなどは極力排除し、HTMLを動的に生成することでゲーム画面を構築しています。もし余力があれば、プログラムを改造して、カード画像が出るように改良してみると良いでしょう。
まとめ
以上、今回はトランプゲームの定番「七並べ」を作ってみました。今回、トランプのカードを通し番号で管理する方法を紹介しましたが、もちろん作るゲームの種類によっては、別の表現方法を使う方が適切な場合もあるでしょう。実際、どのようにデータを表現するのかは、試行錯誤してみて落ち着くという場合もあります。データをどのように表現するのか、工夫次第で、プログラムがより完結になったり、高速になったりします。試してみましょう。本稿がテーブルゲームやカードゲーム製作の参考になれば幸いです。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。