玩过麻将 龙虎榜的人应该很熟悉这个画面,一般三连庄之后,会有个小游戏。这个游戏叫胡牌高手,就是给你十三张牌,都是清一色的万子,筒子或者条子,找出胡的那几张牌。
我的电玩生涯中,有几个游戏一直陪伴着我,街霸,双截龙,拳皇,快打三和龙虎榜,也叫搓牌高手。其他的游戏起起落落,一段时间过去,都从各大游戏室里面消失,当然搓牌高手最后也不能幸免,但是它的时间跨度是其他游戏所不能比的。最早玩的游戏应该数名将,那个瘦的像芦材棒的选手是大家的最爱,那一招死的玩法是永远的经典,也是早期街机的著名bug。当时,格斗技能不行,和电脑玩玩还凑和,和人玩,心理素质极不过关,后来混久了,慢慢习惯了,成了菜鸟专杀。至今记得在烟雾缭绕的游戏室里面,一叠铜币,偶尔叼根同学给的烟,全神贯注的操作着方向杆,狠狠的按下游戏键,那是有钱的时候,没钱的时候,只能在旁欣赏着别人的表演,一面揣摩着如果是自己在操作会如何如何。那是我人生最堕落的时光,也是我人生最快乐的时候。小学五年,初中三年,快乐的背后,也为我的未来生活留下不少问题,但是年少怎能不轻狂呢,过去要省视,重要的是活在当前
麻将的规则挺多,除去特殊的牌型如十三幺,七对子等等,n*AAA+m*ABC+DD 是万变不离其宗的胡牌牌型。这里不研究通用的麻将胡牌算法,它比较��嗦, 只考虑游戏里的这种情形。清一色的牌型。
选出一张备选的牌型进入牌局,凑成14张牌 ,对十四张牌进行分解,12张牌和对子2张对子。
对12张牌进行分解,将其分解为n*AAA+m*ABC的形式,如果分解成功,那么即为胡牌,否则失败。对于这十二张牌,每次从最左边的牌入手,该牌无非为顺子(ABC)或者刻(AAA),分别进行枚举,若匹配成功,将剩余的九张牌进行递归分解,方法同上。若失败则返回。
#include <stdio.h>
#define INPUT_SIZE 13
int input[INPUT_SIZE] = {2,3,4,4,4,4,5,6,7,7,8,8,9};
//int input[INPUT_SIZE] = {1,2,2,4,4,5,5,6,6,7,7,8,8};
//int input[INPUT_SIZE] = {1,1,1,2,3,4,5,6,7,8,9,9,9}; //九莲宝灯
int data[9] = {0};
void getdata(int *in,int *out)// 将输入数据转换为累加数据
{
int i;
for(i=0;i<INPUT_SIZE;i++) out[in[i]-1]++;
}
int markshunzi(int *dt,int i,int d)//顺子匹配,d=-1表示选择操作,1表示回滚
{
if(i>=7) return -1;
if(d==-1)
{
if(dt[i]==0||dt[i+1]==0||dt[i+2]==0) return -1;
}
dt[i]+=d;
dt[i+1]+=d;
dt[i+2]+=d;
return 0;
}
int markke(int *dt,int i,int d)//d的意义同上
{
dt[i] += 3*d;
if(dt[i]>=0&&dt[i]<=4) return 0;
dt[i] -= 3*d;
return -1;
}
int check3pattern(int *dt,int total) //进行顺子或者刻的搜索过程
{
int i,j ;
if(total==12) return 0;
for(i=0;i<9;i++)
{
if(dt[i]==0) continue;
if(markke(dt,i,-1)==0)
{
total+=3;
j = check3pattern(dt,total);
total-=3;
markke(dt,i,1);
if(j==0)
{
printf("%d,%d,%d \n",i+1,i+1,i+1);
return 0;
};
}
if(markshunzi(dt,i,-1)==0)
{
total+=3;
j =check3pattern(dt,total);
total-=3;
markshunzi(dt,i,1);
if(j==0)
{
printf("%d,%d,%d \n",i+1,i+2,i+3);
return 0;
}
}
if(j!=0) return -1;
}
return -1;
}
int is_hupai(int *dt)
{
int i,left = 0,rst; //对子的左边张数,对子的右边张数
for(i=0;i<9;i++) //是否为7对子
{
if(dt[i]%2!=0)
{
break;
}
}
if(i==9)
{
printf("七对子 \n");
return 0; //符合7对子牌型
}
for(i=0;i<9;i++)
{
if((dt[i]==2&&left%3==0)||dt[i]>2) //做一些剪枝
{
dt[i]-=2;
rst = check3pattern(dt,0);
dt[i]+=2;
if(rst==0)
{
printf("门对:%d,%d \n",i+1,i+1);
return 0;
}
}
left+=dt[i];
}
return -1;
}
void main()
{
int i;
getdata(input,data);
for(i=0;i<9;i++)
{
if(data[i]>=4)
{
printf("%d�f已经超过4张牌,不能加入%d �f\n",i+1,i+1);
continue;
}
data[i]++;
if(is_hupai(data)==0)
{
printf("胡 %d �f \n",i+1);
}
else
{
printf("不胡 %d �f \n",i+1);
}
data[i]--;
}
}
程序清单
输入
2,3,4,4,4,4,5,6,7,7,8,8,9
1,2,2,4,4,5,5,6,6,7,7,8,8
1,1,1,2,3,4,5,6,7,8,9,9,9 //九莲宝灯