牌の危険度計算アルゴリズム(2) - koba::blog で実現した牌の 相対危険度 を押し引きに適用する。従来は手牌を 愚形*1、好形*2、超好形*3 の3種、切る牌を 安全*4、危険*5 の2種に分類し、以下のパターンで押し引きを決定していた。
安全牌あり | 安全牌なし | |
---|---|---|
愚形 | ベタオリ(危険度最低の牌を切ってオリる) | 全押し(危険牌を切ってもよい) |
好形 | 回し打ち(安全牌なら切ってよい) | |
超好形 | 全押し(危険牌を切ってもよい) |
相対的危険度を使えば危険牌をさらに分類できるはずで、それにより上記パターンの 全押し について細分化できるのではないかと期待する。
安全牌の閾値
危険度を測る尺度が絶対危険度から相対危険度に変わったので、まずどこまでを安全牌とみなすべきか具体的な値で決定する必要がある。押し引きパターンを以下に簡略化し、安全牌とみなす 閾値A を 2.0 → 2.5 → 3.0 → 3.5 → 4.0 と変動させ*6、 先制リーチを受けた局の局収支で比較した。
安全牌あり | 安全牌なし | |
---|---|---|
愚形 | ベタオリ | |
好形 | 回し打ち | |
超好形 | 全押し |
1000半荘の デュプリケート対局 の結果は以下の通り。
結果 | 閾値A: 2.0 | 閾値A: 2.5 | 閾値A: 3.0 | 閾値A: 3.5 | 閾値A: 4.0 | |||||
---|---|---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.0% | +6812 | 10.1% | +6817 | 10.2% | +6858 | 10.4% | +6896 | 10.5% | +6887 |
放銃 | 10.2% | -6656 | 10.3% | -6656 | 10.5% | -6629 | 10.8% | -6636 | 11.2% | -6589 |
被ツモ | 31.8% | -2738 | 31.7% | -2739 | 31.7% | -2745 | 31.5% | -2757 | 31.3% | -2762 |
横移動 | 29.3% | -67 | 29.3% | -67 | 29.3% | -69 | 29.2% | -71 | 29.0% | -71 |
流局 | 18.7% | -770 | 18.5% | -762 | 18.4% | -753 | 18.2% | -749 | 17.9% | -747 |
平均 | -1033 | -1030 | -1021 | -1023 | -1031 |
これにより 危険度 3.0 未満を安全牌とみなす ことにした。
続いて閾値Aを 3.0 に固定した上で以下のように安全牌なしなら全押しとするのだが、このとき安全牌なしとみなす 閾値B を 3.0 → 3.5 と変動させてみた。
安全牌あり | 安全牌なし | |
---|---|---|
愚形 | ベタオリ | 全押し |
好形 | 回し打ち | 全押し |
超好形 | 全押し |
1000半荘のデュプリケート対局の結果は以下の通り。
結果 | 閾値B: 3.0 | 閾値B: 3.5 | ||
---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.6% | +6820 | 10.4% | +6806 |
放銃 | 10.8% | -6479 | 10.7% | -6570 |
被ツモ | 31.6% | -2752 | 31.5% | -2748 |
横移動 | 28.9% | -71 | 29.1% | -70 |
流局 | 18.2% | -734 | 18.3% | -751 |
平均 | -1002 | -1017 |
閾値AとBは一致させた方がよいようなので、危険度 3.0 の牌がない場合は全押し することとした。
全押し上限の閾値
次に危険牌を細分化する。まずは全押しのケースでも押してはいけない 超危険牌 となる 閾値C を定めたい。通っていないスジが残り4本で待ちがこの両面の8種に限られたとすると危険度は 1 / 8 = 12.5% となるので、このあたりを中心に閾値Cを変動させてみた。
結果 | 閾値C: 11.0 | 閾値C: 11.5 | 閾値C: 12.0 | 閾値C: 12.5 | 閾値C: 13.0 | |||||
---|---|---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.3% | +6760 | 10.3% | +6770 | 10.4% | +6797 | 10.4% | +6805 | 10.4% | +6805 |
放銃 | 10.4% | -6460 | 10.4% | -6461 | 10.4% | -6457 | 10.5% | -6476 | 10.5% | -6476 |
被ツモ | 31.8% | -2749 | 31.8% | -2749 | 31.7% | -2747 | 31.6% | -2749 | 31.7% | -2749 |
横移動 | 29.0% | -69 | 28.9% | -69 | 28.9% | -69 | 28.9% | -70 | 28.9% | -70 |
流局 | 18.6% | -798 | 18.5% | -792 | 18.6% | -778 | 18.5% | -780 | 18.5% | -775 |
平均 | -1020 | -1015 | -1000 | -1002 | -1004 |
この結果から、危険度 12.0 以上の牌は全押しのケースでも切らない こととした。
押し上限の閾値
さらに、安全牌がないため全押しとしているケースについて、押してよい上限の 閾値D を探ってみる。通っていないスジが残り6本でその両面だけが危険牌とすると 1 / 12 = 8.33% なので、この近辺に解がありそうである。
結果 | 閾値D: 7.0 | 閾値D: 7.5 | 閾値D: 8.0 | 閾値D: 8.5 | 閾値D: 9.0 | |||||
---|---|---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.4% | +6814 | 10.4% | +6809 | 10.4% | +6799 | 10.4% | +6799 | 10.4% | +6799 |
放銃 | 10.4% | -6445 | 10.4% | -6456 | 10.4% | -6415 | 10.4% | -6440 | 10.4% | -6430 |
被ツモ | 31.7% | -2745 | 31.7% | -2745 | 31.7% | -2747 | 31.7% | -2746 | 31.7% | -2746 |
横移動 | 29.0% | -70 | 29.0% | -70 | 29.0% | -69 | 28.9% | -69 | 28.9% | -70 |
流局 | 18.5% | -781 | 18.5% | -782 | 18.5% | -781 | 18.5% | -779 | 18.6% | -780 |
平均 | -1001 | -1002 | -993 | -999 | -1000 |
(安全牌なしのため)押しのケースで危険度 8.0 以上の牌は切らない こととした。
続いて、愚形の押しのケースについて、押してよい上限値の 閾値E を探ったが、3.0 〜 8.0 までの間に適切な値がなかったため、このケースでも好形同様に 8.0 を上限とする。危険度 12.0 までは押すケースを 全押し、危険度 8.0 までは押すケースを 押し とすると、以下の表になる。
安全牌あり | 安全牌なし | |
---|---|---|
愚形 | ベタオリ | 押し |
好形 | 回し打ち | 押し |
超好形 | 全押し |
愚形テンパイ押し上限の閾値
最後に愚形テンパイ時の押しに関して上限とする 閾値F を探ってみる。8.0〜12.0 を探ってみたが、最良なのは 12.0 であった。愚形テンパイでも全押しがよいようである。ならば、形式テンパイ(評価値 0 のテンパイ)の上限の 閾値G は?ということで 4.5〜12.0 で試したが、最良はやはり 12.0 であった。ノー聴罰の収支まで含めると、テンパイ後は全押しした方がよいようだ。
結論として押し引き表は以下となった。
安全牌あり | 安全牌なし | ||
---|---|---|---|
愚形 | (3シャンテン以前か評価値400未満) | ベタオリ (最も安全な牌を切る) | 押し (危険度8.0以上は切らない) |
好形 | (評価値400以上〜1200未満) | 回し打ち (危険度3.0以上は切らない) | |
超好形 | (評価値1200以上かテンパイ) | 全押し (危険度12.0以上は切らない) |
プログラム修正
まず、相対危険度を計算し、最低の危険度とその牌を求める。
let anquan, min = Infinity; let weixian = this._suanpai.suan_weixian_all(this._shoupai._bingpai); // 相対危険度を計算し、それを取り出す関数を取得する。 if (weixian) { // リーチを受けている場合 for (let p of this.get_dapai()) { // 全ての可能な打牌について以下を実行 if (weixian(p) < min) { min = weixian(p); // 最低の危険度を min に、 anquan = p; // そのときの牌を anquan に設定する。 } } }
牌姿の評価値と牌の危険度で押し引き判断する。
if (anquan && weixian(p) > min) { // 危険度最低の牌以外を押す場合 if (12.0 <= weixian(p)) continue; // 危険度 12.0 以上は押さない if (n_xiangting > 2 || n_xiangting > 0 && ev < 400) { // 愚形 if (8.0 <= weixian(p)) continue; // 危険度 8.0 以上は押さない if (min < 3.0) continue; // 安全牌がある場合はベタオリ } else if (n_xiangting > 0 && ev < 1200) { // 好形 if (8.0 <= weixian(p)) continue; // 危険度 8.0 以上は押さない if (min < 3.0 && 3.0 <= weixian(p)) continue; // 安全牌があれば回し打ち } }
評価
今までの改善の結果は以下の通り。
結果 | 改善前 | 改善(1) | 改善(2) | 改善(3) | ||||
---|---|---|---|---|---|---|---|---|
割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | 割合 | 局収支 | |
和了 | 10.4% | +6848 | 10.7% | +6861 | 10.7% | +6854 | 10.4% | +6799 |
放銃 | 11.3% | -6554 | 11.2% | -6612 | 11.2% | -6609 | 10.4% | -6415 |
被ツモ | 31.5% | -2735 | 31.4% | -2749 | 31.4% | -2750 | 31.7% | -2747 |
横移動 | 28.5% | -69 | 28.6% | -69 | 28.6% | -70 | 29.0% | -69 |
流局 | 18.3% | -762 | 18.0% | -750 | 18.1% | -749 | 18.5% | -781 |
平均 | -1047 | -1027 | -1024 | -993 |
改善前 | 改善(1) | 改善(2) | 改善(3) | 改善前 | 改善(1) | 改善(2) | 改善(3) | ||
---|---|---|---|---|---|---|---|---|---|
対戦数 | 1,000 | 1,000 | 1,000 | 1,000 | 総局数 | 10,480 | 10,488 | 10,488 | 10,505 |
1位率 | .237 | .237 | .237 | .233 | 和了率 | .213 | .215 | .215 | .213 |
2位率 | .244 | .250 | .250 | .256 | 放銃率 | .133 | .133 | .132 | .128 |
3位率 | .248 | .244 | .244 | .247 | 立直率 | .231 | .233 | .233 | .233 |
4位率 | .271 | .269 | .269 | .264 | 副露率 | .342 | .342 | .342 | .342 |
平均順位 | 2.55 | 2.55 | 2.55 | 2.54 | 平均打点 | 5,622 | 5,626 | 5,625 | 5,607 |