Header

首先这里不是用打表这种对于提高打牌技术没有实际意义的 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 63 4 5 5 6 73 4
└─────────┴───────────┴───┘

然而这样的表示对于处理没有什么助益,所以要把每一组编码成一个长度为9的array,对应每种花色 1~9 的牌每张出现的数量。

enc{9⎕IO1 ⋄ ((≢⌸⍵)@(⍵))⍺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 00 0 1 1 2 1 1 0 00 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 00 1 1 1 0 0 0 0 00 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 00 0 2 2 2 0 0 0 01 1 2 1 1 0 0 0 0
└─────────────────┴─────────────────┴─────────────────┘

这样似乎看不出来有什么,但 reshape 一下编码的结果就显而了。

      {3 3enc ⍵}¨(1 2 2 3 3 4)(3 3 4 4 5 5)(1 2 3 3 4 5)
┌─────┬─────┬─────┐
1 2 20 0 21 1 2
1 0 02 2 01 1 0
0 0 00 0 00 0 0
└─────┴─────┴─────┘

那么如果是 1 2 2 2 3 3 3 4 4 这样的呢

      +3 3enc 1 2 2 2 3 3 3 4 4
3 3 3

如果再复合刻子呢?

      ((3|),⊂)+3 3enc 1 1 1 1 2 2 3 3 4
┌─────┬─────┐
2 2 25 2 2
└─────┴─────┘

只要 mod 3 就可以了。

只是还有个小问題,比如 2 3 7 这样的特例,不过只要限定是连续的就行了。

      3 3enc 2 3 7
0 1 1
0 0 0
1 0 0

因此

Theorem: 对于听牌形中连续的 $0=3|\omega$ 组,可以用 APL function

{(⊃∧.=,)3|+3 3}

判断是否为完成的面子。