paiza開発日誌

IT/Webエンジニア向け総合求人・学習サービス「paiza」(https://paiza.jp ギノ株式会社)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

Pythonを使って、ボードゲームで勝つための確率計算をしてみた

f:id:paiza:20171031170746j:plain
秋山です。

最近、社内でボードゲームが流行っていて、お昼休みにみんなで集まって遊んだりしています。

大体どんなゲームをやっていても、みんな途中から「誰が何手前でこうしていればああなっていた」とか「あのときこうしていたらこうなっていた確率はどれぐらい」とか、そんな話で盛り上がってしまって全然終わらなくなってしまいます。エンジニアが多いからなのか…。

そこで今回はPythonを使って、「カタン」というボードゲームで勝つためのヒントが何か得られないか、いろいろ計算して遊んでみようと思います。

カタン スタンダード版

カタン スタンダード版

Pythonを使ってカタンで勝てるヒントを探してみた

カタンのルールは、こんな感じです。

最初に六角形のタイルを並べて作るカタン島が舞台となる。各タイル(土地)には2〜12(7を除く)の数字が割り振られる。プレイヤーが手番で振るサイコロ2つの合計と同じ数字の土地から、土地に対応した資源(木材、粘土、麦、鉄、羊毛)が産出する。各プレイヤーは産出した資源を使い、道(道路)、家(開拓地)、街(都市)を建設していく(それぞれの建造物は版によって呼称は異なるが機能は同じ)。開拓の度合いが点数化され、自分の手番時に最初に10点に到達した人が勝利となる……(カタンの開拓者たち - Wikipedia

手番のプレイヤーがサイコロを2つ振り、出目の合計に対応したカタン島の土地と、隣接する点に開拓地や都市を置いていたプレイヤーは、その資源を得られます。

今回は、この「土地と資源獲得の期待値を上げること」を中心に考えていきたいと思います。(カタンに詳しい人は、「交渉とか港とか銀行とかについてはどうすんだ」とか思われるかもしれませんが…)

カタンは、毎回盤面の構成がランダムで変わるので、プレイする度に違った展開が楽しめます。

一般的なカタンのルールでは、6種類の六角形な土地カード19枚(森林4個、畑4個、牧草地4個、丘陵3個、山脈3個、砂漠1個)をシャッフルして並べ、砂漠を除く各土地に対して数字を割り当てていきます。

数字の割り当ては、AからRのアルファベットがついた17種類のコインがあり、六角形の上から反時計回りに内側へ渦巻状に配置していきます。このとき砂漠の土地だけはコインを置かずに飛ばします。

A~Rのコインには、以下のように対応する数字が裏面に記載されています。

ABCDEFGHIjKLMNOPQR
52638109121148109456311

各土地には、この順にぐるっと数字が配置されます。間に砂漠が入るパターンが全部で19パターンになります。

例えば、以下は中央に砂漠が来たパターンの図です。ちなみに、赤くなっているのは出現率が高い数値のマスです。
f:id:paiza:20171031162143j:plain

砂漠が左上に来た場合は、以下のような配置になります。上と比べると、6を置いていた場所が砂漠なので飛ばして、その下からまた数字が順番に続いています。
f:id:paiza:20171031162245j:plain

プレイヤーはこのマップに対して、開拓地を配置します。配置するのは、各六角形の土地の頂点に当たる場所です。

ゲームが始まると、手番のプレイヤーがサイコロを2個振って、出目の合計数が割り振られた六角形と、自分の開拓地が接している人は、その土地の資源を得ることができます。(7の場合は盗賊のコマを動かすという特殊な行為になります…)

例えば以下のマップでプレイしていたとして、赤丸の場所に自分の開拓地を置いていたなら、サイコロの合計値で5・8・10が出れば、該当する資源を得られます。
f:id:paiza:20171031164922j:plain

◆サイコロの確率を考える

サイコロの目の合計値が出る確率をまとめると以下になります。
f:id:paiza:20171101154237j:plain

この表を見ると、強い土地は当然6か8ですね。(7は先に書いたとおり盗賊のコマを動かす行動で、ちょっとややこしくなるので一旦置いて考えます…)

隣接する数も7に近ければ近いほど出やすい数となるので、先のマップ図だと5・8・10に接している頂点などは、4/36 + 5/36 + 3/36 = 12/36 で、概ねサイコロが3回振られれば、1回は資源が手に入るぐらいの確率です。結構強いですね。


では、この資源が得られる確率を頂点ごとに求めて、マップのパターンによって開拓地をどこに置けば勝率が上がりそうか考えてみましょう。

前述しましたが、マップのバリエーションは、砂漠が19か所のどの位置になるかによって決まるため、19種類となります。

砂漠が中心にあるマップの場合、頂点の数は
1つの土地と頂点が接している(=自分自身の頂点のみ) 外周の 18箇所
2つの土地と頂点が接している 外周の 12箇所
3つの土地と頂点が接している 24箇所
の合計54箇所となります。

54の頂点と19種類のマップの組み合わせを掛け合わせて求めるのは、手動だと気が遠くなりそうなので、Pythonでざっくり数値だけ取ってみることにしました。

以下のコードでは、tmp変数で各サイコロの出目の情報が作られます。マップでは上から反時計回りに、正午の位置から0〜18の数値が割り当てられています。

出力は

[5, 2, 6, 3, 8, 10, 9, 12, 11, 4, 8, 10, 9, 4, 5, 6, 3, 11, 7]

がマップの情報で、7が砂漠、それ以外は正午の位置から反時計回りに設置されている数値となります。

↓例えば、この33.33は、サイコロの目の総出現確率です。後ろの [10, 5, 6] は、頂点の接している土地の数値となっています。

(33.33, [10, 5, 6]) 


では次に、4回に1回以上の確率で出現する数値と確率をピックアップしてみていきます。

中心に砂漠があるマップでは、33.33%の最も高確率で資源を得られるのは 10,5,6 と 10,9,6 と 8,10,5 の3つの頂点です。
f:id:paiza:20171101142838j:plain

(33.33, [10, 5, 6])
(33.33, [10, 9, 6])
(33.33, [8, 10, 5])
(30.56, [3, 8, 5])
(30.56, [5, 10, 9])
(27.78, [8, 10, 11])
(27.78, [4, 8, 11])
(27.78, [9, 12, 6])
(27.78, [6, 3, 4])
(25.0, [5, 6, 7])
(25.0, [10, 9, 11])
(25.0, [3, 4, 5])
(25.0, [2, 6, 4])

ルール上、既に誰かが開拓地を置いている頂点と隣接した頂点には、他のプレイヤーは開拓地を置けないので、あえて他の人を邪魔することも考えると、10, 5, 6に置くと自分の期待値もよく他人の期待値も奪えてよいかもしれません。あと、5, 10, 9あたりは一見弱そうですが確率的にはよい場所ですね。


これが砂漠が中心から1つ外側にズレたマップの場合、一見同じように見えますが、30.56%の頂点が3つ増えて、27.78%の頂点が 2つに減っています。
f:id:paiza:20171101143415j:plain

[5, 2, 6, 3, 8, 10, 9, 12, 11, 4, 8, 10, 9, 4, 5, 6, 3, 7, 11]
(33.33, [10, 5, 6])
(33.33, [10, 9, 6])
(33.33, [8, 10, 5])
(30.56, [5, 6, 11])
(30.56, [3, 8, 5])
(30.56, [5, 10, 9])
(27.78, [9, 12, 6])
(27.78, [6, 3, 4])
(25.0, [6, 3, 11])
(25.0, [4, 5, 11])
(25.0, [9, 4, 11])
(25.0, [3, 4, 5])
(25.0, [2, 6, 4])

5, 6, 10は同じように強いままですが、右上付近が弱くなり、代わりに左上の4の周りが強くなっています。


上記のように、1つズレていたぐらいなら誤差レベルですが、この砂漠が中心から4つズレて、中心の真下の位置にきた場合は、確率が少し特殊になります。
f:id:paiza:20171101143720j:plain

[5, 2, 6, 3, 8, 10, 9, 12, 11, 4, 8, 10, 9, 4, 5, 7, 6, 3, 11]
(33.33, [8, 10, 5])
(30.56, [3, 8, 5])
(30.56, [5, 10, 9])
(27.78, [8, 10, 3])
(27.78, [4, 6, 3])
(27.78, [4, 8, 3])
(27.78, [11, 4, 6])
(27.78, [6, 3, 4])
(25.0, [6, 3, 11])
(25.0, [4, 5, 11])
(25.0, [9, 4, 11])
(25.0, [10, 9, 3])
(25.0, [3, 4, 5])
(25.0, [2, 6, 4])

8,10,5 の 33.33%で資源を得られる頂点が1つありますが、それ以下は30.56%以下の確率になるため、8,10,5が単独1位で期待値が高くなりますね。最も強い頂点をとると、次に強い頂点は5, 9, 10となります。手番が4番目の人は、結構不利になってしまいますね。


上のパターンからさらに砂漠が2つズレて中心の左上に来た場合は、27.78%の数が7か所となります。しかも上位4箇所は30.56%で同率です。プレイヤー4人全員が順にそこを選んでしまえば、その後は27.78%のどこを選ぼうか…と考えていく形になります。
f:id:paiza:20171101144128j:plain

[5, 2, 6, 3, 8, 10, 9, 12, 11, 4, 8, 10, 9, 7, 4, 5, 6, 3, 11]
(30.56, [5, 6, 11])
(30.56, [10, 9, 5])
(30.56, [8, 10, 4])
(30.56, [5, 10, 9])
(27.78, [8, 10, 3])
(27.78, [4, 6, 3])
(27.78, [4, 8, 3])
(27.78, [11, 4, 6])
(27.78, [12, 5, 6])
(27.78, [10, 4, 5])
(27.78, [3, 8, 4])
(25.0, [6, 3, 11])
(25.0, [4, 5, 11])
(25.0, [10, 9, 3])
(25.0, [9, 12, 5])

もうこうなってくると、資源獲得率よりも「道を繋げやすそう」とか、他の要素を考えながら場所を置いていくことでしか差が出ないかと思います…。


マップのパターンとして、遭遇したら確実におさえておきたいのは以下ですね。実は、全パターンの中で最も出現率が高い36.11%が現れるパターンです。この36.11%は、9,5,6に隣接する頂点として1つだけ現れます。
f:id:paiza:20171101144436j:plain

[5, 2, 6, 3, 8, 10, 7, 9, 12, 11, 4, 8, 10, 9, 4, 5, 6, 3, 11]
(36.11, [9, 5, 6])
(33.33, [5, 8, 10])
(30.56, [5, 6, 11])
(30.56, [8, 10, 4])
(30.56, [6, 3, 9])
(27.78, [8, 10, 3])
(27.78, [4, 8, 3])
(27.78, [9, 12, 6])
(27.78, [10, 4, 5])
(27.78, [3, 8, 4])
(27.78, [2, 6, 9])
(25.0, [8, 5])
(25.0, [6, 3, 11])
(25.0, [4, 5, 11])
(25.0, [9, 4, 11])
(25.0, [10, 9, 11])
(25.0, [11, 6, 3])
(25.0, [3, 9, 4])

マップの一番上の5から反時計回りに、半回転の外周のいずれかに砂漠が置かれた場合に出現するので覚えておきたいところです。1番目に開拓地を置けるときや、先の手番の人が見逃していたら絶対に押さえたい…。

■まとめ

特徴的なマップは上記みたいな感じかなと思います。前述もしましたが、カタンはサイコロの目以外の要素も大きくゲームの形勢に影響してくるので、確率が高い場所が確実にベスト!というわけではないですが……あくまで目安として、マップによってはお得な頂点…を覚えておくとちょっとだけ勝利に近づける?かもしれません。

……とPythonを使ってまで初期配置の勝てそうなパターンをいろいろと分析してきましたが、この確率を考えた後にみんなで1プレイして私はボロ負けしました。

やっぱりカタンは他の要素の影響も大きいゲームですね……時間があればAIを組んで対戦させるとかもやってみたいです……。


今回はPythonを使って分析してみましたが、「プログラミング自体が初心者なので、Pythonを基礎から学びたい!」という方は、プログラミングが動画で学べる「paizaラーニングPython入門編から始めてみると、無理なく基礎を習得できると思います。

途中でブログパーツとして使ったオンライン実行環境サービス「paiza.IO (パイザ・アイオー)」はこちら




paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。

自分のスキルを磨いていきたいという方におすすめなのが「paizaラーニング」。オンラインでプログラミングしながらスキルアップできる入門学習コンテンツです。初心者でも楽しくプログラミングの基本を学ぶことができます。

詳しくはこちら

そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。

詳しくはこちら

スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza