###前提・実現したいこと
【背景】Python2.7で、サイコロを使ったボードゲームの勝率を計算しようとしています。
【前提】ゲームは、プレイヤー同士が、指定された数のサイコロ(1~4個)を振り、
その最大値を比較して、相手より大きければ勝ち、同値なら相打ち、小さければ負けとなります。
サイコロの出目を操作したり、振り直しをする効果が有るため、
効果による勝率の変化を算出する場合、出目を保持ことが必要です。
ゲーム進め方の例:
- Player 1(P1): ダイス4個、相手のダイスを選んで1つ振り直すことが出来る。
- Player 2(P2):ダイス2個、自分のダイスを選んで目を5に変えることが出来る。
- ダイス比較
サイコロ(P1): 4, 5, 2, 1、最大値5
サイコロ(P2): 6, 2、最大値6
このままだとplayer 2の勝ち。
- Player 1がPlayer 2 の6の目の振り直しを要求
振り直した結果、6の目が3になる。
サイコロ(P1): 4, 5, 2, 1、最大値5
サイコロ(P2): 3, 2、最大値3
このままだと、Player 1の勝ち
- Player 2が2の目を5に変える。
サイコロ(P1): 4, 5, 2, 1、最大値5
サイコロ(P2): 3, 5、最大値5
結果、相打ち
###発生している問題
【問題】numpyのitertools.productを使って、プレイヤー同士が振るサイコロの出目の
一覧を作り、勝利確率を計算しました。ただこれだとサイコロ数が多くなったり、
振り直しが必要な場合は、計算時間が膨大になります。
【どうしたいか】効率化したいです。
【現状】サイコロは区別しないので、組み合わせと、その確率が得られれば
効率化できそう。だが、関数や良い方法が思い浮かんでいません(見つけられていない)。
###該当のソースコード
サイコロ4つ振りと、サイコロ1つ振りのデカルト積を得て、
出目の最大値を比較しています。
Python
1import numpy as np 2import itertools 3 4sai=(1,2,3,4,5,6) 5sai5=np.array(list(itertools.product(sai,repeat=5))) 6 7sai5_4=sai5[:,:4].max(axis=1) 8sai5_1=sai5[:,4:].max(axis=1) 9 10win_4 = list(sai5_4>sai5_1).count(True) 11even = list(sai5_4==sai5_1).count(True) 12all = len(sai5) 13 14print win_4*100.0/all 15print even*100.0/all
結果はただしそう。
70.7433127572 16.6666666667
###試したこと
numpyのintertoolsの使い方は一通り読んだ。
順列、組み合わせの数を出す関数は見当たらない。
###補足情報(言語/FW/ツール等のバージョンなど)
上記の環境
- Python 2.7.13 |Anaconda 4.3.1 (64-bit)| (default, Dec 20 2016, 23:09:15)
- IPython 5.1.0 -- An enhanced Interactive Python.
回答3件
あなたの回答
tips
プレビュー