2016-11-08(Tue)
今日の成果はこちら。
2016年11月8日 ver1.06
打牌固定しない場合で、黒5が手牌にあるのに赤5が打牌候補になってる時と、
一向聴・手替わり1以上のとき、手替わり0で予備調査を行い、最善手候補より500点以上局収支が低い打牌は本調査を省くよう修正。
一向聴の最善手候補の有効牌が12枚以下の時は、本調査のスキップは行わない。
手牌入力値が変わった時、固定打牌のチェックを外すよう修正。
学習モードを削除
計算速度の改善。
1個目は前回話をした一向聴・手替わり1以上のときの打牌のより分けについて。
従前はシャンテンを維持できるすべての牌について計算していましたが、明らかに損な打牌についても計算してるケースがあったので、そういうのは計算から省くようにしました。(3444m56789p6799s9sなら打4mとか打9sとか。)
ただ、テストを進めていくと、狭い一向聴のケースでは変化が重要になることが多いためか、手替わり0の予備調査では不利であっても変化も考慮することで覆るケースも散見されました。
二向聴戻しがキャッチできないのはしょうがないとして(「固定打牌」で別途調べることで対応する。)、一向聴で実は有利になる打牌を計算から取りこぼすことがないように、受け入れ12枚以下(予備調査での最適打)の場合は本調査の省略はしないことにしました。
それで昨日から今日にかけてウザク本300問テストをやって、それがなんとか終わったのですが(けっこう大変だった…)、
終わってみてまたコードを見直したところ、より高速化できるプランが浮かんだので、いろいろいじくってみました。
そうしたら結局、計算の本体関数がほぼ全面修正という結果になりました。
手を加えようと思ったのが、記憶検索のところが中心です。ざっと箇条書きで挙げると、
・何度も使うハッシュ値を変数に保存して使い回す。
・再帰関数の引数に有効牌情報を入れた配列と有効牌枚数の変数を加え、再帰先でそれを参照することで有効牌の計算回数を減らす。
・異なる打牌のときに記憶情報をリセットしていたものをそのまま情報を引き継いで使い回し。
・記憶情報を格納するコレクションをList型からDictionary型に乗り換え。
1個目と2個目が無駄の排除です。バグというほどではないけれど、同じような計算をしてるところを1回にまとめて計算時間を減らしています。
3個目は異なる打牌の時にも結局似たような牌姿に戻ることがけっこう多くて、その都度計算し直していたのを、記憶情報を引き継ぐことで再計算の時間をカットするのが目的です。ただし、貯めておくレコードの件数が増えてかえって検索コストがかかるというデメリットもあるので判断が難しかったです。
この点については4個目で改善されて、実際に両者を比べて時間が短くなったので、晴れて採用となりました。
4個目はいろいろ調べてみるとDictionary型というものを使うと、文字列をキーとして値を高速検索できるらしいことが分かりました。
いちいちListをFor文で検索して、さらに別のList(局収支とか和了率とか)を参照しなくても、文字列と各種数値をセットで扱うことができ、高速検索可能なTryGetValue関数で臨時で設けた変数に一発で検索結果を引き渡せると。
また値の型は配列型でもOKなので、いちいち
Dim tmptmpkyokushusi As Integer
Dim tmptmphouraritu As Integer
…
とか宣言してたのを
Dim tmptmpsu(6)As Integer
If kioku_dic_kyokushusitati(tmpkey4, tmpkey3).TryGetValue(tmpstring2, tmptmpsu) Then '記憶検索
…
とかやってればスピードは上がるし、コードも見やすくなるしで一石二鳥です。
入門書には載ってない情報だったので、まさにインターネット先生のお力ですね。
その効果がこちら。左が前回で、右が今回。

本調査(打4mと打9s)の計算を省略してるのも込みですが、効果はてきめんです。検索の時間が10分の1くらいまで減っています。
ほぼ全面改修になって、バグが出まくったのを乗り越えた甲斐があるというものです。
打牌の選択肢が多くて、変化も(1回が上限ですが)考慮していて7秒で終わるなら十分戦力ですね。いやー、やってよかった。
ただ、かなり手直ししたので、もう一度テストが必要です。さすがにもう一度300問やり直すモチベーションはないので、後半の90問くらいのテストにとどめておこうかしら。
さすがに全く未テストのものをお出しするわけにはいかないので、今日の最新版のアップはなしで。
さすがにこれ以上の計算速度の改善はもうできないとは思うので、テストが終わって何もなければ、次回報告と最新版アップをして、無事一人麻雀計算のフェーズは終了と。
いよいよ四人麻雀への拡張の道も見えてきました。
2016年11月8日 ver1.06
打牌固定しない場合で、黒5が手牌にあるのに赤5が打牌候補になってる時と、
一向聴・手替わり1以上のとき、手替わり0で予備調査を行い、最善手候補より500点以上局収支が低い打牌は本調査を省くよう修正。
一向聴の最善手候補の有効牌が12枚以下の時は、本調査のスキップは行わない。
手牌入力値が変わった時、固定打牌のチェックを外すよう修正。
学習モードを削除
計算速度の改善。
1個目は前回話をした一向聴・手替わり1以上のときの打牌のより分けについて。
従前はシャンテンを維持できるすべての牌について計算していましたが、明らかに損な打牌についても計算してるケースがあったので、そういうのは計算から省くようにしました。(3444m56789p6799s9sなら打4mとか打9sとか。)
ただ、テストを進めていくと、狭い一向聴のケースでは変化が重要になることが多いためか、手替わり0の予備調査では不利であっても変化も考慮することで覆るケースも散見されました。
二向聴戻しがキャッチできないのはしょうがないとして(「固定打牌」で別途調べることで対応する。)、一向聴で実は有利になる打牌を計算から取りこぼすことがないように、受け入れ12枚以下(予備調査での最適打)の場合は本調査の省略はしないことにしました。
それで昨日から今日にかけてウザク本300問テストをやって、それがなんとか終わったのですが(けっこう大変だった…)、
終わってみてまたコードを見直したところ、より高速化できるプランが浮かんだので、いろいろいじくってみました。
そうしたら結局、計算の本体関数がほぼ全面修正という結果になりました。
手を加えようと思ったのが、記憶検索のところが中心です。ざっと箇条書きで挙げると、
・何度も使うハッシュ値を変数に保存して使い回す。
・再帰関数の引数に有効牌情報を入れた配列と有効牌枚数の変数を加え、再帰先でそれを参照することで有効牌の計算回数を減らす。
・異なる打牌のときに記憶情報をリセットしていたものをそのまま情報を引き継いで使い回し。
・記憶情報を格納するコレクションをList型からDictionary型に乗り換え。
1個目と2個目が無駄の排除です。バグというほどではないけれど、同じような計算をしてるところを1回にまとめて計算時間を減らしています。
3個目は異なる打牌の時にも結局似たような牌姿に戻ることがけっこう多くて、その都度計算し直していたのを、記憶情報を引き継ぐことで再計算の時間をカットするのが目的です。ただし、貯めておくレコードの件数が増えてかえって検索コストがかかるというデメリットもあるので判断が難しかったです。
この点については4個目で改善されて、実際に両者を比べて時間が短くなったので、晴れて採用となりました。
4個目はいろいろ調べてみるとDictionary型というものを使うと、文字列をキーとして値を高速検索できるらしいことが分かりました。
いちいちListをFor文で検索して、さらに別のList(局収支とか和了率とか)を参照しなくても、文字列と各種数値をセットで扱うことができ、高速検索可能なTryGetValue関数で臨時で設けた変数に一発で検索結果を引き渡せると。
また値の型は配列型でもOKなので、いちいち
Dim tmptmpkyokushusi As Integer
Dim tmptmphouraritu As Integer
…
とか宣言してたのを
Dim tmptmpsu(6)As Integer
If kioku_dic_kyokushusitati(tmpkey4, tmpkey3).TryGetValue(tmpstring2, tmptmpsu) Then '記憶検索
…
とかやってればスピードは上がるし、コードも見やすくなるしで一石二鳥です。
入門書には載ってない情報だったので、まさにインターネット先生のお力ですね。
その効果がこちら。左が前回で、右が今回。

本調査(打4mと打9s)の計算を省略してるのも込みですが、効果はてきめんです。検索の時間が10分の1くらいまで減っています。
ほぼ全面改修になって、バグが出まくったのを乗り越えた甲斐があるというものです。
打牌の選択肢が多くて、変化も(1回が上限ですが)考慮していて7秒で終わるなら十分戦力ですね。いやー、やってよかった。
ただ、かなり手直ししたので、もう一度テストが必要です。さすがにもう一度300問やり直すモチベーションはないので、後半の90問くらいのテストにとどめておこうかしら。
さすがに全く未テストのものをお出しするわけにはいかないので、今日の最新版のアップはなしで。
さすがにこれ以上の計算速度の改善はもうできないとは思うので、テストが終わって何もなければ、次回報告と最新版アップをして、無事一人麻雀計算のフェーズは終了と。
いよいよ四人麻雀への拡張の道も見えてきました。
スポンサーサイト