麻雀の打牌選択アルゴリズム(1) - koba::blog、麻雀の打牌選択アルゴリズム(2) - koba::blog で待ち受けを広くする打牌はある程度選択できるようになったのだが、孤立牌の打牌に問題が残っていた。
例えば
の牌姿の場合、打 、 ともに の5種14枚の待ちとなるのだが、赤ドラかつ中張牌でくっつきの可能性が高い を打牌してしまう(評価が同じ場合手牌の右側から切るため)。
今回は牌の評価値を求めることで中張牌やドラを残すよう改善する。
牌の評価値は以下とした、
- 搭子となる枚数を評価値とする
- ドラの評価値は2倍とする
- 役牌の評価値は2倍とする
例えば の場合、搭子となり得るのは 1種3枚なので3点、かつ役牌なので2倍として6点となる(ドラの場合はさらに2倍して12点)。
の場合、、、、 の各4枚と の3枚で搭子となり得るので19点。さらに赤ドラでもあるので2倍して38点。
これにさらに残り枚数を考慮して牌の評価値を求めるメソッドをMajiang.SuanPai
に追加した。
Majiang.SuanPai.prototype.paijia = function(p) { function weight(s, n) { if (n < 1 || 9 < n) return 0; var rv = 1; for (var baopai of self._baopai) { if (s+n == Majiang.Shan.zhenbaopai(baopai)) rv *= 2; } return rv; } var self = this; var rv; var s = p[0], n = p[1]-0||5; if (s == 'z') { rv = this.paishu(s+n) * weight(s+n); } else { var left = (1 <= n-2) ? Math.min(this.paishu(s+(n-2)), this.paishu(s+(n-1))) : 0; var center = (1 <= n-1 && n+1 <= 9) ? Math.min(this.paishu(s+(n-1)), this.paishu(s+(n+1))) : 0; var right = (n+2 <= 9) ? Math.min(this.paishu(s+(n+1)), this.paishu(s+(n+2))) : 0; rv = left * weight(s, n-2) + Math.max(left, center) * weight(s, n-1) + this.paishu(s+n) * weight(s, n) + Math.max(center, right) * weight(s, n+1) + right * weight(s, n+2); } if (p[1] == '0') rv *= 2; if (p == 'z'+(this._zhuangfeng+1)) rv *= 2; if (p == 'z'+(this._menfeng+1)) rv *= 2; if (p.match(/^z[567]/)) rv *= 2; rv *= weight(s, n); return rv; }
ドラ 、 残り3枚、 残り2枚、 残り1枚、 残り4枚、 残り3枚の状況で を評価した場合、
- で有効な*1搭子ができる枚数(
left
)は 2 - で有効な搭子ができる枚数(
center
)は 2 - で有効な搭子ができる枚数(
right
)は 3
となる。
weight()
はドラによる重みづけで、上記の場合 weight('m', 6)
は 2、他はすべて 1 となるので評価値は、
- ( (2 x 1) + (2 x 1) + (1 x 1) + (3 x 2) + (3 x 1) ) x 2 x 1 = 24
となる。
この孤立牌評価機能を組み込んだアルゴリズムで前回同様1000戦自動対戦させた結果は以下の通り。
対戦数 | 1,000 | 総局数 | 9,631 |
---|---|---|---|
1位率 | .289 | 和了率 | .233 |
2位率 | .267 | 放銃率 | .158 |
3位率 | .230 | 立直率 | .446 |
4位率 | .214 | 副露率 | .000 |
平均順位 | 2.37 | 平均打点 | 7,097 |
和了役 | 出現回数 | 出現率 | 和了役 | 出現回数 | 出現率 | |
---|---|---|---|---|---|---|
ドラ | 1,049 | 46.81% | 翻牌 | 160 | 7.14% | |
赤ドラ | 1,094 | 48.82% | 平和 | 577 | 25.75% | |
裏ドラ | 935 | 41.72% | 断幺九 | 289 | 12.90% | |
立直 | 2,226 | 99.33% | 一盃口 | 90 | 4.02% | |
ダブル立直 | 3 | 0.13% | 三色同順 | 45 | 2.01% | |
一発 | 678 | 30.25% | 一気通貫 | 12 | 0.54% | |
門前清自摸和 | 575 | 25.66% | 七対子 | 168 | 7.50% |
立直率 43.7% → 44.6%、和了率 22.7% → 23.3%、放銃率 15.4% → 15.8%。中張牌を残すことで聴牌効率が上がったがその分放銃も増えた感じ。和了役ではドラの使用枚数が増え、断幺九も増えている。このため平均打点が 6,629 → 7.097 とアップした。平均順位も 2.45 → 2.37 と大幅に上昇したのでこの改良はうまくいったようである。このアルゴリズムを ver.0.4 に採用した。
今回の差分はこちら
*1:面子となり得るという意味