Poker time 2 (enhanced version) 北理乐学作业题

思路在代码注释内pwp
PS:个人做题记录,不是最优解,如有错误欢迎指正喵!

背景:两个人每人发3张牌(各从一副牌中),每张牌包括花色(红桃(Heart)>黑桃(Spade)>方块(Diamond)>梅花(Club))和大小(从小到大依次是:2-10、J、Q、K、A),胜负规则如下:同花顺(3张同花色的连牌,先比大小,再比花色后同)>炸弹(3张相同大小的牌)>连牌(3张不同花色的连牌)>对子(两张相同大小的牌)>单牌。例如,红桃QKA>黑桃QKA>梅花567>方块234>AAA(红桃、方块、梅花)>AAA(黑桃、方块、梅花)>JQK(红桃、红桃、方块)>JQK(黑桃、红桃、方块)>AA2(梅花黑桃梅花)>QQJ(红桃梅花方块)>JQA(红桃红桃红桃)。注:A23不算连牌。

输入:A的3张牌(未排序)和B的3张牌(未排序)。(参见用例)

输出:A的3张牌的排序后的输出和B的3张牌的排序后的输出,以及A和B谁获胜。(参见用例)

 测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. DA H2 C3↵
  2. H4 H3 DJ↵
以文本方式显示
  1. Winner is A!↵
  2. A: DA C3 H2↵
  3. B: DJ H4 H3↵
1秒64M0
测试用例 3以文本方式显示
  1. HA CA CB↵
  2. HQ CJ CQ↵
以文本方式显示
  1. Input Error!↵
1秒64M0
测试用例 4以文本方式显示
  1. HA CA CJ↵
  2. DA DK DK↵
以文本方式显示
  1. Input Error!↵
1秒64M0
测试用例 5以文本方式显示
  1. SA SJ SK↵
  2. SA SJ SK↵
以文本方式显示
  1. Draw!↵
  2. A: SA SK SJ↵
  3. B: SA SK SJ↵
1秒64M0
测试用例 8以文本方式显示
  1. D2 D4 D3↵
  2. HA DA CA ↵
以文本方式显示
  1. Winner is A!↵
  2. A: D4 D3 D2↵
  3. B: HA DA CA↵
1秒64M0
测试用例 11以文本方式显示
  1. H2 C2 D2↵
  2. CA DQ DK↵
以文本方式显示
  1. Winner is A!↵
  2. A: H2 D2 C2↵
  3. B: CA DK DQ↵
1秒64M0
测试用例 12以文本方式显示
  1. H10 D9 C8↵
  2. H3 S3 D3↵
以文本方式显示
  1. Winner is B!↵
  2. A: H10 D9 C8↵
  3. B: H3 S3 D3↵
1秒64M0
测试用例 13以文本方式显示
  1. H2 H3 D4↵
  2. HA DA CK↵
以文本方式显示
  1. Winner is A!↵
  2. A: D4 H3 H2↵
  3. B: HA DA CK↵
1秒64M0

 

#include<stdio.h>
#include<string.h>
int flower_key(char arr[]) //该函数与下个函数分别获取花色和数字(J Q K A当作数字)对应的值,便于计算 
{   //该函数传入的是player[]的形式 即二维数组内部的一维数组
	char flower[4]={'C','D','S','H'};
	for(int i=0;i<4;i++) if(arr[0]==flower[i]) return i+1;
	return 0;  //此时代表获取不到花色 证明花色输入错误 
}
int num_key(char arr[])
{	//该函数传入的是player[]的形式 即二维数组内部的一维数组
	char num[13][3]={"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
	for(int i=0;i<13;i++) if(strcmp(&arr[1],num[i])==0) return i+1;
	return 0; //此时代表获取不到数字 证明数字输入错误 
}
int check_input(char player[][4])
{
	for(int i=0;i<3;i++)//扫描输入的三张卡 
	{
		for(int m=i+1;m<3;m++) if(strcmp(player[i],player[m])==0) return 1;  //判断有无相同的两张 若有则输入错误 
		if(flower_key(player[i])==0 || num_key(player[i])==0) return 1; //是否能获取到花色和数字的对应的值,不能则输入错误 
	}
	return 0;   //若输入错误返回1,无误返回0 
}
int player_sort(char arr[][4]) //排序玩家的卡牌,采用冒泡排序法 
{
	char temp[4];
	for(int i=0;i<2;i++)
	{
		for(int m=0;m<2;m++)
		{
			if(num_key(arr[m])<num_key(arr[m+1])) //若数字小与后面一张 交换顺序 
			{
				strcpy(temp,arr[m+1]);
				strcpy(arr[m+1],arr[m]);
				strcpy(arr[m],temp);
			}
			else if(num_key(arr[m])==num_key(arr[m+1]))
			{
				if(flower_key(arr[m])<flower_key(arr[m+1])) //数字相同比较花色 
				{
					strcpy(temp,arr[m+1]);
					strcpy(arr[m+1],arr[m]);
					strcpy(arr[m],temp);
				}
			}
		}
	}
}
int get_key(char arr[][4])
{
	for(int i=0;i<2;i++)//判断是否为同花顺 循环比较元素 
	{
		if(flower_key(arr[i])!=flower_key(arr[i+1])) break; //若某一张花色与后面一张不同就跳出
		//若比到倒数第二张与最后一张发现仍相同,看数字是否满足顺子 
		if(i==1 && num_key(arr[0])-1==num_key(arr[1]) && num_key(arr[0])-2==num_key(arr[2]) && num_key(arr[0])>=3) return 5; 
	}
	for(int i=0;i<2;i++)//判断是否为炸弹 循环比较元素 
	{
		if(num_key(arr[i])!=num_key(arr[i+1])) break; //若某一张与后面那张数字不同就跳出 
		if(i==1) return 4; //比完倒数第二张与倒数第一张仍未跳出则是炸弹 
	}
	//判断是否为顺子 
	if(num_key(arr[0])-1==num_key(arr[1]) && num_key(arr[0])-2==num_key(arr[2]) && num_key(arr[0])>=3) return 3;
	//判断是否为对子 
	if(num_key(arr[0])==num_key(arr[1]) || num_key(arr[1])==num_key(arr[2])) return 2;
	return 1;//上面的情形都不是那就是单牌了 
}
int double_place(char arr[][4])//此函数在传入的玩家牌有对子时返回对子两张牌中排序后位于前面的那张的角标 
{
	if(num_key(arr[0])==num_key(arr[1]))  return 0;
	else return 1;
}
int who_win(char player1[][4],char player2[][4])
{
	int count=0;
	for(int i=0;i<3;i++) if(strcmp(player1[i],player2[i])==0) count++;//先判断俩人三张是否一样 过滤平局情况 
	if(count==3) return 2;//平局 返回2 
	int key1=get_key(player1),key2=get_key(player2);//key代表大小,同花顺、炸弹、连牌、对子、单牌分别为 5,4,3,2,1
	if(key1>key2) return 0; //key大的就是赢家,key相同在下面分情况比较 
	if(key1<key2) return 1;
	if(key1==key2 && key1==5)//都是同花顺 判断一下大小 
	{
		if(num_key(player1[0])>num_key(player2[0])) return 0; //数字大的是赢家
		if(num_key(player1[0])<num_key(player2[0])) return 1;
		if(flower_key(player1[0])>flower_key(player2[0])) return 0; //数字相同比花色 
		if(flower_key(player1[0])<flower_key(player2[0])) return 1;
	}
	if(key1==key2 && key1==4)//都是炸弹 判断一下大小 
	{
		if(num_key(player1[0])>num_key(player2[0])) return 0; //数字大的是赢家
		if(num_key(player1[0])<num_key(player2[0])) return 1;
		for(int i=0;i<3;i++)//数字相同从前到后逐个比花色 
		{
			if(flower_key(player1[i])>flower_key(player2[i])) return 0;
			if(flower_key(player1[i])<flower_key(player2[i])) return 1;
		}
	}
	if(key1==key2 && key1==3)//都是顺子 判断一下大小 
	{
		if(num_key(player1[0])>num_key(player2[0])) return 0; //数字大的是赢家
		if(num_key(player1[0])<num_key(player2[0])) return 1;
		for(int i=0;i<3;i++)//数字相同从前到后逐个比花色 
		{
			if(flower_key(player1[i])>flower_key(player2[i])) return 0;
			if(flower_key(player1[i])<flower_key(player2[i])) return 1;
		}
	}
	if(key1==key2 && key1==2)//都是对子 判断一下大小 
	{
		int place1=double_place(player1),place2=double_place(player2);
		if(num_key(player1[place1])>num_key(player2[place2])) return 0; //数字大的是赢家
		if(num_key(player1[place1])<num_key(player2[place2])) return 1;
		for(int i=0;i<2;i++)//数字相同从前到后逐个比花色 
		{
			if(flower_key(player1[place1+i])>flower_key(player2[place2+i])) return 0;
			if(flower_key(player1[place1+i])<flower_key(player2[place2+i])) return 1;
		}
	}
	for(int i=0;i<3;i++)	//下面判断单牌情形的大小 第一张比第一张 若相同 往后进行 
	{
		if(num_key(player1[i])>num_key(player2[i+1])) return 0; //数字大的赢 
		if(num_key(player1[i])<num_key(player2[i+1])) return 1;
		if(flower_key(player1[i])>flower_key(player2[i])) return 0;//数字相同看花色 
		if(flower_key(player1[i])<flower_key(player2[i])) return 1;
	}
}
int main()
{
	char player1[3][4],player2[3][4];  //采取二维数组的形式存储卡牌 第n行代表第几张 每一行代表的卡牌以字符串储存 
	scanf("%s %s %s",player1[0],player1[1],player1[2]);
	scanf("%s %s %s",player2[0],player2[1],player2[2]);
	if(check_input(player1) || check_input(player2)) //如果输入错误直接输出提示并结束 
	{
		printf("Input Error!\n");
		return 0;
	}
	player_sort(player1);player_sort(player2);//排序两个玩家的手牌
	switch(who_win(player1,player2)) //根据who_win函数的返回值判断谁赢并输出 
	{
		case 0: printf("Winner is A!\n");break;
		case 1: printf("Winner is B!\n");break;
		case 2: printf("Draw!\n");
	}
	printf("A:"); for(int i=0;i<3;i++) printf(" %s",player1[i]);printf("\n");//输出排序后的牌 
	printf("B:"); for(int i=0;i<3;i++) printf(" %s",player2[i]);printf("\n");
	return 0; 
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红茶Nauy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值