模拟扑克牌洗牌发牌——续一

本文介绍了如何编写一个发牌函数,用于检测五张牌游戏中是否存在对子、三张/四张同级牌、同花和顺子。通过记牌器和临时数组实现复杂逻辑判断。

前面模拟了扑克牌洗牌发牌的程序,这一篇将解决更复杂一点的扑克牌问题。
编写程序,使发牌函数(deal)可以处理一把5张牌的扑克游戏,具体问题如下:

(1)判断是否包含对子
(2)判断是否包含三张同级的牌(比如3个J)
(3)判断是否包含四张同级的牌(比如4个J)
(4)判断是否是一个同花(五张牌的花色相同)
(5)判断五张牌是否是一个顺子

洗牌程序和之前的一样,这篇只分享发牌函数模块的程序。

第一步 先发五张牌

int plays = 5;//处理5张牌
int hand[2][5] = { 0 };
for (int play = 1; play <= plays; card++)
{
	for (int row = 0; row < SUITS; row++)
	{
		for (int col = 0; col < FACES; col++)
		{
			if (deck[row][col] == card)
			{
				//存放每张牌对应的花色和牌面值编号
				hand[0][card - 1] = row;
				hand[1][card - 1] = col;
			}
		}
	}
}

第二步 判断是否包含对子
思路:前三个问题根据牌面值进行判断,因此,定义一个记牌器(仅记录牌面值),将每张牌的牌面值存储在对应的记牌器位置中,对应的问题只根据记牌器中的数据进行判断即可。

int counter_face[FACES] = { 0 };//定义一个记牌器(仅记录牌面值)
for (int play = 1; play <= 5; play++)
{
	//hand[1][play]:一把牌中每张牌的牌面值对应的编号
	counter_face[hand[1][play - 1]]++;
}

//判断是否包含对子
for (int i = 1; i < FACES; i++)
{
	if (counter_face[i] == 2)
	{
		printf("有一对%s\n", face[i]);
	}		
}

第三步 判断是否包含三张同级的牌(比如3个J)

	//判断是否包含三张同级的牌(比如3个J)
	for (int i = 1; i < FACES; i++)
	{
		if (counter_face[i] == 3)
		{
			printf("有三张%s\n", face[i]);
		}
	}

第四步 判断是否包含四张同级的牌(比如4个J)

	//判断是否包含四张同级的牌(比如4个J)
	for (int i = 1; i < FACES; i++)
	{
		if (counter_face[i] == 4)
		{
			printf("有四张%s\n", face[i]);
		}
	}

第五步 判断是否是一个同花(五张牌的花色相同)
思路:这一问题只判断花色,因此定义一个记牌器,仅记录花色,将五张牌的花色数目存放在相应的记牌器中。

	int counter_suit[SUITS] = { 0 };//花色记牌器
	for (int play = 1; play <= plays; play++)
	{
		counter_suit[hand[0][play - 1]]++;
	}
	for (int i = 0; i < SUITS; i++)
	{
		if (counter_suit[i] == 5)
			printf("有五张%s", suit[i]);
	}

第六步 判断五张牌是否是一个顺子
思路:(1)将五张牌的牌面值存放到一个临时数组中;(2)将牌面值按从小到大排序;(3)判断是否是顺子(每前后两张牌进行一次比较,如果相差均为1则表明是顺子,但是当牌数过多时,程序比较复杂。在这一部分中,我假设是顺子,用变量flag=1表示,判断相邻的两张牌是否相差1,如果相差不为1时,flag=0,最终只要判断flag的值即可)

int arrtmp[5] = { 0 };//定义一个临时数组将五张牌的牌面值存储起来
for (int i = 0; i < plays; i++)
{
	arrtmp[i] = hand[1][i];
}
for (int i = 0; i < plays; i++)//将五张牌的牌面值按从小到大排序
{
	for (int j = 0; j < plays - 1 - i; j++)
	{
		if (arrtmp[j] > arrtmp[j + 1])
		{
			int tmp = arrtmp[j];
			arrtmp[j] = arrtmp[j + 1];
			arrtmp[j + 1] = tmp;
		}
	}
}
int flag = 1;//假设是顺子
for (int i = 0; i < plays - 1; i++)
{
	if (arrtmp[i + 1] != arrtmp[i] + 1)
	{
		flag = 0;
		break;//相邻两个相差不是1,则说明不是顺子,退出循环
	}
}
printf("\n%s\n", flag != 0 ? "是顺子!" : "不是顺子!");
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值