-
Notifications
You must be signed in to change notification settings - Fork 840
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7376597
commit a936908
Showing
11 changed files
with
1,814 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
由网友QQ 24431188 重写版本 | ||
|
||
一)查表法核心思想: | ||
1、名词解释:eye(将),字牌(feng、东南西北中发白),花色(万、筒、条、字牌) | ||
2、分而治之:检查手牌是否能胡是依次检查万、筒、条、字牌四种花色是否能组成胡牌的一部分。 | ||
3、单一花色要能满足胡牌的部分,则要么是3*n(不带将),要么是3*n+2(带将)。3*n中的3带表三张牌一样的刻子,或三张连续的牌如1筒2筒3筒。 | ||
4、判断是否满足胡牌的单一花色部分,需要根据是否有将,有几个赖子,查询不同的表。表内容表示表里的元素加上对应的赖子数量能组成3*n 或3*n+2。 | ||
赖子数是表名最后的数字,带有eye的表表示满足3*n+2,没有的表示满足3*n。 | ||
5、查表的key值,是直接根据1-9有几张牌就填几(赖子不算),如1-9万各一张,则key为111111111。如1万3张,9万2张,则key为300000002。 | ||
6、组合多种花色,判断是否能胡牌。将赖子分配给不同的花色,有若干种分配方式,只要有一种分配能让所有花色满足单一花色胡牌部分,则手牌能胡。 | ||
如:手上有3个赖子,可以分配万、筒、条各一张,也可以万、同、字牌各一张 | ||
7、根据是否有将、是否字牌分为4种表,每种表又根据赖子个数0-8分别建表,共36张表,具体如下: | ||
|
||
赖子个数 筒子万子索子表 字牌表 | ||
0 Table0 Table_Feng0 | ||
1 Table1 Table_Feng1 | ||
2 Table2 Table_Feng2 | ||
3 Table3 Table_Feng3 | ||
4 Table4 Table_Feng4 | ||
5 Table5 Table_Feng5 | ||
6 Table6 Table_Feng6 | ||
7 Table7 Table_Feng7 | ||
8 Table8 Table_Feng8 | ||
|
||
要单独分开字牌表是因为字牌是不能形成顺子的,东南西不是顺子。(但是有些地方的玩法,例如南昌,它是可是东南西组成顺子的。) | ||
|
||
步骤: | ||
1、统计手牌中鬼牌个数 ghostCount,将鬼牌从牌数据中去除. | ||
2、把手上的牌编码成一串数字比如:1筒2筒3筒3筒3筒3筒6筒7筒8筒2万3万3万3万4万 | ||
筒: 1,1,4,0,0,1,1,1,0 得出的数字为114001110 | ||
万: 0,1,3,1,0,0,0,0,0 得出的数字为13100000 | ||
3、查表检查单一种花色能否胡牌先查Table0; 如果不能胡,再根据手上鬼牌的个数查其它表。 | ||
4、当所有牌型都能胡,并且有且仅有一种牌型是3*n+2, 其它牌型为3*n. | ||
|
||
|
||
二) 表的产生 | ||
|
||
非字牌表的产生: | ||
1、穷举万字牌所有满足胡牌胡可能,将对应的牌型记录为数字,放入Table0中。 | ||
具体是每次加入一个刻子,顺子或是将(将只能加入一对),最多加入四组外带将牌。 | ||
2、将Table0中牌去掉一张,放入Table1中,表示去掉的牌用1张赖子代替。 | ||
3、将Table1中牌去掉一张,放入Table2中,表示去掉的牌用1张赖子代替。 | ||
4、将Table2中牌去掉一张,放入Table3中,表示去掉的牌用1张赖子代替。 | ||
5、将Table3中牌去掉一张,放入Table4中,表示去掉的牌用1张赖子代替。 | ||
6、将Table4中牌去掉一张,放入Table5中,表示去掉的牌用1张赖子代替。 | ||
7、将Table5中牌去掉一张,放入Table6中,表示去掉的牌用1张赖子代替。 | ||
8、将Table6中牌去掉一张,放入Table7中,表示去掉的牌用1张赖子代替。 | ||
9、将Table7中牌去掉一张,放入Table8中,表示去掉的牌用1张赖子代替。 | ||
|
||
只计算到8张牌,如果手上有超过8张牌,无论是什么牌都是胡牌的。 | ||
|
||
字牌表的产生: | ||
与非字牌表的产生方法相同,只是第一步中,不能加入顺子(除非麻将玩法字牌是能组成顺子的)。 | ||
|
||
三) 代码实现 | ||
1) 只有在没有表的情况下,才会生成每一张表。 | ||
2) 每张表生成以后,将会加载下来,并存放在内存中。 | ||
3) GenTable是个单例,这样可以节约内存。 | ||
|
||
使用方法: | ||
1) let hulogic = new HuLogic(); | ||
2) hulogic.checkHu(cardList,ongoingCard); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
|
||
const Card = require('../Models/Card'); | ||
const HuLogic = require('../Models/HuAlgorithm/HuLogic') | ||
const assert = require('assert'); | ||
|
||
|
||
describe('胡牌测试', function () { | ||
|
||
it('检查胡牌', function () { | ||
var testPaiList = | ||
[ | ||
["1万", "3万", "5万", "6万", "7万", "8筒", "8筒", "6筒", "6筒", "4筒", "4筒", "中", "中", "5筒"], | ||
["5万", "6万", "4万", "9筒", "9筒", "8筒", "1条", "6筒", "2条", "3条", "南", "南", "中", "7筒",],//7筒 | ||
["1万", "3万", "4万", "5万", "6万", "2筒", "3筒", "4筒", "5筒", "7筒", "南", "中", "中", "南"],//南 | ||
["1万", "3万", "4万", "5万", "6万", "2筒", "3筒", "4筒", "5筒", "7筒", "中", "中", "中", "8万"],//8万 | ||
["2筒", "4筒", "5筒", "6筒", "7筒", "2万", "4万", "5万", "7万", "8万", "8万", "中", "白", "3万"],//3万 | ||
|
||
["6筒", "6筒", "1条", "3条", "4条", "5条", "6条", "7条", "9条", "7万", "9万", "中", "白", "中"],//中 | ||
["3筒", "4筒", "5筒", "5筒", "6筒", "7筒", "3条", "4条", "8条", "8条", "3万", "5万", "白", "4万"],//4万 | ||
["9筒", "9筒", "6条", "7条", "8条", "3万", "3万", "4万", "6万", "7万", "7万", "7万", "白", "3万"],//3万 | ||
["1筒", "2筒", "3筒", "4筒", "5筒", "6筒", "2万", "5万", "7万", "8万", "中", "中", "白", "4万"],//4万 | ||
["2筒", "3筒", "4筒", "7筒", "8筒", "5条", "6条", "7条", "9条", "9条", "7万", "7万", "白", "中"],//中 | ||
|
||
["5筒", "1条", "2条", "3条", "6条", "7条", "8条", "6万", "7万", "7万", "8万", "9万", "白", "5万"],//5万 | ||
|
||
["白", "中", "中", "8条", "7条", "7条", "5条", "4条", "3条", "2条", "5万", "3万", "2万", "1万"],//1万 | ||
["中", "1条", "3条", "4条", "5条", "6条", "1万", "1万", "2万", "3万", "4万", "5万", "7万", "白"],//白 | ||
["白", "9条", "8条", "8条", "7条", "7条", "4条", "3条", "5筒", "4筒", "3筒", "2筒", "2筒", "4条"],//4条 | ||
|
||
["7万", "8万", "9万", "9条", "9条", "8条", "8条", "4筒", "3筒", "2筒", "1筒", "白", "白", "中"],//"中" | ||
["9万", "8万", "7万", "6万", "4万", "3万", "2万", "1万", "3条", "1条", "1条", "白", "白", "1条"],// | ||
|
||
["7万", "7万", "3万", "3万", "9条", "8条", "7条", "8筒", "7筒", "6筒", "5筒", "4筒", "中", "7万"],//"7万" | ||
["8万", "7万", "4万", "4万", "9条", "8条", "7条", "7筒", "5筒", "2筒", "2筒", "白", "中", "2筒"],//"2筒" | ||
|
||
["8万", "7万", "6万", "4万", "3万", "2万", "1万", "7筒", "6筒", "5筒", "3条", "3条", "中", "9万"],//"9万" | ||
|
||
|
||
["中", "中", "9条", "8条", "8条", "7条", "6条", "5条", "4条", "3条", "9筒", "7筒", "2筒", "8筒"],//"8筒" | ||
["白", "中", "9条", "8条", "7条", "6条", "9筒", "9筒", "7筒", "5筒", "4筒", "2筒", "3筒", "4条"]//"4条" | ||
]; | ||
|
||
var testHuResult = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]; | ||
for (let i = 0; i < testPaiList.length; i++) { | ||
let cardDisplayNameList = testPaiList[i]; | ||
|
||
let cardList = Card.CreateCardWithNameList(cardDisplayNameList, [31, 32, 33]); | ||
let huLogic = new HuLogic(); | ||
let isHu = huLogic.checkHu(cardList); | ||
assert(isHu == testHuResult[i]); | ||
|
||
} | ||
|
||
|
||
}) | ||
}) |
Oops, something went wrong.