*All archives* |  *Admin*

<<09  2016/10  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  11>>
一人麻雀計算機その5・聴牌かつ手替わりなしの計算
前回までで、有効牌の計算と和了時の得点計算という基礎的なところまでは終わったので、
いよいよ本題の一人麻雀の計算に入ります。

まずは一番簡単な聴牌かつ手替わりなしの場合。
上がり牌を引いたら和了して得点を計算、
上がり牌を引けなかったら次順に移る、
東家南家の18巡目と西家北家17巡目なら流局として得点を計算(今のところ他家聴牌者は一人と固定して計算する)、
という単純なプログラム、
…と言いたいところですが、かなり作るのに苦労しました。

「次順に移る」というところが曲者です。
例えば16巡目の期待値は
(17巡目に上がり牌を引く確率)*(上がった時の得点)+(17巡目に上がり牌を引けない確率)*(17巡目の期待値)

このままでは(17巡目の期待値)が分からないので、続いて
(17巡目の期待値)=(18巡目に上がり牌を引く確率)*(上がった時の得点)+(18巡目に上がり牌を引けない確率)*(18巡目の期待値)
(18巡目の期待値)=(流局時収入)

といった具合に再帰的に関数を呼び出す必要があります。
(実際は1mを引く確率、1m引いたときの期待値、みたいに毎順37個の足し算をします。)

もしくはいつもの局収支シミュレータみたいに、乱数を与えて最後の局結果を見る、という作業をn回繰り返して平均値を取る、モンテカルロシミュレーションにするかのどちらかです。

どちらにしても(上がり牌を引く確率)が必要になるので、前に取ったこちらのデータをパラメータとして採用します。
見えてる枚数別手持ち枚数別ツモ率
今は他家の挙動がないので、前半の手持ち枚数別ツモ率の数値です。
ドラ表示牌については自分の手にあるものと同等としてパラメータを参照します。(例えば、ドラ表示牌1mで自分1m対子持ちなら「3枚持ち」の数値を参照する。)
ただし、これをそのまま適用すると手牌にある牌次第ですべての牌のツモ率の合計がちょうど1にならないという問題が出てくるので、合計が1になるような調整(すべての牌のツモ率について、合計ツモ率で割る)を行います。

最初はモンテカルロシミュレーションで作ってみたのですが、毎順処理時間がかかるシャンテンチェックの関数を呼び出すためか
、1000局やるのに40秒という時間ばかりかかる残念なプログラムになってしまいました。
これだと10万局なら4000秒≒1時間もかかってしまいます。たった1局面を判別するだけでこれです。
とてもじゃないけどこのままではやってられないです。
できればモンテカルロ方式にして、4人麻雀への応用がしたかったけど、手替わりなし・聴牌でこの状態なのでしょうがないですね。

というわけで、再帰的に関数を呼び出す、従来の計算方式で作り直してみました。

手探りでいじっていったらやはりというかバグが出まくってものすごく苦労しました。

まず最初に作ってみたのがこちら。
161030-01.png
18巡目は流局時収入1500点そのままです。

17巡目は関数を再帰的に呼び出した回数が35回。
上がり牌以外の35種類の牌を引いたときに、18巡目の期待値を求めるために同じ関数を呼び出すので35回です。

16巡目は関数を再帰的に呼び出した回数が1260回。
17巡目に上がり牌を引けなかった35種類に対して、また17巡目の期待値を求めるために35回関数を呼び出すので1260回。
…なんか嫌な予感がしてきました。

15巡目。44135回。

14巡目。1544760回。
ここでギブアップ。14巡目を求めるのに3~4分も時間がかかったのでもう無理です。

今のままだと残り順目が多いと指数関数的に計算時間が増えてしまうようです。
これではモンテカルロ式以上に無理です。


というわけで、ない知恵絞って工夫してみました。

デバッグで中身の変数の推移を眺めていると、大半が同じような計算をやってることに気付きました。
同じ巡目、同じ手牌なら(乱数を使わない計算なので)同一の結果を返すので、
一度計算した巡目と手牌を記憶しておいて、同じ局面が再び現れた場合はそのとき計算済みの期待値を返す、
というような仕組みに変えました。
これなら関数を再帰的に呼び出す回数は少なくなりそうです。

これで作り直してみたところこんな感じになりました。
161030-02.png

今回は手替わりなしなので、記憶する情報のうち変わるのは現在巡目と(立直時)一発フラグだけです。
一番下の再帰回数を見ると差は歴然です。
6巡目でも385回です。1回計算したものは記憶しておけるので、ほぼ35×(18-6)回の呼び出し回数で済んでいます。

とはいえ、いいことばかりではありません。弊害もあります。
今のところ出ている問題は、
・自分がこの後捨てる牌については記憶することができない。
ということです。
記憶情報に捨て牌まで含んでしまうと、同一局面がこの先現れることはまずないため、処理時間の圧縮効果がなくなってしまうからです。
なので、一度捨てた牌の枚数が減ってツモ率が下がる(それにより他の牌のツモ率が上がる)効果が出なくなってしまいます。
極端なケースだと同じ牌を何回でもツモれる可能性があるので4枚目を引いた後、5枚目6枚目を引いてくる可能性もわずかにあるということです。

このへん、他の方はどうされてるんだろうか?

今後4人麻雀に拡張する場合でも、現在の順目以降の他家の挙動(捨て牌など)を記憶できないということが問題として出てきそうです。他家の挙動お構いなしに全ツッパする分にはそこまで影響は出なさそうですが、繊細な挙動をするAI作りとかの段階になったらかなり響いてきそうな気がします。


とはいえ、処理速度の軽減は重要なのでこの要素を取り下げることはできません。またなんかいいアイデアが浮かんだらいいですが。


こうして毎日ブログを更新しているのを見ると一人麻雀計算機なんか簡単に作れるんじゃないの?と誤解されるかもしれませんが、はっきり言っておきます。

作るの、超難しいです。

思いつきでいろいろいじってるのでバグが次から次に出ててんやわんやしてます。
やたらと時間かかるプログラムができるのも、知識・経験不足なんだろうなぁと思いつつ、ちょっとがっかり。
スポンサーサイト
一人麻雀計算機制作計画その4・一般手役判定と得点計算とその他
今日は一人麻雀計算機の続き。
一般手役の判定です。

ほぼ全部の役について判定できています。
判定していない役は海底ツモ、河底ロン、嶺上開花、槍槓、裏ドラです。

↓テストの軌跡。
161029-01.png
全部の役を一通り調べて回ったので大変だったけど、とりあえずうまくいってくれてそうでよかったよかった。


あとは点数計算とか例外処理とか細々としたことをやって対外的に体裁を整えたので、
途中経過としてソフトをUPしておきます。

https://www.axfc.net/u/3735848

161029-02.png

和了形についてはメンツの切り分けと役判定と点数計算を、
非和了形についてはシャンテン数と有効牌をそれぞれ計算します。

現状では天鳳の牌理ツールに和了の役判定と点数計算機能を付け加えたようなソフトです。

テキストへの書き込み機能付き。

詳しくは同梱の操作説明をご覧ください。


これでルールとかの基本的なところはOK。
次からは一人麻雀計算の核心的なところに入っていきます。
まずは簡単なところから。手替わりなしの聴牌の期待値からですね。
一人麻雀計算機制作計画その3・メンツの切り分けと役満手役判定
一人麻雀計算機制作の続き。
前回まででシャンテンチェックと有効牌の計算までできたので、今日は和了時のメンツの切り分けと符計算をやります。

14枚で上がってる手牌について、チートイと国士以外について4メンツ1雀頭の組み合わせとしてあり得るものをすべて列挙していきます。
この作業をすることにより、
・符計算が簡単にできる。
・メンツ構成にかかわる役の判定が簡単にできる。
・高点法を取るのがやりやすくなる。
といったような効果があります。

各パーツの分け方は
・「AGARIGUKEITAATU」…「上がり愚形塔子」。上がり牌を含んだシュンツのうちペンチャンとカンチャンのもの。2符加算。
・「AGARIKOTU」…「上がり刻子」。シャボで上がった場合の刻子。ツモなら4符or8符、ロンなら2符or4符加算。
・「AGARIRYANMEN」…「上がり両面」。上がり牌を含んだシュンツのうち両面のもの。符加算なし。
・「AGARITOITU」…「上がり対子」。単騎待ちの上がり牌。単騎待ちの2符加算と役牌雀頭の2符or4符加算。
・「ANKAN」…「暗槓」。16符or32符加算。
・「ANKO」…「暗刻」。上がり牌でできた暗刻を除いたもの。4符or8符加算。
・「CHII」…「チー」。鳴いたシュンツ。0符加算。
・「MINKAN」…「明槓」。大明槓or加カン。8符or16符加算。
・「PON」…「ポン」。鳴いた刻子。2符or4符加算。
・「SYUNTU」…「シュンツ」。鳴いていないand上がり牌を含まない出来シュンツ。0符加算。
・「TOITU」…「対子」。単騎待ちでない雀頭。役牌雀頭の2符or4符加算。

このパーツ区分分けと、各パーツの中で牌番号(1~37番)が一番小さいもの(赤は考慮しない)をセットにして扱います。
234pのチーなら12番、南の明槓なら32番です。

追加で必要になる情報は、「上がり牌」「ツモorロン」「自風」「場風」なので、それを入力できるスペースを設けて、
メンツの切り分けand符計算のコードを書いていきます。

符計算のためには平和を判定できるようにしなければいけないので、その部分のコードも書きます。
メンツの切り分けができていれば、5パーツがすべて「AGARIRYANMEN」or「SYUNTU」or「TOITU」のいずれかである、かつTOITUの牌が役牌でないなら、平和が成立するという簡単なコードです。

前の牌譜解析では敬遠していた平和の判定があっさりできてしまいました。
いやー素晴らしいですねー。

以下、テストの軌跡。
161028-01.png

5番目の1m1m2m3mで上がり牌1mみたいな亜両面形が切り分けパターンが2パターンになる典型的な例ですね。

上がり牌1mを2m3mの「AGARIRYANMEN」(片割れの1m対子が「TOITU」)として取るか、
1mの単騎で「AGARITOITU」(片割れの1m2m3mが「SYUNTU」)として取るかの2パターンです。
平和があるなら前者の方がハン数が高いので前者採用、平和がないなら後者の方が符数が高いので後者採用という高点法を取ります。

11番目の二盃口の手についても
両面待ちのメンツ手or単騎待ちのメンツ手or七対子の3種類の切り分けがきちんとできています。

パッと思い浮かんだ中で切り分けパターンが一番多そうな牌姿が16番目の1m1m1m2m2m2m2m3m3m3m3m4m4m ロン1mの牌姿
1m単騎の清一色二盃口
1m雀頭2m3m両面の清一色平和二盃口
4m雀頭2m暗刻3m暗刻1m明刻1m2m3mシュンツの清一色のみ
4m雀頭1m暗刻2m暗刻3m暗刻2m3m両面の清一色三暗刻
4m雀頭1m2m3mシュンツ×3、2m3m両面の清一色平和二盃口
の5パターンで全部かなーと思います。
(高点法で2番目か5番目の清一色平和二盃口の10ハン)

一番下の4s5s5s6s7s ツモ6sは平和がなければカン6sにも取れて2符増える有名問題ですね。
きちんと2パターンに分けられていることが分かります。

というわけでメンツの切り分け+符計算のところまでがうまくいったことを確認できました。


続いて役判定に移りたいと思います。
すべての4メンツ1雀頭の切り分けパターンについてほぼ全部の役を逐一調べる(各役ごとに判定する関数を作らなければいけない)ので、けっこう大変ですが、これをやらないことには一人麻雀計算もAIもへったくれもないですから、がんばりましょう。

今日は役満の手についてです。
なぜ役満からやるかというと、役満が一つでも複合した時点で役満未満の役を調べる必要がなくなるからです。

役満のルールは天鳳依存とします。(すべてシングル役満)
役満のうち、「四暗刻」と「四槓子」はメンツの切り分けを行った後、それぞれの切り分けパターンごとに判定します。
それ以外の役満はメンツ構成に依存しない役なので、メンツ切り分けをする前に判定しておきます。

追加する情報は「天和or地和フラグ」および「順目」(1巡目以外は天和地和にはならない)です。

以下、テストの軌跡。
161028-02.png
2番目と3番目が天和・地和
4番目が大三元
5番目~9番目が四暗刻関連
10番目が字一色(メンツ手)
11番目が字一色七対子
12番目が複合役満(役満複合処理も正しくできている)
13,14番目が緑一色
15番目が清老頭
16,17番目が国士無双
18,19番目が四喜和
20番目が四槓子
21,22番目が九連宝橙

今のところはミスはなさそうです。(もちろんテストの過程でいろいろバグは潰しましたが。)

残りは役満以外の一般手の手役判定です。
今日はここまででコードを書くところまでは終わって、これからテストしてバグ潰しの作業です。


いやー、今日はけっこう頑張ったなー。かなり集中して作業ができました。
一人麻雀計算機制作計画その2・有効牌の計算
昨日はシャンテンチェックまでできたので、今日は有効牌の計算について。

新しい牌を引いたときにシャンテン数が下がるかどうかを見るだけなので、そんなに難しくはないですが、
今後一人麻雀をするときに呼び出しまくる関数なので、少しでも省力化をしたいところです。

具体的には
・メンツ手は±2の距離に関連牌がなければシャンテンチェックをスキップする。
・チートイ手は手持ちが6種類以下(3枚持ち4枚持ちが多くて、新たに孤立牌を引かないといけない状況)を除き、1枚持ちの牌だけをシャンテンチェックする。
・国士手はヤオ九牌のみをシャンテンチェックをする。

特に処理時間を食うのがメンツ手なので、その部分を特に省力化したいのですが、これ以上改善するのは厳しいか?
その色の枚数が3の倍数だったらシャンテン進むことはないとしてシャンテンチェックをスキップできるか?
いや、113sの時で1sと2s引きでシャンテン進むからふつうにだめだな。

というわけで、がりがりーとコード書き―の、ちょっと動かしてバグ取りをしーので一応できました。

以下はテストの軌跡。
161027-01.png
今のところは不正解は出てないのでだいじょうぶそうです。

次は上がり時のメンツの切り分けと符計算と手役判定と得点計算か。
まだまだ始まったばかりで難易度的にぬるいですが、これからたくさんコードを書かないといけない。
ぼちぼちやっていきましょう。
一人麻雀計算機制作計画その1・計画案とシャンテン数計算
ちょっと前からつくりたいと思っていたのが、一人麻雀計算機。

すでにあらさんやcritterさんが先陣を切って作っていらっしゃいますが、
これと同じような機能に加え、四人麻雀への拡張や麻雀AI制作にまで発展できたらうれしいなぁ、なんて考えています。

制作の手順を言語化してまとめておけば先の展望も見えてきます。
まぁまずは基本的なところからの積み上げですね。

◎Step0・麻雀の基本ルール関連
○Step0-1・シャンテン数計算
○Step0-2・上がり時のメンツ切り分け
○Step0-3・得点計算

◎Step1・従来モデルの一人麻雀計算機制作

◎Step2・モンテカルロシミュレーションによる一人麻雀計算機制作

◎Step3・四人麻雀への拡張

◎Step4・鳴き・点棒状況も考慮した四人麻雀への拡張

◎Step5・ベタ降りの打牌選択

◎Step6・全ツorベタ降り麻雀AI制作

◎Step7~・より複雑な麻雀AI制作

どこかで頓挫する可能性もあるけれど、今のところはこのような予定。うまくいくといいなぁ。
先のことはまだよくわからないので、ざっくりとしたStep分けです。


○Step0-1・シャンテン数計算
一番基本的なやつ。
今日はここまでできました。

参考にさせていただいたのが、「麻雀C言語プログラム集」のコードです。
参考にしたというか、ほぼ丸パクリしています。
いつも私が使ってるVBの言語の文法に合うようにちょっとだけ作り替えただけです。

自力で作ってもバグとかでボロが出そうなので、先人の知恵はありがたく借りることにしましょう。
文法がCとVBでは多少違うので、ある程度はプログラムの流れは理解しておく必要があります。単純な丸パクだけではうまくいかないです。

今日の成果物。
161026-01.png
161026-02.png
161026-03.png

上のテキストボックスに14枚の手牌情報を入力して(文法は東風荘のmjscore形式に準じる。)、
シャンテン数計算ボタンを押すと、シャンテン数などが計算されると。

テキストボックスのすぐ下にある4つの数字は左側から
国士のシャンテン数、チートイのシャンテン数、メンツ手のシャンテン数、副露数です。

シャンテン数計算ボタンの下にあるリストボックスは各牌の番号(マンズが1~9番+赤5mが10番、ピンズが11番~20番、ソーズが21番~30番、字牌が31番~37番)ごとに手牌にある枚数で、
4つある数字のうち左から
鳴いた牌も含めた枚数(赤は区別する)
鳴いた牌も含めた枚数(赤は区別しない)
鳴いた牌を含めない枚数(赤は区別する)
鳴いた牌を含めない枚数(赤は区別しない)

一番上は7s引いて69m引いたら字牌の単騎待ちだから二向聴で合ってる。
二番目は2mを切れば69m待ちの聴牌だから合ってる。(赤5mも正しく処理できている。)
三番目は北を切ればカン5s待ちの聴牌だから合ってる。(副露についても正しく処理できている。)

天鳳の牌理ツールでいくつかテストしてみましたが今のところ間違ったシャンテン数を返してはいないです。
いやー、素晴らしいですねー。これが最先端の科学の力か。

○Step0-2・上がり時のメンツ切り分け
○Step0-3・得点計算
こちらも上記サイトのコードを流用させていただく予定。
手間はかかるけど、ここまでは問題ないでしょう。

◎Step1・従来モデルの一人麻雀計算機制作
再帰式によってツモのみを考慮した和了率と局収支を出す計算プログラム。
この辺から私の力量が問われるでしょう。

◎Step2・モンテカルロシミュレーションによる一人麻雀計算機制作
どの牌を切るかを毎順分岐させて一番局収支が高いものを選択していくみたいな。
この辺はできるかどうかよくわからない。
計算量が発散しそうな気がして、できるかどうかやや悲観的ではあるが。
このStepがクリアできればその先の展望が見えてきます。

◎Step3・四人麻雀への拡張
◎Step4・鳴き・点棒状況も考慮した四人麻雀への拡張
今の局収支シミュレータと同様、パラメータを牌譜解析から得てそれをパーツごとに組み込んでいくみたいな。
今のところは場に出てる枚数とか牌の種類(端寄り中寄り)とかその牌をその他家がすでに切ってるかどうかくらいを考慮できればいいかなーと。山読み的なのはできるかもしれないけど今のところは考えてないです。
ここまでいければすべて全ツッパAIが1個完成します。

◎Step5・ベタ降りの打牌選択
他家攻撃に対してベタ降りするプログラムを別途作ります。
単純に現在切る牌の危険度だけでなく、安全牌の水増し的なことも考えなくてはいけないので、そこまで事は単純ではないです。
さすがに全ツAIよりは簡単だとは思いますが。

◎Step6・全ツorベタ降り麻雀AI制作
◎Step7~・より複雑な麻雀AI制作
後は全ツAIとベタ降りAIを組み合わせれば、最低限麻雀ができる(攻撃と防御ができる)AIが1個完成します。
ここまでいけば後はお楽しみタイムですね。
例えば、
・AIと対戦できる麻雀ゲームを作る
・AIどうしの対戦で牌譜を採取する
・他家から鳴ける牌が出た時の選択
・回し打ち的なAI作り
・どの牌を引いたら降りるか
・染め手やトイトイ狙いのAI

夢が膨らみますねぇ。

やはり最難関はStep1と2ですね。
一人麻雀計算のノウハウを持っていないので、その部分はかなり苦労しそうですが、
その先はすでに今の局収支シミュレータ作りのノウハウを活かせそうなので、なんとかなりそうな予感がします。
積み棒1500点ルール
今日はもう一本軽いネタを。
巷では積み棒が300点じゃなくて1500点というルールもあるという噂を聞きます。
私はやったことないのであまりわかりませんが、これってけっこう影響大きいのでは?と思いました。

局収支だけを調べる分には今のシミュレータのままで計算できます。
単に本場の数字を5倍にするだけなので。

さっそく調べてみます。

○仮定
・自分南家で両面のみ手の面前聴牌
・北家がリーチ(一発順ではない)
・初手無筋2378
・本場の数字だけを変える。
161025-05.png
押した場合の局収支。
場300の0本場と1本場はほとんど差がないように見えますが、
場1500の0本場と1本場は300点くらい1本場の方が上回っています。
この条件だと和了率>>放銃率なので、積み棒の利益の方が大きいですね。

場1500の2本場に至っては局収支が500点も違うのでシャレでは済まないレベルになってます。
押し引きに直結するレベルです。
161025-06.png
降りた場合の局収支。

自分の支出だけがあるような状況なので、積み棒がでかいとその分損という感じです。
ただの300・500が1本積むだけで800・1000になってしまうので被ツモの損失がバカになりません。

というわけで両面で無筋切って追っかけという和了率>>放銃率の状況なら積み棒があればあるほど押し有利(押し側プラスかつ降り側マイナスなので。)といえるでしょう。
たぶんこの調子なら和了率=放銃率くらいでもなんとかなりそうなので、愚形のみ手で初手両無筋456でも1本積めば押せそうな雰囲気になってます。
(→やってみたらさすがに放銃時のダメージがでかすぎるせいか、押した時0本場-1500点とか1本場-1700点とか2本場-1900点とかになった。降りに比べてめちゃくちゃ大損というわけではないが、まぁやりにくいでしょうね。)

個人的には降りの有利度が下がる積み棒1500点ルールは白熱した戦いが繰り広げられそうで面白そうとは思いますが、実際に金銭を賭けるとなるとそのハイリスクさに怖気づきそうです。
赤ドラの普及と同様、全体的にハイリスクになると相対的にリーチ棒1000点とかノーテン罰符の価値が下がるので、なんでもリーチ病and回し打ちできない病の私にとってはいいのかもしれませんが。
一向聴の実測値とシミュレーションの比較
今までいろいろと一向聴についてシミュレーションをやってきましたが、実は実測値との整合性のチェックをしていませんでした。
というのは、一向聴の実測値を取るためにはいろいろと障害が多かったためです。

・そもそもプログラミングの難易度が高い。(聴牌と比較して)
・一向聴の形を逐一定義して集計するのが困難。
・聴牌時の待ちが場合によって違ったりする。
・一向聴の手替わりがある。
・鳴きがある。
・面前で聴牌した時、リーチとダマの選択がある。
・一向聴時と非リーチの聴牌時、他家攻撃に対して降りる判断がある。

とまぁ、難しさばかりが目立つオンパレードです。
そういちいち言い訳を並べて嘆いていても仕方ないので、一番簡単な条件でやってみます。

・現在の順目で全員が非リーチ面前である。
・現在のツモ番の人が1枚切った時に一向聴である。
・分類は巡目と一向聴の受け入れ枚数のみ。形、聴牌時の待ち、手替わり有無、鳴き、リーチorダマ、途中で降りる、親子などは分類しない。(すべての要素がミックスされた平均的な挙動になる。)
・上記条件に当てはまるときの最終局結果(和了率・放銃率・被ツモ率・横移動率・聴牌流局率・不聴流局率・局収支)を調べる。

一向聴の受け入れ枚数については自分の手牌のみを見た残り枚数をカウントしています。通常完全一向聴なら他家・自分の捨て牌にかかわらず20枚、34556m44599p123sなら19枚のカウントです。(平面図での受け入れ枚数にあたる。)
場合分けは4枚区切りにします。
分類は巡目と受け入れ枚数のみなので、同じ受け入れ枚数でもいろいろな形が混在しています。
例えば受け入れ16枚の一向聴なら、両面両面とか両面リャンカンとか両面カンチャン対子とかカンチャン両面対子とか(レアケースとして)三面張+カンチャンなどいろんな形があります。
そういうのをいちいち分けたりはしていません。そこはご了承ください。

この条件で集計を始めてみたのですが…、
ものすご~く時間かかりました。
毎順時間のかかるシャンテンチェックの処理が入る影響が元凶です。
ツモ切りの場合は前巡の受け入れ枚数の変数をそのまま流用するとか、
明らかに聴牌化しない字牌はシャンテンチェックを省略するとか、
ない知恵を絞って省力化もしましたが、7日半もかかってしまいました。いやー大変だった。

そうして苦労して出てきた集計結果がこちらになります。

まずは各分類ごとの総データ数から。
161025-01.png
一向聴の形として一番多いのが9~12枚となっています。両面+カンチャン+浮き牌みたいな一向聴が標準的であると。
その次に多いのが13~16枚。
いわゆる完全一向聴が入る17~20枚は全体の10%程度しかありません。20枚受けの一向聴というのはかなり恵まれているというのがわかります(?)。
21枚以降は徐々に減少傾向にはなりますが、急に減少したりはしないようです。
37枚~40枚のあたりにも小さな山があるのが見えます。そのへんでありがちなのは3~7牌の孤立浮き牌2つのくっつき一向聴ですかね。浮き牌周辺とヘッドが暗刻になるのとでちょうど40枚の受け入れです。

また二向聴以上と一向聴・聴牌のデータ数を比較してみると、6巡目でも(鳴き手を含まない)全体の6~7割くらいは二向聴以上です。
たとえ形が不十分でも、6巡目で一向聴になってるというのはそれだけ運がいい現象なのかもしれません。

次に和了率です。
161025-02.png
基本的には受け入れが多いほど和了率も増える傾向にあります。ただ、増え方には差があります。

一番差が大きいのが9枚~12枚と13枚~16枚の間です。
おそらくは聴牌時の待ちが12枚と16枚では大きく変わることが原因でしょう。
12枚受けでありがちなカンチャン+カンチャン対子なら手替わりしない限りは愚形確定である一方、
16枚受けでありがちな両面+両面なら良形確定となるように聴牌時の受けがぐっとよくなります。
もちろん、他のケースもあるので、それよりは差が縮まるでしょうが、聴牌時良形割合が増えるのは間違いないでしょう。

17枚~20枚は13枚~16枚より和了率が3~4%くらい高めになっています。
単純な受け入れの多さに加え、両面+リャンカンなどの愚形残りのパターンが20枚だと大きく減るためでしょう。(例外は三面張+カンチャンなど)

21枚以降は和了率の伸びがかなり緩やかになります。
すでに受け入れ枚数・待ちの良さが十分なので、1枚の価値がそこまで大きくないということなんでしょう。
特に聴牌しやすいヘッドレス形やくっつき形だと愚形聴牌の可能性もありますしね。

48枚受けとか超広い一向聴でも聴牌の和了率には遠く及びません。
一向聴はえらいが、聴牌はもっとえらいみたいな。

続いて局収支です。
161025-03.png
これも基本的に枚数が多いほど有利です。
だいたい増え方は和了率のときと似たような感じですかね。

なぜか1巡目二向聴以上も局収支プラスになってますが、供託リーチ棒の影響だろうか。あとは1巡目に鳴きが入ったケースが除かれる影響と。
あとは1枚~4枚の一向聴がかなりイレギュラーな値(かなりの局収支プラス)になってます。観測されたのは1224m+関係ない浮き牌の一向聴ばかりだったので、一盃口とか七対子が複合しやすいみたいな事情だろうか。

そういうところは置いておいて、
5枚~8枚の一向聴だと7巡目まで局収支プラスです。8枚と言えば愚形+愚形+関係ない浮き牌の一向聴が大半でしょうが、そういう形悪い一向聴でも二向聴よりはかなりえらいということでしょう。
9枚~12枚だと9巡目まで局収支プラスです。他家が全く動いていないという条件付きですが、わりと遅めの巡目でも一向聴は通常より恵まれているということでしょう。(まぁ、ドラの有無とかもかかわってくるでしょうが。)
13枚~16枚は一気に局収支のプラスが大きくなります。特に和了が見込める序盤は格別です。良形が見込める一向聴はもっとえらいという感じ。
次の17枚~20枚がそこそこで、その先はあんまり局収支が増えないです。
まぁ広いにこしたことはないけど、愚形聴牌になる牌を引いてもうれしくないしなぁ、みたいな。
それよりは聴牌の方が圧倒的にえらいですね。


というわけで、実測値を取り終えたのですが、これをシミュレーションとの比較にぶち込もうと思うと、これまた一苦労です。
形とか鳴きとか変化とかそういうのが全部ごちゃ混ぜになってるので、すべて何らかの仮定を置かないと計算できないシミュレーションとの比較はかなり難しいです。

ここでは、
・17枚~20枚の実測値と、枚数問わずの完全一向聴のシミュレーションを比較する。
・鳴きなしと鳴きありのケースを2パターンやってみる。
・他家攻撃に対して、一向聴から7%以上の危険度の牌は押さずにベタ降りに回る。
・その他条件はシミュレーション初期値に準じる。
・局収支は無視する。

17枚~20枚ならほとんど完全一向聴かつ両面ほぼ確定で変化の余地も少なかろうという推測をもとに、
これくらいざっくりとした感じで比較をやってみます。
161025-04.png
17枚~20枚実測VS鳴きなしシミュレーションの比較。
和了率はシミュレーションの方がやや低いですが、鳴きを考慮してない分があるのでまぁ順当なところでしょう。
和了時ツモ割合がシミュレーションの方がかなり高いです。シミュレーション側は聴牌したら全部リーチの一方、実測は鳴き聴牌やダマも含まれるからだろうけど、ちょっと違いすぎる気がする。
放銃率・被ツモ率はかなり近い。
横移動率はやや低めに出てる。

17枚~20枚実測VS鳴きありシミュレーションの比較。
和了時ツモ割合は実測に近くなったが、和了率そのものがかなり高めになってます。
実測は鳴けないケースとか、鳴ける場合でもスルーしたケースも含まれてる(というかそちらの方が多数か)分だとは思いますが、
さすがに和了率が違いすぎるのでこれは比較にはなりませんなぁ。


というわけで、鳴きなしの方はわりかし実測に近いですが、ちょっと違うところもあるので、実測との整合性チェックの件は今のところよくわからんという結論で。
さんざん難しいことやっといて結論がそれかよ、みたいなツッコミが入りそうですが、実測側を細かく場合分けとかしないと厳しいですね。
とりあえず当分は時間かかる牌譜解析はやりたくないというのが本音です。
他家副露者の打点別降り移行率+初手危険度手動設定
昨日、今日と、シミュレータの改造をやっていました。

○改造その1
現状、他家通常副露で打点を「平均」に指定すると、副露聴牌時の聴牌崩し率について平均的な値を適用していましたが、
これを相手の打点によって聴牌崩し率を変える(高打点ほど聴牌崩し率は低く、安手ほど聴牌崩し率が高い)ような変更を試みました。

そのために現状、他家の打点については和了の発生後に決定させていましたが、そうすると聴牌崩し率で打点を参照できない(和了発生前は打点が定まっていない)ので、
他家の打点を現在の巡目の時点で決定させるよう変更しなければなりません。
思ったより影響する範囲が広くて改造に手間取りましたが、なんとかできました。

それで自分リーチ(残り2枚超愚形待ち)VS相手一人副露(平均打点)で放銃時の失点をチェックしてみます。(初手は完全安牌(自分リーチは100%成立する)、他二人は降り)
161016-01.png
打点分布のパラメータそのものは変わっていませんが、
新バージョンでは高打点ほど押してきて、低打点ほど降りられる傾向が強いのを加味してるので、
300点くらい全体の放銃時失点が上がっています。

打点によって変えてるのが聴牌時のみで、ノーテン時に打点を参照して聴牌化率とか1順当たりリーチへのロン和了率を変えるみたいなことはやってないので、まだ不十分かもしれませんが、とりあえずリーチしたときの放銃時失点が通常時よりも高くなる傾向を多少はキャッチできて、まぁ今日のところはよしとしましょう。

同じ条件で、他家打点だけ変えた時の放銃率です。
161016-02.png
低打点の方が降りてもらいやすいので放銃率が低くなって、高打点だとまっすぐ突っ込んでこられるので、放銃率が高くなってるのが分かります。
だいたい2%差くらいですね。

とりあえずは作って最低限のテストだけはやった(途中でエラーが出る系のバグは潰した)のですが、隠れてるバグがまだありそうで怖いので、ちょっと様子見してみます。

○改造2
初手に切る牌の危険度について、現状は牌の種類を選択する方式になってますが、
読みによって危険度が通常と違うと読めるみたいなケースにも対応するため、危険度を数値でも入力できる機能もつけました。
こちらはかなり簡単。

自分両面リーチのみVS相手一人染め3副露余りあり(聴牌率100%に指定)で初手危険度50%としてテストでシミュレーションしてみます。
161016-03.png
わぁい、放銃率が地獄の50%台に乗ったぞー♪

局収支も-2000点と非常に悪く、可能な限りベタ降りしたいですね。
リーチ者の有無の副露者の打点
今日のテーマは副露者が和了した時の打点についてです。
リーチ者が他にいたら副露の安手では押せないで降りるケースが増えるので、平均打点はリーチ者なしに比べて増えるのではないかという予想があります。

○集計条件
・和了者が副露をしている。
・染め手模様とドラポンは除外する。
・リーチ者の有無と先制リーチから経過した巡目別に、和了者の上がりハン数と平均素点を調べる。

牌譜解析にかけてみたのがこちら。
161014-01.png

確かにリーチ者がいるときほど、またはリーチから巡目が多く経過しているときほど、上がりハン数と平均素点は上がる傾向があるようです。

子のロンでリーチ者なしと5巡以上先制リーチから経過してる場合とで0.5ハンくらい差であると。
うーん。そこそこ大きいような、そうでないような。

親なら安手でも十分押す価値があるので得点の伸び方は緩やかになっています。

現状だとシミュレーション上で他家副露者が降りに回る挙動をするとき、
内部処理的に他家の和了が発生してから上がりハン数符数を決定する処理をやっているので、
聴牌崩し率を平均打点のものを使ってるんですよねー。

これを現在の巡目時点であらかじめ上がりハン数符数を決定させておいて、聴牌崩し率をそのハン数に応じたものに変えるみたいな改善をやってみようかなぁ。
それで今回の結果に近くなる(リーチ者なしとリーチ者ありで他家副露者和了時の打点に差が出る)ならそれで万々歳、
そうならなかったらまた別の方法でも考えましょうか。

両面塔子選択・端寄りか枚数か
今日のテーマはこちら。
161013-03.png

両面塔子選択で、23mか56mのどちらかを嫌うところ。
見えてる枚数に差がなければ、端寄りの23mを残すので異論はないでしょうが、
問題は1mの見えてる枚数と7mの見えてる枚数に差があるとき。
どういう条件なら56mを残せるかを調べてみます。

○仮定
・自分南家、他3人非リーチ面前
・メンピンの両面両面一向聴
・69pの受けは残り枚数不問。14mと47mについては残り8枚~4枚まで調べる。
・変化(縦引き完全一向聴化など)は考慮しない。
・他家攻撃に対して全ツ
・形テンは15巡目から

161013-01.png
見えてる枚数1枚差のときの和了率。
グラフにしようかと思ったけど、微差すぎてかえってわかりにくいかなぁと思って表にしました。

微差なのでどちらを選んでもよさそうですが、
強いて挙げるなら枚数が多く残ってる(8枚VS7枚とか)なら1枚の価値が大きくないので端寄り残し側、
残り枚数が少ないなら(5枚VS4枚とか)なら1枚の価値が大きいので枚数重視で中寄り残り側、
というところでしょうか。

161013-02.png
2枚差の時の和了率。

さすがに2枚差なら大体枚数重視で47mを残した方がいいみたいです。
ただ、6枚VS8枚だとあんまり差は大きくないです。(多少は8枚47mの方がいいみたいですが。)
プロフィール

Author:nisi5028
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
フリーエリア
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード