首先这里不是用打表这种对于提高打牌技术没有实际意义的 baka 方法。
特殊型(国士,七对型)听牌先按下,字牌因为没有什么难度请读者自行作为课后作業。这里先只考慮由 1~9 的万,条,筒组成的牌形。
众所周知标准和牌形是由一对将+四面子组成的。听牌则有单骑,两面,嵌张。对于如下简单的情形的只要是稍会麻将的就能不难看出是听 2 5 筒的(请忽略最右的白牌)。
表示法
首先,根據花色拆为 (12366 索), (345566 万), (24 索) 三组。
我们要一个在 APL 中表示手牌的方法。假设己经有做了分组,那么如上圖的手牌就可以用一个 nested array 表示
⊢hand←(1 2 3 6 6)(3 4 5 5 6 7)(3 4)
┌─────────┬───────────┬───┐
│1 2 3 6 6│3 4 5 5 6 7│3 4│
└─────────┴───────────┴───┘
然而这样的表示对于处理没有什么助益,所以要把每一组编码成一个长度为9的array,对应每种花色 1~9 的牌每张出现的数量。
enc←{⍺←9⊣⎕IO←1 ⋄ ((⊢∘≢⌸⍵)@(∪⍵))⍺⍴0}
enc 1 2 3 6 6
1 1 1 0 0 2 0 0 0
enc¨hand
┌─────────────────┬─────────────────┬─────────────────┐
│1 1 1 0 0 2 0 0 0│0 0 1 1 2 1 1 0 0│0 0 1 1 0 0 0 0 0│
└─────────────────┴─────────────────┴─────────────────┘
己完成的面子
在上面所示的听牌中,人类可以一眼看出三组中 345 567 万是己完成的面子,那这「一眼」中发生了什么?
Lemma: 当(标准听牌形)听牌时, $0=3|\omega$ 的组必然都组成面子,且不包括听牌。
证明: 当一组中有牌不能组成面子时,亦不能和其他花色的组形成将或面子,故不能滿足手牌中同时只有一个听牌形,不为听牌。
那么,用什么样的方法可以判斷呢,人类做的是一个順子/刻子的解离。在 APL 里这样写就会很麻煩。
对于 $3=\omega$ , 1 2 3, 2 3 4, 4 5 6, 这样的順子在编码后的表示
enc¨(1 2 3)(2 3 4)(4 5 6)
┌─────────────────┬─────────────────┬─────────────────┐
│1 1 1 0 0 0 0 0 0│0 1 1 1 0 0 0 0 0│0 0 0 1 1 1 0 0 0│
└─────────────────┴─────────────────┴─────────────────┘
相信一部分读者己经发现規律了。
对于 $6=\omega$ 的复合刻子 1 2 2 3 3 4, 3 3 4 4 5 5, 1 2 3 3 4 5
enc¨(1 2 2 3 3 4)(3 3 4 4 5 5)(1 2 3 3 4 5)
┌─────────────────┬─────────────────┬─────────────────┐
│1 2 2 1 0 0 0 0 0│0 0 2 2 2 0 0 0 0│1 1 2 1 1 0 0 0 0│
└─────────────────┴─────────────────┴─────────────────┘
这样似乎看不出来有什么,但 reshape 一下编码的结果就显而了。
{3 3⍴enc ⍵}¨(1 2 2 3 3 4)(3 3 4 4 5 5)(1 2 3 3 4 5)
┌─────┬─────┬─────┐
│1 2 2│0 0 2│1 1 2│
│1 0 0│2 2 0│1 1 0│
│0 0 0│0 0 0│0 0 0│
└─────┴─────┴─────┘
那么如果是 1 2 2 2 3 3 3 4 4 这样的呢
+⌿3 3⍴enc 1 2 2 2 3 3 3 4 4
3 3 3
如果再复合刻子呢?
((⊂3∘|),⊂)+⌿3 3⍴enc 1 1 1 1 2 2 3 3 4
┌─────┬─────┐
│2 2 2│5 2 2│
└─────┴─────┘
只要 mod 3 就可以了。
只是还有个小问題,比如 2 3 7 这样的特例,不过只要限定是连续的就行了。
3 3⍴enc 2 3 7
0 1 1
0 0 0
1 0 0
因此
Theorem: 对于听牌形中连续的 $0=3|\omega$ 组,可以用 APL function
{(⊃∧.=,)3|+⌿3 3⍴⍵}
判断是否为完成的面子。