国士無双を狙う基準について

麻雀の話です。

国士無双とは、以下で与えられるような役満の役です。

初めの手牌で何枚以上揃っていれば狙うべきかについて考えます。

国士無双 (麻雀) - Wikipedia

 

 

プログラムが大変になりそうだったので、まずはとても強い仮定を起きます。

この下で、上がるまでに何巡かかったかについて計算しました。

 仮定:

  • 4人麻雀
  • 引く確率は独立で(1/34≒0.0294117)あると仮定する。つまり、捨て牌やドラ表示牌によるブレは無視します。

・8枚(対子なし)のとき、

 1 回目 8 枚対子なし
X
2 回目 8 枚対子なし
O
3 回目 9 枚対子なし
O
4 回目 9 枚対子
O
5 回目 10 枚対子
6 回目 10 枚対子
7 回目 10 枚対子
8 回目 10 枚対子
9 回目 10 枚対子
10 回目 10 枚対子
11 回目 10 枚対子
12 回目 10 枚対子
13 回目 10 枚対子
O
14 回目 11 枚対子
15 回目 11 枚対子
16 回目 11 枚対子
17 回目 11 枚対子
18 回目 11 枚対子
19 回目 11 枚対子
20 回目 11 枚対子
21 回目 11 枚対子
O
22 回目 12枚対子(聴牌)
X
X
O
X
上がり
回数: 22 

 手が進んだときに、Oと出力するようにしています。聴牌のときは相手の捨て牌で上がれるので1巡で4回チャンスが有ることになります。

 

1000回のシミュレーション結果:

f:id:ayamedaga:20161002221036p:plain

> summary(data)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
   9.00   35.00   48.00   51.74   64.00  172.00  

 

 

 

 

 

・10枚(対子あり)

f:id:ayamedaga:20161002221229p:plain

> summary(data)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
   4.00   21.00   32.00   36.91   48.00  174.00  

 

当然後者のほうが早い。対数正規分布っぽい?

続きます。

 

 

 

 

 

 

クソザコソースコード:

n=1000
data=numeric(n)
m=1


while(m<n+1){
cnt=0        #計数
finind=0    #終了
k=10        #手牌
i=1        #重複の有無

while(finind==0){    
    if(k==13&i==1){
        cat("上がり\n")
        finind=1
        }
    else{
        if(k==13&i==0){
            cat(cnt,"回目","13面待ち(聴牌)\n")
            for(j in 1:4){
                num=rgeom(1,13/34)+1
                cnt=cnt+(n-n%%4)/4
                }
            i=1
            }
        else{
            if(i==1){
                if(k<12){
                    cat(cnt+1,"回目",k,"枚対子\n")
                    l=13-k#引くべき数
                    if(rbinom(1,1,l/34)==1){
                        k=k+1
                        cat("O\n")
                        }
                }
                else{
                    cat(cnt+1,"回目","12枚対子(聴牌)\n")
                    for(j in 1:4){
                        if((rbinom(1,1,1/34)==1)&k==12){
                            k=k+1
                            cat("O\n")
                        }
                        else{
                            cat("X\n")
                        }
                    }
                }
            }
            else{                                                #対子なし
                cat(cnt+1,"回目",k,"枚対子なし\n")
                l=13-k#持ってない枚数
                rnd=runif(1)
                if(rnd<k/34){
                    i=1
                    cat("O\n")
                }
                if(k/34<rnd&rnd<13/34){
                    k=k+1
                    cat("O\n")
                }
                if(13/34<rnd){
                    cat("X\n")
                }
            }
        }
        cnt=cnt+1
    }
}

cat("回数:",cnt,"\n")
data[m]=cnt
m=m+1


}