C语言 利用随机数的赢三张扑克游戏

扑克牌。使用一副去掉大小王的扑克牌,共52张牌。 2-4人, 可只支持固定人数,每人三张牌,比大小牌型,
由大到小分别为:。 
1)同花顺:花色相同的顺子,黑桃456.红桃A23.。 
(2)三张:三张点相同的牌,AAA. 222 
3)顺子,花色不完全相同的顺子,黑桃5红桃6方片7。 “ 
(4)同色:花色相同,非顺子,黑桃368, 方片945.。 
(5) 对子:对子:带有两张点相同的牌,223, 334. 
(6) 散排,三张牌不组成以上任何类型的牌。。 
牌点从大到小依次为,A. K、Q、J10.9.8.7.6、5.4.3.2.先比牌型,牌型靠前面的胜:同样牌型则比牌点大小。 
例如。 ” (1)甲,同色,乙:对子,甲胜(花色靠前的花色大)。 
(2甲,对223. 乙对子334.乙胜(对子大), 
3)甲, 对子885乙:对子884.甲胜(对子相等,单牌大), 
4)甲,散牌087.乙散牌094.乙胜(最大牌相等,第二大牌大)“ 
可以用规则复杂度高于上述要求的某种朴克牌打法完成扑克牌程序。
花色大小顺序:黑、红、方、梅

#include<stdlib.h>
#include<time.h>
#include <stdio.h>

//花色
typedef enum _HUASE
{
	MEIHUA = 0,
	FANGKUAI = 1,
	HONGTAO = 2,
	HEITAO = 3
}HUASE;

//牌型
typedef enum _PUKETYPE
{
	ZP = 0,		//杂牌
	DZ = 1,		//对子
	TH = 2,		//同花
	SZ = 3,		//顺子
	TN = 4,		//三张
	THS = 5		//同花顺
}PUKETYPE;

typedef struct _PUKE
{
	unsigned short num;
	HUASE huase;
}PUKE;

class person
{
private:
	PUKE p[3];
	PUKETYPE pukeType;
	void calcType()//计算牌力
	{
		if(p[0].num == p[1].num)
		{
			if(p[1].num == p[2].num)
				pukeType = TN;  //三张相同,三张
			else
				pukeType = DZ;	//两张相同,对子
		}
		else if(p[1].num == p[2].num) //两张相同,对子
			pukeType = DZ;
		else  //三张都不相同的情况,先比较是否顺子,再比较是否同花
		{
			//特例判定,不符合递减顺序的顺子
			if(p[0].num == 14 && p[1].num == 3 && p[2].num == 2)
			{
				if(p[0].huase != p[1].huase || p[1].huase != p[2].huase)
					pukeType = SZ;
				else
					pukeType = THS;
			}
			else if((p[0].num - p[1].num)==1 && (p[1].num - p[2].num)== 1) //如果递减排序
			{
				if(p[0].huase != p[1].huase || p[1].huase != p[2].huase)
					pukeType = SZ;
				else
					pukeType = THS;
			}
			else if(p[0].huase == p[1].huase && p[1].huase == p[2].huase) //如果花色相同为同花
			{
				pukeType = TH;
			}
			else 
				pukeType = ZP;
		}
		//
	}
public:
	person() {}
	~person() {}
	PUKETYPE GetPukeType() { return pukeType; }
	PUKE *GetPuke() { return p; }
	unsigned short GetDZ(PUKE &ZP)  //当牌力为对子时,获取对子牌点数,同时返回剩余的杂牌,便于比较
	{//因为牌已经排序,所以要么前两张相同,要么后两张相同
		if(p[0].num == p[1].num)
		{
			ZP = p[2];
			return p[0].num;
		}
		ZP = p[0];
		return p[1].num;
	}
	void SetPuke(PUKE pk[3]) 
	{ 
		for (int n = 0; n < 3; n++)
			p[n] = pk[n];
		//对三张牌进行从大到小排序
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 2; j++)
			{
				if (p[j].num < p[j + 1].num)
				{
					PUKE puke = p[j];
					p[j] = p[j + 1];
					p[j + 1] = puke;
				}
				//牌点数相同时,进行花色排序
				else if (p[j].num == p[j + 1].num)
				{
					if (p[j].huase < p[j + 1].huase)
					{
						PUKE puke = p[j];
						p[j] = p[j + 1];
						p[j + 1] = puke;
					}
				}
			}
		}
		//计算牌力
		calcType();
	}
	void ShowPukeType()
	{
		switch (pukeType)
		{
		case THS:
			printf("同花顺");
			break;
		case TN:
			printf("三张");
			break;
		case SZ:
			printf("顺子");
			break;
		case TH:
			printf("同花");
			break;
		case DZ:
			printf("对子");
			break;
		case ZP:
			printf("杂牌");
			break;
		}
	}
	void ShowPuke() 
	{
		for (int i = 0; i < 3; i++)
		{
			switch (p[i].huase)
			{
			case MEIHUA:
				printf("梅花");
				break;
			case FANGKUAI:
				printf("方块");
				break;
			case HONGTAO:
				printf("红桃");
				break;
			case HEITAO:
				printf("黑桃");
				break;
			}
			if (p[i].num >= 2 && p[i].num <= 10)
				printf("%d\t", p[i].num);
			else if (p[i].num == 11)
				printf("J\t");
			else if (p[i].num == 12)
				printf("Q\t");
			else if (p[i].num == 13)
				printf("K\t");
			else if (p[i].num == 14)
				printf("A\t");
			if (i < 2)
				printf(" ");
		}
	}
	bool operator > (person &ps)
	{
		//如果牌力不同,直接出结果
		if (pukeType > ps.GetPukeType())
			return true;
		//如果牌力相同,根据不同牌力进行比较
		else if (pukeType == ps.GetPukeType())
		{
			PUKE *puke = ps.GetPuke();
			switch (pukeType)
			{
			case THS:  //如果都是同花顺,则比较最大牌的大小
			case SZ:	//如果都是顺子,与同花顺的比较相同
				{
					if (p[0].num > puke[0].num) //先比较最大牌大小
						return true;
					else if (p[0].num > puke[0].num) //如果最大牌大小相同,比较最大牌花色(花色不可能相同)
						return p[0].huase > puke[0].huase;
				}
				break;
			case TN: //如果都是三张,则只需要比较牌大小,不可能相同
				return p[0].num > puke[0].num;
				break;
			case TH:	//如果都是同花,则先比较牌大小,当牌完全相同时,再比较最大牌花色
			case ZP:	//如果都是杂牌,与同花的比较相同
				{
					//逐张牌比较大小
					if(p[0].num != puke[0].num)
						return p[0].num > puke[0].num;
					else if(p[1].num != puke[1].num)
						return p[1].num > puke[1].num;
					else if(p[2].num != puke[2].num)
						return p[2].num > puke[2].num;
					else if (p[0].num > puke[0].num) //如果最大牌大小相同,比较最大牌花色(花色不可能相同)
						return p[0].huase > puke[0].huase;
				}
				break;
			case DZ:	//对子
				{
					PUKE ZP1,ZP2;
					unsigned short DZ1,DZ2;
					DZ1 = GetDZ(ZP1);
					DZ2 = ps.GetDZ(ZP2);
					if(DZ1 == DZ2) //如果对子相同,则比较杂牌
					{
						if(ZP1.num == ZP2.num) //如果杂牌点数相同,则比较花色
							return ZP1.huase > ZP2.huase;
						else
							return ZP1.num > ZP2.num;
					}
					else
						return DZ1 > DZ2;
				}
				break;
			}
		}
		return false;
	}
};

int main()
{
	while (true)
	{
		bool bUse[4][13] = { 0 };
		int n, i, m, num;
		HUASE hs;
		PUKE pk[3];
		printf("请输入玩游戏人数(2-4):");
		scanf_s("%d", &n);
		if(n>4 || n<2)
		{
			printf("游戏人数必须是2-4个,请重新输入\n");
			continue;
		}
		printf("\n");
		//
		person *ps = new person[n];
		srand((unsigned)time(NULL));
		for (i = 0; i < n; i++)
		{
			m = 0;
			while (m < 3)
			{
				hs = (HUASE)(rand() % 4);
				num = rand() % 13;
				if (!bUse[hs][num])
				{
					bUse[hs][num] = true;
					pk[m].huase = hs;
					pk[m].num = num + 2;
					m++;
				}
			}
			ps[i].SetPuke(pk);
		}
		int winpos = 0;
		for (i = 0; i < n; i++)
		{
			printf("%d号牌手的三张牌为: \t",i+1);
			ps[i].ShowPuke();
			printf("\t牌型为:");
			ps[i].ShowPukeType();
			printf("\n");
			if(i<n-1)
			{
				if(ps[i+1] > ps[winpos])
				{
					winpos = i+1;
				}
			}
		}
		printf("\n恭喜本局%d号牌手以 ",winpos+1);
		ps[winpos].ShowPukeType();
		printf(" 获胜!\n");
		//
		delete []ps;
		ps = NULL;
		printf("\n再来一局?(N键退出,其它键继续):");
		getchar();
		char ch;
		scanf_s("%c", &ch,1);	
		if (ch == 'N' || ch=='n')
			break;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值