學而時<span lang="ko">習</span>之 RSSフィード

學而時

20150208 ”ごいた”の駒を配った時点で勝敗が確定している確率を計算してみた

"ごいた"では、駒を配った時点で勝敗は決していることがあります。麻雀でいうところの天和あるいは人和、地和。わたしが知る限りのパターンについて、どれくらいの確率で発生するのか試してみました。


10,000,000回やってみたらこんなかんじになりました。

  • 必勝パターンと6しなどが同時発生した場合、6しなどとしてカウント。
  • 親でanyパターンが発生した場合、anyパターンの発生としてカウント。
  • 例えば「王王飛飛角角☗☗」のように「王王飛飛☗☗☗☗」と「王王角角☗☗☗☗」は同時に発生するが、このような場合は表の上位でカウント。このため「王王飛飛☗☗☗☗」の方が若干発生確率が高くなる。
手番 持ち駒 回数 確率
親のみ香香香香☗☗☗☗14,731回0.15%
親のみ王香香香し☗☗☗102,467回1.02%
親のみ王王飛飛☗☗☗☗11,635回0.12%
親のみ王王角角☗☗☗☗11,425回0.11%
親のみ王王金金金金☗☗239回0.00%
親のみ王王銀銀銀銀☗☗255回0.00%
親のみ王王馬馬馬馬☗☗258回0.00%
親のみ王王金金金香し☗2713回0.03%
親のみ王王銀銀銀香し☗2543回0.03%
親のみ王王馬馬馬香し☗2629回0.03%
any王香香香香し☗☗15676回0.16%
any王王飛飛香し☗☗28854回0.29%
any王王角角香し☗☗28614回0.29%
any王王香香香しし☗12631回0.13%
any王王金金金金香し151回0.00%
any王王銀銀銀銀香し159回0.00%
any王王馬馬馬馬香し168回0.00%
anyしししししししし174回0.00%
anyししししししし☗10,034回0.10%
anyしししししし☗☗185,009回1.85%
anyししししし☗☗☗ ししししし☗☗☗970回0.01%
合計 431,345回4.31%

およそ4%の確率で、最初っから勝敗が決まってるみたいです。ただし、自分の駒がそうなるのはその4分の1の確率なので、約1%です。ちなみに天和の確率は33万分の1だそうですので、それに比べればずいぶん発生しやすい。

「王王飛飛香し☗☗」もしくは「王王角角香し☗☗」は合計で0.6%程度の確率で発生します。コレが出たら、誰かが残り2枚になるまでは"なし"でOK!

過去の記事で書いているように、ひとりのプレイヤーに配られる駒のパターンは3,699ありますが、親であればうち619通りが、子であれば113通りが上の表に合致しますので、仮に全探索系の対戦プログラムを書くのであれば、この制約を利用することで計算量を減らすことができると考えます。とはいえ発生確率は高々4%ですが。


総当りプログラムはこんなかんじ

DAMA = 1
HISHA = 2
KAKU = 3
KIN = 4
GIN = 5
BAKKO = 6
GON = 7
SHI = 8
KOMA = [ [DAMA]*2, [HISHA]*2, [KAKU]*2, [KIN]*4, [GIN]*4, [BAKKO]*4, [GON]*4, [SHI]*10 ].flatten

n = 0
count = Array.new(21, 0)

while true
  k = KOMA.sample(KOMA.length)
  koma = [k[0..7].sort, k[8..15].sort, k[16..23].sort, k[24..31].sort]
  f = -1
  
  if koma[0].count(GON) == 4
    f = 0 # 香香香香
  elsif koma[0].count(DAMA) >= 1 and koma[0].count(GON) >= 3 and koma[0].count(SHI) >= 1
    f = 9 # 王香香香し    
  elsif koma[0].count(DAMA) == 2
    if koma[0].count(HISHA) == 2
      f = 1 # 王王飛飛
    elsif koma[0].count(KAKU) == 2
      f = 2 # 王王角角
    elsif koma[0].count(KIN) == 4
      f = 3 # 王王金金金金
    elsif koma[0].count(GIN) == 4
      f = 4 # 王王銀銀銀銀
    elsif koma[0].count(BAKKO) == 4
      f = 5 # 王王馬馬馬馬
    elsif koma[0].count(KIN) == 3 and koma[0].count(GON) >= 1 and koma[0].count(SHI) >= 1
      f = 6 # 王王金金金香し
    elsif koma[0].count(GIN) == 3 and koma[0].count(GON) >= 1 and koma[0].count(SHI) >= 1
      f = 7 # 王王銀銀銀香し
    elsif koma[0].count(BAKKO) == 3 and koma[0].count(GON) >= 1 and koma[0].count(SHI) >= 1
      f = 8 # 王王馬馬馬香し
    end
  end
  
  (0..3).each do |i|
    if koma[i].count(DAMA) >= 1 and koma[i].count(GON) == 4 and koma[i].count(SHI) >= 1
      f = 10; break # 王香香香香し
    elsif koma[i].count(DAMA) == 2 and koma[i].count(GON) >= 1 and koma[i].count(SHI) >= 1
      if koma[i].count(HISHA) == 2
        f = 11; break # 王王飛飛香し
      elsif koma[i].count(KAKU) == 2
        f = 12; break # 王王角角香し
      elsif koma[i].count(GON) >= 3 and koma[i].count(SHI) >= 2
        f = 13; break # 王王香香香しし
      elsif koma[i].count(KIN) == 4
        f = 14; break # 王王金金金金香し
      elsif koma[i].count(GIN) == 4
        f = 15; break # 王王銀銀銀銀香し
      elsif koma[i].count(BAKKO) == 4
        f = 16; break # 王王馬馬馬馬香し
      end
    end
  end
  
  (0..3).each do |i|
    shi = koma[i].count(SHI)
    if shi == 8
      f = 17; break # 8し
    elsif shi == 7
      f = 18; break # 7し
    elsif shi == 6
      f = 19; break # 6し
    elsif shi == 5 and koma[(i+2)%4].count(SHI) == 5
      f = 20; break # 5しダブル
    end
  end
  
  count[f] += 1 if f >= 0
  n += 1
  if n%100000 == 0
    p count
    p n
    p count.inject(:+)
    printf("%.5f%%\n\n", count.inject(:+)*100.0/n)
  end
end

自力勝利不能な持ち駒

必勝パターンがあればその反対もある。対面の相方が勝ってくれない限り勝つことができないそんな持ち駒のパターンも計算してみます。

手番 持ち駒 回数 確率
any飛飛角角金金金金7回0.00007%
any飛飛角角銀銀銀銀5回0.00005%
any飛飛角角馬馬馬馬3回0.00003%
any金金金金銀銀銀銀4回0.00004%
any金金金金馬馬馬馬3回0.00003%
any銀銀銀銀馬馬馬馬2回0.00002%
子のみ飛飛角角香香香香4回0.00004%
子のみ金金金金香香香香1回0.00001%
子のみ銀銀銀銀香香香香2回0.00002%
子のみ馬馬馬馬香香香香2回0.00002%
合計 33回0.00033%

必勝っぽくてもそうではない

手番 持ち駒 回数 確率
親のみ王飛飛角角香し☗1,269回0.01%
親のみ王金金金金香し☗1,270回0.01%
親のみ王銀銀銀銀香し☗1,367回0.01%
親のみ王馬馬馬馬香し☗1,335回0.01%

更新履歴

  • 2015/2/8 初出
  • 2015/2/21 自力勝利不能な持ち駒を追記
  • 2015/2/25 必勝のパターンを追加(3%→4.26%)