2017-02-10(Fri)
今日は前に作った麻雀ゲームから棒テン即リー全ツッパAIのところを移植して、サーバーと通信させるところまで成功しました。
何戦かテストで打たせてみて、打牌選択、リーチ宣言、ツモ和了、ロン和了が今のところうまくいってるのを確認。
↓ログの一例
http://gimite.net/mjai/log/2017-02-10-172058.mjson.html
http://gimite.net/mjai/log/2017-02-10-173004.mjson.html
http://gimite.net/mjai/log/2017-02-10-173847.mjson.html
ログを眺めていると棒テン即リー全ツッパAIの弱さがよくわかるなぁ。
シャンテン数と1次有効牌の残り枚数のみが判断材料なので、メンツ手シャンテン数>チートイシャンテン数になってるときに、そうそうに七対子に決め打って、暗刻やシュンツを崩すケースが頻発しています。
あとは頭が他にない時に両面対子を早い段階で頭固定するケースもでてきてます。
まぁ、棒テンを忠実に再現していて、単純なCPUらしいといえばらしいですが。
次はちゃんと期待値計算をするプログラムをAI化するところですね。
棒テン即リー全ツッパAIは麻雀ゲームを作るときに、グローバル変数をなるべく使用しない設計にしてあるけれど、
ちゃんとした四麻計算機はそういう処理をまだやってなくて、関数の設計のやり直しから入らないといけないから完成まではちょっと時間がかかりそうな気がします。
あとは処理速度的な問題をどうするかを考えないといけません。
とりあえず最初は他家を考慮しない再帰パートのみでシミュレーションパートはやらない(つまり鳴きと他家攻撃は全く考えない全ツッパAI)、ということと
情報の更新タイミングをなるべく減らして計算時間を節約するというのを考えています。
情報の更新タイミングを減らすというのは具体的には
シャンテン数が進む有効牌について、
・対子・暗刻の牌が他家から出た時
・0枚持ち・1枚持ちの有効牌で2枚目以降が見えた時
に限って最適打テーブルを再計算するということです。
逆にそれ以外のケースについてはそこまで場況(見えてる枚数)の情報が増えてないということなので、前の巡目で計算した最適打テーブル(当該巡目以降のあらゆる手牌についての最適打情報がすべて載っている)をそのまま活用するということです。
さすがに2枚目以降が見えた時はそこの塔子・対子の受け入れがかなり弱くなると思われるので、増えた情報により最適打が変わってくるケースが出てくるので、再計算をした方がいいと思っています。
後は現在のシャンテン数ごとに計算方式を変えるということですね。
・3シャンテン以上…棒テン即リー全ツッパAIをそのまま使う。(ただし、七対子偏重を防ぐための仕組みは何かしら考える。)
・2シャンテン…手替わり回数0として一人麻雀の期待値計算。シャンテン戻しは考慮しない。
・1シャンテン…手替わり回数1として一人麻雀の期待値計算。シャンテン戻しは(最初は)考慮しない。
・聴牌…ダマとリーチのそれぞれを計算していい方を採用。シャンテン戻しも1番受け入れの広くなる1打のみに限って考慮する。
こんな感じでしょうか。聴牌についてはちょっとコードを書き直す必要がありそうです。
とりあえずこれでやってみますか。
何戦かテストで打たせてみて、打牌選択、リーチ宣言、ツモ和了、ロン和了が今のところうまくいってるのを確認。
↓ログの一例
http://gimite.net/mjai/log/2017-02-10-172058.mjson.html
http://gimite.net/mjai/log/2017-02-10-173004.mjson.html
http://gimite.net/mjai/log/2017-02-10-173847.mjson.html
ログを眺めていると棒テン即リー全ツッパAIの弱さがよくわかるなぁ。
シャンテン数と1次有効牌の残り枚数のみが判断材料なので、メンツ手シャンテン数>チートイシャンテン数になってるときに、そうそうに七対子に決め打って、暗刻やシュンツを崩すケースが頻発しています。
あとは頭が他にない時に両面対子を早い段階で頭固定するケースもでてきてます。
まぁ、棒テンを忠実に再現していて、単純なCPUらしいといえばらしいですが。
次はちゃんと期待値計算をするプログラムをAI化するところですね。
棒テン即リー全ツッパAIは麻雀ゲームを作るときに、グローバル変数をなるべく使用しない設計にしてあるけれど、
ちゃんとした四麻計算機はそういう処理をまだやってなくて、関数の設計のやり直しから入らないといけないから完成まではちょっと時間がかかりそうな気がします。
あとは処理速度的な問題をどうするかを考えないといけません。
とりあえず最初は他家を考慮しない再帰パートのみでシミュレーションパートはやらない(つまり鳴きと他家攻撃は全く考えない全ツッパAI)、ということと
情報の更新タイミングをなるべく減らして計算時間を節約するというのを考えています。
情報の更新タイミングを減らすというのは具体的には
シャンテン数が進む有効牌について、
・対子・暗刻の牌が他家から出た時
・0枚持ち・1枚持ちの有効牌で2枚目以降が見えた時
に限って最適打テーブルを再計算するということです。
逆にそれ以外のケースについてはそこまで場況(見えてる枚数)の情報が増えてないということなので、前の巡目で計算した最適打テーブル(当該巡目以降のあらゆる手牌についての最適打情報がすべて載っている)をそのまま活用するということです。
さすがに2枚目以降が見えた時はそこの塔子・対子の受け入れがかなり弱くなると思われるので、増えた情報により最適打が変わってくるケースが出てくるので、再計算をした方がいいと思っています。
後は現在のシャンテン数ごとに計算方式を変えるということですね。
・3シャンテン以上…棒テン即リー全ツッパAIをそのまま使う。(ただし、七対子偏重を防ぐための仕組みは何かしら考える。)
・2シャンテン…手替わり回数0として一人麻雀の期待値計算。シャンテン戻しは考慮しない。
・1シャンテン…手替わり回数1として一人麻雀の期待値計算。シャンテン戻しは(最初は)考慮しない。
・聴牌…ダマとリーチのそれぞれを計算していい方を採用。シャンテン戻しも1番受け入れの広くなる1打のみに限って考慮する。
こんな感じでしょうか。聴牌についてはちょっとコードを書き直す必要がありそうです。
とりあえずこれでやってみますか。
スポンサーサイト