棋牌(跑胡子)项目中的一道胡牌算法,折磨了一星期,还是没写出来。前后切换各种姿势,最终都无济于事,快崩溃了
技术太菜,实在折腾不出来,特来求救。
跑胡子游戏介绍,
百科。这里就不浪费大家时间看游戏规则了,我直接把胡牌规则简化出来:
1)数字 1、2、3、4、5、6、7、8、9、10 代表小牌,共10张;
2)数字11、12、13、14、15、16、17、18、19 、20 代表大牌,共10张;
3)玩家手牌是以上20个数字的随机组合,每个数字最多出现3次(实际是4张,因为我项目里已过滤,这里只需求3张),最少0次,总数量2~21张(在这个范围内 且 %3要么等于2,要么等于0,这个是跑胡子规则,不用纠结哈);
4)3个相邻数字 或 2 7 10(特殊) 或 12 17 20(特殊)可以组成 1组(俗称:吃),如1 2 3,4 5 6,2 7 10。小牌不能跟大牌组合(即需区分范围判断,要么属于1~10,要么属于11~20),像 9 10 11这种组合是不允许的;
5) 3个相同数字可以组成1组(俗称:碰),如1 1 1,3 3 3,12 12 12;
6) 3个相同点数的小牌跟大牌可以组成1组(俗称:绞),即组成 a a+10 a+10或 a a a+10 或 a a-10 a-10 或 a a 1-10形式,例如2 12 12或12 2 2。
7) 玩家卡牌数量%3等于0时,刚好3张一组,需全部拆尽;
8) 玩家卡牌数量%3等于2时,有且只有”一对"牌单独出来(即2张相同的牌作对),其他牌需按3张一组全部拆尽;
9) 玩家卡牌如果能按以上规则拆尽,则代表能胡牌,否则不能胡牌。
麻将的胡牌算法是满足 nAAA+mXYZ+DD 公式,但跑胡子更特殊一点,它有大小牌之分,还有2 7 10这种特殊组合,且DD(作对的牌) 不一定有。
示例卡牌1:
List<int> cardList = new List<int>(){ 1, 7, 8, 9, 4, 4, 15, 1, 2, 3, 11, 11, 13, 14, 15, 16, 17, 18, 19, 20 };
拆分完后运行结果:
示例卡牌2:
List<int> cardList = new List<int>(){ 8, 8, 9, 9, 10, 10, 1, 2, 3, 11, 12, 13, 17, 17, 15, 15, 7 };
拆分完后运行结果:
以上结果是我本地运行,虽然是正确结果,但代码兼容性差,只能胡特定格式的牌,代码我就不贴出来了(主要是不敢贴,写到自己都无法控制了)。
网上有一份前辈写的胡牌算法,是C写的,看不大懂,它里面还有算胡息,这个暂可忽略。大家可参考:https://github.com/yuanfengyun/qipai/blob/master/phzlib_c/hulib.c
先谢过,感激不尽!