電脳麻将 の現在の押し引きアルゴリズムは親に対する考慮がない。牌の危険度計算アルゴリズム(1) - koba::blog までの 絶対危険度 は危険度を現物、字牌、スジ、無スジのように離散的に扱っており、危険度の値は序列を表しているに過ぎなかったのだが、牌の危険度計算アルゴリズム(2) - koba::blog、牌の危険度計算アルゴリズム(3) - koba::blog で 相対危険度 を導入し、危険度が連続値になったことにより「親の危険度は1.5倍」のような比較が可能になった。今回は親のリーチに対する危険度を変動させながら実際にAI同士を対戦させ、適切な値があるのか検証する。
親リーチの危険度
親リーチを子のリーチより危険とする根拠は親の打点が1.5倍という麻雀のルールによるものなので、親のリーチに対する危険度を 1.30~1.50 倍(これを 係数A とする)で変動させ、実際の押し引きに効果があるか検証した。
結果 | 係数A: 1.30 | 係数A: 1.35 | 係数A: 1.40 | 係数A: 1.45 | 係数A: 1.50 | |||||
---|---|---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.3% | +6833 | 10.3% | +6841 | 10.3% | +6841 | 10.3% | +6851 | 10.2% | +6845 |
放銃 | 10.3% | -6391 | 10.2% | -6351 | 10.1% | -6385 | 10.1% | -6382 | 10.0% | -6372 |
被ツモ | 31.7% | -2748 | 31.7% | -2746 | 31.8% | -2744 | 31.7% | -2742 | 31.8% | -2741 |
横移動 | 29.0% | -67 | 29.0% | -67 | 29.0% | -68 | 29.0% | -68 | 28.9% | -67 |
流局 | 18.7% | -806 | 18.8% | -814 | 18.8% | -820 | 18.9% | -824 | 19.1% | -830 |
平均 | -997 | -987 | -987 | -986 | -989 |
1.35〜1.50 で大きな差はなかったが局収支が最もよかった 1.45 を採用することとした。
二軒リーチの危険度
危険度を計算する対象が2名以上の場合、牌ごとに最大値を取るようにしていたのだが、ダブロンありのルールでは総和の方が正しいかもしれないと思い、総和をとるように変更してみた。
結果 | 割合 | 局収支 |
---|---|---|
和了 | 9.9% | +6847 |
放銃 | 9.6% | -6385 |
被ツモ | 31.9% | -2744 |
横移動 | 29.4% | -66 |
流局 | 19.2% | -842 |
平均 | -997 |
局収支が悪化。このアイデアは失敗のようなので不採用とした。
プログラム修正
クラス Majiang.SuanPai
の牌の相対危険度を求めるメソッド suan_weixian_all()
を以下に修正する。
suan_weixian_all(bingpai) { let weixian_all; // 相対危険度を格納するハッシュ for (let l = 0; l < 4; l++) { /* …… */ /* 全ての牌の絶対危険度(weixian)とその総和(sum)を求める */ /* …… */ /* 全ての牌の相対危険度を計算する */ for (let p of Object.keys(weixian)) { weixian[p] = weixian[p] / sum * 100 * (l == 0 ? 1.45 : 1); // 相対危険度を求める // リーチ者が親の場合は危険度を 1.45 倍する /* …… */ weixian_all[p] = Math.max(weixian_all[p], weixian[p]); // リーチ者が2人以上の場合は最大値を選択する } } if (weixian_all) return (p)=>weixian_all[p.substr(0,2).replace(/0/,'5')]; // 相対危険度を返す関数を返す }
評価
今までの改善結果は以下の通り。*1
結果 | 改善前 | 改善(1) | 改善(2) | 改善(3) | 改善(4) | |||||
---|---|---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.4% | +6848 | 10.7% | +6861 | 10.7% | +6854 | 10.4% | +6799 | 10.3% | +6851 |
放銃 | 11.3% | -6554 | 11.2% | -6612 | 11.2% | -6609 | 10.4% | -6415 | 10.1% | -6382 |
被ツモ | 31.5% | -2735 | 31.4% | -2749 | 31.4% | -2750 | 31.7% | -2747 | 31.7% | -2742 |
横移動 | 28.5% | -69 | 28.6% | -69 | 28.6% | -70 | 29.0% | -69 | 29.0% | -68 |
流局 | 18.3% | -762 | 18.0% | -750 | 18.1% | -749 | 18.5% | -781 | 18.9% | -824 |
平均 | -1047 | -1027 | -1024 | -993 | -986 |
改善前 | 改善(2) | 改善(3) | 改善(4) | 改善前 | 改善(2) | 改善(3) | 改善(4) | ||
---|---|---|---|---|---|---|---|---|---|
対戦数 | 1,000 | 1,000 | 1,000 | 1,000 | 総局数 | 10,480 | 10,488 | 10,505 | 10,502 |
1位率 | .237 | .237 | .233 | .232 | 和了率 | .213 | .215 | .213 | .213 |
2位率 | .244 | .250 | .256 | .264 | 放銃率 | .133 | .132 | .128 | .127 |
3位率 | .248 | .244 | .247 | .244 | 立直率 | .231 | .233 | .233 | .233 |
4位率 | .271 | .269 | .264 | .260 | 副露率 | .342 | .342 | .342 | .342 |
平均順位 | 2.55 | 2.55 | 2.54 | 2.53 | 平均打点 | 5,622 | 5,625 | 5,607 | 5,642 |
改善前と比べ、対リーチ和了率は 10.4% → 10.3% と若干下がったが、対リーチ放銃率は 11.3% → 10.1% と大幅に改善した。これにより対リーチ局収支も -1047 → -986 と向上した。
順位に関してはトップ率が下がったものの2位率が大幅に上昇しラス率が下がったことで、平均順位 2.55 → 2.53 と若干上昇した。和了率などの統計では、放銃率のみが 13.3% → 12.7% と大きく改善された。
このアルゴリズムを次回リリースの ver.1.6.0 に採用する。
*1:改善(1)と(2)で順位成績はほぼ同じなので、改善(1)は割愛した