押し引きアルゴリズムの改善(1) - koba::blog で全ての打牌について1つ1つ押し引きを判断できるようになったので、押し引き表の牌姿は評価値何点? - koba::blog で言及した「評価値を基準とした押し引き判断」を実装する。
改善内容
現在1シャンテンでは手牌の良し悪しに関わらず
- 現物・字牌・スジは押す
としているが、評価値を基準に手牌を 愚形、好形、超好形 の3つに分け、
- 愚形
- ベタオリ(現在の2シャンテン同様)
- 好形
- 現物・字牌・スジは押す(現在の1シャンテンのまま)
- 超好形
- 全押し(現在のテンパイ同様)
とする改善を行う。具体的には評価値400未満を愚形、400以上1200未満を好形、1200以上を超好形とした*1。押し引き表の牌姿は評価値何点? - koba::blog の牌姿と照らし合わせると、
牌姿 | 子の場合 | 親の場合 | ||||
---|---|---|---|---|---|---|
愚形 | 好形 | 超好形 | 愚形 | 好形 | 超好形 | |
七対子 | +2翻 | (なし) | (なし) | +1翻 | +2翻 | (なし) |
両面 + 愚形 | 平和 | 平和+1翻 〜平和+2翻 | (なし) | のみ手 | 平和 〜平和+1翻 | 平和+2翻 |
両面 x 2 | のみ手 | 平和 〜平和+2翻 | (なし) | (なし) | のみ手 〜平和+1翻 | 平和+2翻 |
くっつき | (なし) | のみ手 〜平和 | 平和+1翻 | (なし) | のみ手 〜平和 | 平和+1翻 |
となる。評価値は2シャンテン以降であれば計算できる*2ので、2シャンテンの場合も上記基準を適用することする。
プログラム修正
/* anquan: 危険度最低の牌 min: 最低の危険度 weixian: 各牌の危険度を納めるハッシュ dapai: 打牌する牌(初期値は危険度最低の牌) max: 打牌する牌の評価値 */ let n_xiangting = Majiang.Util.xiangting(this._shoupai); // 手牌のシャンテン数を取得 /* ……… */ for (let p of this.get_dapai()) { // 全ての可能な打牌について以下を行う /* ……… */ let shoupai = this._shoupai.clone().dapai(p); // 打牌後の牌姿を作成 /* ……… */ let ev = this.eval_shoupai(shoupai, paishu); // 評価値を計算 let x = 1 - paijia(p)/100 + ev; // 評価値同点の補正 /* ……… */ if (min < 6) { // 打牌可能な牌が全て無スジ以上の危険度なら押す if (n_xiangting > 2 && weixian[p] > min) continue; // 2シャンテン以前はベタオリ if (n_xiangting > 0 && ev < 400 && weixian[p] > min) continue; // 1〜2シャンテンの場合、愚形はベタオリ if (n_xiangting > 0 && ev < 1200 && weixian[p] > 5) continue; // 超好形でなければ無スジは押さない } if (x >= max) { // 評価値最大の場合 max = x; // max を更新する dapai = p; // dapai を更新する max_tingpai = n_tingpai; } }
評価
前回同様 デュプリケート方式 で1000戦の対局を行った結果は以下の通り。
結果 | 改善前 | 改善(1) | 改善(2) | |||
---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.2% | +6441 | 11.6% | +6468 | 11.3% | +6721 |
放銃 | 10.5% | -6209 | 13.0% | -6200 | 12.0% | -6279 |
被ツモ | 32.6% | -2690 | 31.5% | -2703 | 31.9% | -2706 |
横移動 | 26.3% | -57 | 25.6% | -68 | 26.0% | -63 |
流局 | 20.4% | -827 | 18.2% | -615 | 18.9% | -667 |
平均 | -1057 | -1036 | -999 |
改善前 | 改善(1) | 改善(2) | 改善前 | 改善(1) | 改善(2) | ||
---|---|---|---|---|---|---|---|
対戦数 | 1,000 | 1,000 | 1,000 | 総局数 | 10,505 | 10,465 | 10,464 |
1位率 | .241 | .249 | .255 | 和了率 | .209 | .218 | .215 |
2位率 | .251 | .244 | .248 | 放銃率 | .128 | .141 | .137 |
3位率 | .254 | .255 | .248 | 立直率 | .221 | .237 | .232 |
4位率 | .254 | .252 | .249 | 副露率 | .346 | .349 | .349 |
平均順位 | 2.52 | 2.51 | 2.49 | 平均打点 | 5,492 | 5,499 | 5,580 |
局収支はかなり改善されたが、平均順位の変動はわずかだった。次回はテンパイしていてもオリるべきケースを検討する。