思考
牌效率是什么
经营自己的手牌,以达成和牌为目标
我们的任何操作(切牌、碰、吃等)都是为了最终能够和牌服务的,也就是提高和了率。
在只考虑自摸的情况下,我们可以快速的计算出打哪张牌能够使向听数前进、有效牌和改良牌变多。
有效牌
能够减少向听数的牌
通过向听数的计算公式8-2*(面子数)-对子数-搭子数
,我们发现,能够减少向听数的牌有以下几
种:
- 能够与搭子组成一个顺子,此时面子数量+1,搭子数量-1,向听数+1
- 能够与对子组成一个刻子,此时面子数量+1,对子数量-1,向听数+1
- 能够与孤张组成一个对子,此时对子数量+1,向听数+1
- 能够与孤张组成一个搭子,此时搭子数量+1,向听数+1
这样一来就很清晰了,接下来我们来编码,计算以下两种情况
- 在向听数减少的情况下,打出哪张牌后的有效牌最多
- 在打出任何牌都不能导致向听数减少的情况下,打出哪张牌后的有效牌最多(也就是指改良)
编码
我们需要有个工具来记录当前玩家视角内牌的数量情况:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32/**
* 对局中牌出现数量的计数器
*/
public class PaiCounter {
private Map<Pai, AtomicInteger> paiCount = new HashMap<>();
public PaiCounter() {
Pai.ALL.forEach(p -> {
paiCount.put(p, new AtomicInteger(0));
});
}
public PaiCounter(Map<Pai, AtomicInteger> paiCount) {
this.paiCount = paiCount;
}
/**
* 查询当前玩家视角内某张牌已经出现的数量
* @param pai 需要查询的牌
* @return 数量
*/
public int getCount(Pai pai) {
return paiCount.computeIfAbsent(pai, p -> new AtomicInteger(0)).get();
}
/**
* 玩家新摸到、对手打出、或者吃碰杠等操作,导致当前玩家视角内出现新的牌,请调用此方法计数
*
* @param pai 新出现的牌
*/
public void addCount(Pai pai) {
paiCount.computeIfAbsent(pai, p -> new AtomicInteger(0)).incrementAndGet();
}
}
计算当前手牌打出哪张后的有效进张
1 | /** |
示例输出1
2
3
4
5
6
7
8
9
10
11
12
13
14
1534677m67p22577s27z
throw=2z total=30 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=7z total=30 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=7m total=28 {2m=4, 5m=4, 8m=4, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=7m total=28 {2m=4, 5m=4, 8m=4, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=2s total=28 {2m=4, 5m=4, 7m=2, 8m=4, 6s=4, 7s=2, 5p=4, 8p=4}
throw=2s total=28 {2m=4, 5m=4, 7m=2, 8m=4, 6s=4, 7s=2, 5p=4, 8p=4}
throw=7s total=28 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 5p=4, 8p=4}
throw=7s total=28 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 5p=4, 8p=4}
throw=4m total=26 {5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=6m total=26 {2m=4, 5m=4, 7m=2, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=5s total=26 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 7s=2, 5p=4, 8p=4}
throw=3m total=22 {5m=4, 7m=2, 2s=2, 6s=4, 7s=2, 5p=4, 8p=4}
throw=6p total=22 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 7s=2}
throw=7p total=22 {2m=4, 5m=4, 7m=2, 8m=4, 2s=2, 6s=4, 7s=2}
天凤牌理
我们用天凤牌理来验证一下我们的程序是否正确
跟我们程序的输出是不一致的,其实是因为天凤牌理并没有计算我们上面列出的3、4两种情况
- 能够与孤张组成一个对子,此时对子数量+1,向听数+1
- 能够与孤张组成一个搭子,此时搭子数量+1,向听数+1
如果我们在代码中把孤张相关的判断去掉,程序的输出就和天凤牌理一样了。
接下来的内容
下一章会讲符数与役种的计算