分享
 
 
 

胡牌判断函数

王朝厨房·作者佚名  2007-01-05
窄屏简体版  字體: |||超大  

胡牌判断函数

胡牌判断函数

[code]//----------------unt_mainwin.cpp---------------------------------------------------------

/*-----------------------------------------------------------------------------------------

*该函数判断手牌有没有胡牌,手牌的数量一定为[2,5,8,11,14]

*当手牌数量为14时,判断是否有特殊牌型的胡牌[十三么,七对,全不靠]

*当不存在以上牌型时,用递归算法判断是否存在一般的胡牌牌型

*

*作者:yutian(于恬)

*E_main:yution@126.com

*

*作者声明:本代码为学习时编写的代码,大家可以随意转贴及编译修改

*但不得用于商业用途和赌博,作者保留一切权力

*

*鸣谢:网友 shyworm(怕怕虫) E_mail:shyworm@sina.com

* CSDN ChinaUnix

*/

//-----------------------------------------------------------------------------------------------

int TWanJia::IsWin()

{

int i,dblpos,dblcount;

if(this->PaiCount==13) //先处理特殊牌型,七对、十三么及全不靠

{

if((this->PaiInHand[0]==this->PaiInHand[1])&(this->PaiInHand[2]==this->PaiInHand[3])

&(this->PaiInHand[4]==this->PaiInHand[5])&(this->PaiInHand[6]==this->PaiInHand[7])

&(this->PaiInHand[8]==this->PaiInHand[9])&(this->PaiInHand[10]==this->PaiInHand[11])

&(this->PaiInHand[12]==this->PaiInHand[13]))

return SevenDbl; //七对胡了

dblcount=0;

for(i=0;i<13;i++) //以下判断手牌中对子的数量及位置

{

if(this->PaiInHand[i]==this->PaiInHand[i+1])

{

dblcount++;

}

if(dblcount>1) break; //如果手牌中含有两个对子(或一个刻子)以上,只能胡基本牌型

}

if(dblcount==1) //有一个对子的十三张手牌,可能为十三么

{

/***********************************************

十三么牌型必须是么九牌和字牌组成的十四张牌,按牌的数值定义

手牌数组PaiInHand中,只要没有1~7,10~16,19~25这些值,

则可以断定,该数组为十三么

*/

int IsThirteen=1;

for(i=0;i<14;i++)

{

if(this->PaiInHand[i]>0&&this->PaiInHand[i]<8)

{

IsThirteen=0;

break;

}

else if(this->PaiInHand[i]>9&&this->PaiInHand[i]<17)

{

IsThirteen=0;

break;

}

else if(this->PaiInHand[i]>18&&this->PaiInHand[i]<26)

{

IsThirteen=0;

break;

}

}

if(IsThirteen) return ThirteenSmall;

} //end of 十三么

if(dblcount==0)//没有对子,可能是全不靠

{

/*-------------------------------------------

十三不靠牌型为万筒条三个花色的147,258,369加上字牌的七张牌共16张

的任意十四张组成的胡牌,147,258,369的花色可以为任意花色,但不能有两副

出现相同的序数,如一万,四万,一条,四条是不能组成胡牌的。

判定的算法是:

先确定所以序数牌(不是字牌)的个数;

如果序数牌个数大于9,则返回错误;

如果有吃牌的序列(存在两张牌可以吃掉另外一张牌),返回错误;

对于所有的序数牌,自第一个开始,分别与其后的所有牌值mod9得

到的值比较,如果存在相等,返回错误。

如果上面判断都通过,则为十三不靠

*/

int NoWordPos=14;

for(i=13;i>=0;i--)

{

if(this->PaiInHand[i]<=26)

{

NoWordPos=i;

break;

}

}

if(NoWordPos<=8) //如果非字牌有9个以上,肯定不能胡全不靠

{

int IsThirteenSingle=1;

for(i=0;i<NoWordPos;i++)

{

if((this->PaiInHand[i+1]<=(this->PaiInHand[i]+2))&(this->PaiInHand[i]%9==this->PaiInHand[i+1]%9))

{

IsThirteenSingle=0;

break;

}

}

if(IsThirteenSingle)

{

for(i=0;i<NoWordPos&IsThirteenSingle;i++)

{

for(int j=0;j<=NoWordPos;j++)

{

if(this->PaiInHand[i]==this->PaiInHand[j]%9)

{

IsThirteenSingle=0;

break;

}

}

}

}

if(IsThirteenSingle) return ThirteenSingle;

}

} //end of 不靠

}

int TempPai[33];

for(i=0;i<34;i++) TempPai=0;

for(i=0;i<14;i++)

{

TempPai[this->PaiInHand[i]]++;

}

if(HuPai(TempPai)) return GenaralWin;

return 0;

}

//-----------------------------------------------------------------------------------------------------------------

int Tfrm_mainwin::HuPai(int arr)

{

/*

以下代码参考了网友

shyworm(怕怕虫) E_mail:shyworm@sina.com

在csdn论坛发表的算法及源码,在此感谢

原来的算法中要对杠牌进行处理,但我设计的数据结构中,不需要对他们进行判断了,

故略去了一段代码

*/

static int Jiang=0; // 将牌标志,即牌型“三三三三二”中的“二”

if(!RemainPai(arr)) return 1; // 递归退出条件:如果没有剩牌,则和牌返回。

for(int i=1;!arr[i]&i<34;i++); // 找到有牌的地方,i就是当前牌, arr[i]是个数

// 3张组合(刻子)

if(arr[i]>=3) // 如果当前牌不少于3张

{

arr[i]-=3; // 减去3张牌

if(HuPai(arr)) return 1; // 如果剩余的牌组合成功,和牌

arr[i]+=3; // 取消3张组合

}

// 2张组合(将牌)

if(!Jiang&arr[i]>=2) // 如果之前没有将牌,且当前牌不少于2张

{

Jiang=1; // 设置将牌标志

arr[i]-=2; // 减去2张牌

if(HuPai(arr)) return 1; // 如果剩余的牌组合成功,和牌

arr[i]+=2; // 取消2张组合

Jiang=0; // 清除将牌标志

}

if(i>26) return 0; // “东南西北中发白”没有顺牌组合,不和

// 顺牌组合,注意是从前往后组合!

if(i%9!=7&i%9!=8&arr[i+1]&arr[i+2])// 排除数值为8和9的牌且如果后面有连续两张牌

{

arr[i]--;

arr[i+1]--;

arr[i+2]--; // 各牌数减1

if(HuPai(arr)) return 1; // 如果剩余的牌组合成功,和牌

arr[i]++;

arr[i+1]++;

arr[i+2]++; // 恢复各牌数

}

// 无法全部组合,不和!

return 0;

}

//----------------------------------------------------------------------------

// 检查剩余牌数

int Tfrm_mainwin::RemainPai(int arr)

{

int sum=0;

for(int i=0;i<34;i++)

sum+=arr[i];

return sum;

}

//----------------------------------------------------------------------------

[/code]

头文件

[code]

//-------------------玩家类及窗体的头文件(修改中)----------------------------------------

#ifndef unt_mainwinH

#define unt_mainwinH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Buttons.hpp>

#define SevenDbl 7 //七对

#define ThirteenSmall 13 //十三么

#define ThirteenSingle 14 //十三不靠

#define GenaralWin 15 //一般胡牌

//============================================

// 0 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 33 34 35

//============================================

//东风 南风 西风 北风 红中 发财 白板 花1 花2

//============================================

//---------------------------------------------------------------------------

struct SChiPai //吃牌的结构体,吃的牌为顺子,故记录首尾两张牌

{

int MinPai; //麻将牌值,吃牌中最小的牌

int MaxPai; //麻将牌值,吃牌中最大的牌

};

//---------------------------------------------------------------------------

struct SGangPai //杠牌的结构体

{

int Pai; //麻将牌值,取值范围为[0..33]

int MingAn;//数值为0或1,1代表为暗杠,0代表明杠

};

//---------------------------------------------------------------------------

class TWanJia

{

//__published:

private:

AnsiString PlayerID;

int FenShu; //玩家的分数,要和数据库保持一致

int MenFeng; //玩家的门风

SGangPai Gangpai[3]; //玩家手中杠的牌

SChiPai ChiPai[3]; //玩家手中吃的牌

int PengPai[3]; //玩家手中的碰牌

int HuaPai; //花牌的数量,算番时要用

int PaiInHand[13]; //玩家的手牌,除掉吃碰杠牌后手中的牌

//即其他玩家看不到的牌,最多为十四张

//其中,PaiInHand[13]在处理完成后,被赋值为-1

int PaiCount; //手牌的数量,取值为1,4,7,10,13

int NewPai; //新摸到或别人打的牌,在处理完成后,被赋值为-1

//如果NewPai为非负值,则必须处理掉一张牌或胡牌

public:

TWanJia(AnsiString PlayID,int fenzhi);

int SetMenFeng(int menfeng);

int SetFenShu(int fenshu);

int SetGangPai(int pai,int mingan);

int SetChiPai(int min,int max);

int SetPengPai(int pengpai);

int SetPaiInHand(int * paiarr);

int SetPaiCount(int count);

int GetMenFeng();

int GetFenShu();

SGangPai * GetGangPai();

int * GetPengPai();

SChiPai * GetChiPai();

int * GetPaiInHand();

int GetPaiCount();

int Buhua();

int ChiPaiWithTwoPai(int min,int max);

int PengPaiWithOneDbl(int pai);

int IsWin();

int SendThePaiToServer();

int RequireOnePai();

};

//---------------------------------------------------------------------------

class TMJZhuo

{

//__published:

private:

int QuanFen,Header,Tail;

int PaiQiang[143];

TWanJia Players[3];

public:

};

//----------------------------------------------------------------------------

class Tfrm_mainwin : public TForm

{

__published: // IDE-managed Components

TEdit *edt_paiInHand1;

TLabel *Label1;

TEdit *edt_GangPai1;

TLabel *Label2;

TLabel *Label3;

TLabel *Label4;

TEdit *edt_ChiPai11;

TEdit *edt_ChiPai12;

TEdit *edt_ChiPai21;

TEdit *edt_ChiPai22;

TEdit *edt_ChiPai31;

TEdit *edt_ChiPai32;

TEdit *edt_ChiPai41;

TEdit *edt_ChiPai42;

TEdit *edt_GangPai2;

TEdit *edt_GangPai3;

TEdit *edt_GangPai4;

TEdit *edt_GangPai11;

TEdit *edt_GangPai22;

TEdit *edt_GangPai33;

TEdit *edt_GangPai44;

TEdit *edt_PengPai1;

TEdit *edt_PengPai2;

TEdit *edt_PengPai3;

TEdit *edt_PengPai4;

TEdit *edt_paiInHand2;

TEdit *edt_paiInHand3;

TEdit *edt_paiInHand4;

TEdit *edt_paiInHand5;

TEdit *edt_paiInHand6;

TEdit *edt_paiInHand7;

TEdit *edt_paiInHand8;

TEdit *edt_paiInHand9;

TEdit *edt_paiInHand10;

TEdit *edt_paiInHand11;

TEdit *edt_paiInHand12;

TEdit *edt_paiInHand13;

TEdit *edt_paiInHand14;

TBitBtn *btn_IsWin;

void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

void __fastcall btn_IsWinClick(TObject *Sender);

void __fastcall FormCreate(TObject *Sender);

private: // User declarations

TWanJia * Player;

public: // User declarations

void SendDataToWanJia();

void DispWanJiaData();

__fastcall Tfrm_mainwin(TComponent* Owner);

int HuPai(int arr);

int RemainPai(int arr);

};

//---------------------------------------------------------------------------

extern PACKAGE Tfrm_mainwin *frm_mainwin;

//---------------------------------------------------------------------------

#endif

[/code]

敬请斧正,谢谢

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有