胡牌高手
2017-03-17 13:24
78 查看
玩过麻将 龙虎榜的人应该很熟悉这个画面,一般三连庄之后,会有个小游戏。这个游戏叫胡牌高手,就是给你十三张牌,都是清一色的万子,筒子或者条子,找出胡的那几张牌。
我的电玩生涯中,有几个游戏一直陪伴着我,街霸,双截龙,拳皇,快打三和龙虎榜,也叫搓牌高手。其他的游戏起起落落,一段时间过去,都从各大游戏室里面消失,当然搓牌高手最后也不能幸免,但是它的时间跨度是其他游戏所不能比的。最早玩的游戏应该数名将,那个瘦的像芦材棒的选手是大家的最爱,那一招死的玩法是永远的经典,也是早期街机的著名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萬已经超过4张牌,不能加入%d 萬\n",i+1,i+1); continue; } data[i]++; if(is_hupai(data)==0) { printf("胡 %d 萬 \n",i+1); } else { printf("不胡 %d 萬 \n",i+1); } data[i]--; } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
输入
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 //九莲宝灯
相关文章推荐
- Eclipse3.0 无法运行tomcat项目? 高手帮忙 在线等答案
- 寂寞不归路-软件高手是这样练成的
- 由菜鸟晋升高手 电脑设置技巧十二则
- Java最简单的单链表(高手勿进)
- 一个LINUX高手写给初学者的话(转)
- 编程高手箴言----高手成长的六个阶段
- 一个计算机高手的成长--转载
- 高手进阶 学会做嵌入式Linux操作系统
- 大家好帮帮我啊病毒 来挑战有没有高手
- Java之美[从菜鸟到高手演变]之常见的几种排序算法-插入、选择、冒泡、快排、堆排等
- 从菜鸟到高手必读:全面了解系统进程
- 高手是怎样练成的(1)--《编程高手箴言》
- 如何成为Java高手
- Python中的对象和动态性 [菜鸟的理解,高手莫入]
- 高手指教
- 【高手技术贴之关于番茄家园的安装盘集成术】
- 给大家看看什么叫高手---97年的Mekka ’97 4K Intro世界编程大赛冠军作品
- 安卓高手应该精通那些内容
- 成为java高手的八大条件
- Android高手进阶教程【转】