めくり合いをした時の和了率や放銃率を計算する(三麻)
※2021 7/14 追記 コードが間違っていたので訂正しています。すみませんでした。
三人麻雀です。自分は安牌を切って追いかけるという条件です。残りの1家は放銃も和了もしません。他にもあまり影響ない程度の単純化をしています。細かい条件は下に載せます。おそらく計算方法はあっていると思うのですが間違っていたらご指摘くださると幸いです。
下のグラフは、5巡目追っかけリーチした時の和了率や放銃率です。こちらの待ち枚数4枚、相手の待ち枚数は横軸で1~12枚までを示しています。
5巡目、自分の待ち枚数4枚
待ち枚数が4:1ならだいたい勝てるようです。逆に4:8だと和了率が33%にまで落ちてます。気になるのは放銃率と被ツモ率が結構違うこと。12枚待ちがあると被ツモ率が42%なのに放銃率は33%です。待ち被りは0枚と計算しているのでそんな違わないとは思うのですが、おそらく相手のほうがツモ巡が先なので12枚待ちでの影響が大きいのだと思います。
次のグラフです
14巡目、自分の待ち枚数3枚、その3枚は相手と待ちが被っている時です。
3:3では互角、3:6では19%:13%放銃+34%被ツモです。終盤で相手の危険牌で単騎テンパイ入れることを想像して設定しました。
次のグラフです
5巡目、自分の待ち3枚、相手7枚、そのうち待ちが被っている枚数が横軸で0~3枚まで示しています
待ちが被ると和了率、放銃率共に下がることがわかります。3枚全部被ってしまうと被ツモがかなりを締めます。まだまだパラメーターをいじれば面白い発見がありそうです。
条件
1家とめくり合いしたときの和了率、被ツモ率、放銃率、流局率を求める
ただし、以下の条件とする
三麻王牌14枚
北抜き、カン、風露入っていない
自分は東家親番、相手は南家
残り山枚数がyama枚で安牌きってテンパイするものとする。既に相手はテンパイしていて和了牌以外ツモ切る(54≧yama>0)
もう1家はベタオリするものとし、放銃はしない。
こちらの待ち枚数はjibun枚(12≧jibun>0)
相手の待ち枚数はaite枚(12≧aite>0)
待ちかぶり枚数はkaburi枚(4≧kaburi>0, jibun≧kaburi, aite≧kaburi)
計算方法
1巡ごとツモる牌から数パターンの確率を求め加算していく
・自分の和了牌を掴めば和了率に加算
・相手の和了牌を掴めば放銃率に加算
・両者の和了牌を掴めば和了率に加算
・安牌を掴んだときは、安牌を掴む確率をもとに次巡を計算する
ソースコード
Pythonで書いてあります
def get_odds(yama,jibun,aite,kaburi,):
"""
和了率とか放銃率とか取得する関数
Parameters
----------
yama : int
この残り山枚数でテンパイするとき。
jibun : int
自分の待ち枚数。
aite : int
相手の待ち枚数。
kaburi : int
待ち被り枚数。
"""
tumo = 0
ron = 0
hitumo = 0
houju = 0
ryukyoku = 0
#テンパイ入ってからの河に見えたリーチ者二人分の牌の数
c=0
#上がらなかった時の割合
scale=1
#現在の残り山枚数
n=yama
#相手の順番から確率を計算していくため残り山を-1、リーチ者二人分の河に見えた牌の数を+1
n -= 1
c += 1
while True:
#相手のツモった牌でのロン和了率と被ツモ率を計算しそれぞれ加算する
#それぞれの確率は、見た目枚数÷見えてない牌の枚数 で求まる
#見えていない牌の枚数=全部の牌108枚ー自分の手牌14枚ードラ表示牌1枚ーリーチ前に河に見えた牌(54ーN)ーリーチ後に河に見えた2件分の牌c
#リーチ前に見えていない牌の枚数
beforeRiichiTiles = 108 - 1 - (54 - yama) - 14
hitumo += scale*(aite/(beforeRiichiTiles-c))
ron += scale*((jibun-kaburi)/(beforeRiichiTiles-c))
#安牌掴んだときは、入れ子状に枠を狭めていく。前巡に安牌掴んだときの枠でさらに安牌つかむときの枠を求めるという感じ。
scale *= 1 - (jibun+aite-kaburi)/(beforeRiichiTiles-c)
#相手が下家なので2枚山から牌を減らす
n -= 2
#河に出た2人分の牌の数が1増える
c += 1
#山が無くなったら流局率の計算をしてループを抜ける
if n < 0:
ryukyoku = scale
break
#次は自分のツモ番。同じように計算する。
tumo += scale*(jibun/(beforeRiichiTiles-c))
houju += scale*((aite-kaburi)/(beforeRiichiTiles-c))
scale *= 1 - (jibun+aite-kaburi)/(beforeRiichiTiles-c)
#次は下家の番なので2枚ではなく1枚のみ減らす
n -= 1
c += 1
if n < 0:
ryukyoku = scale
break
return tumo, ron, houju, hitumo, ryukyoku