相信大家在现实生活中都玩过纸牌游戏,今天带大家实现一下发纸牌并查看自己的牌是什么。(默认4个人玩纸牌游戏+没有大小王)至于更高级的人机对弈功能暂时就没办法讲解了,大家可以期待一手,不过,当前还是看看我们的老伙伴——纸牌游戏之发纸牌在程序中是如何实现的吧!
目录
1.发纸牌的大致流程
首先,像现实生活中一样,我们要先选择我们在发纸牌过程中的次序,然后由系统随机为我们发送纸牌,我们可以输入数字查看当前牌数时手中牌的具体情况,从而判断是否要重新开始(程序员给自己开个挂不过分吧😀)
2.发纸牌的实现思路
还记得我在猜数字游戏的实现中说过的一句话吗?没错,我们在写编程题或者小游戏代码时,最重要的就是理清实现思路——主体是什么?为了实现目的要创建哪些函数?函数的功能都是什么?只有当我们心中有了一个大体的框架,知道该做些什么时,我们才能更高效地编写代码,完成程序设计。
发纸牌的算法如下:
1.menu(提供游戏菜单,由玩家选择是否进行游戏:按“1”开始游戏,按“0”退出游戏,按其他则显示“选择错误,请重新选择”。)
2.game( )(进行游戏);
2.1选择我们在发纸牌过程中的次序;
2.2选择我们要查看时的纸牌数;
2.3SendCards(打印当前手中纸牌);
2.4根据是否满意当前纸牌,选择重新发牌,或者打印这轮所有牌;
3.本轮游戏结束,打印游戏菜单并再次询问玩家选择。
3.发纸牌的代码实现
我们在思考大体框架时不用过多在意具体函数的实现方法,可以先起个能表达其功能的函数名并把它放在需要的位置。(说白了就是先搞一个空壳函数占位置,等到大体框架调试完毕不再有问题后,再去实现这些空壳函数)大体框架代码如下:
#include<stdio.h>
int main()
{
int input,count=5;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}while(input);
return 0;
}
3.1menu函数的代码实现如下:
void menu()
{
printf("*****************************************\n");
printf("**********1.play 0.exit*************\n");
printf("*****************************************\n");
}
3.2game函数的代码如下:
void game(void)
{
int num,n,flag;
printf("请选择你想要的位序:");
scanf("%d",&num);
printf("请输入想要查看时的发牌张数:");
scanf("%d",&n);
SendCards(n);
Printcards(num , n);
printf("你是否放弃当前的牌?\n1.是 2.否");
scanf("%d",&flag);
if(flag == 2 && num != 13)
{
printf("你完整的牌如下");
SendCards(13);
Printcards(num , 13);
}
}
我在SendCards函数的最初实现中出现了些问题,因为上面代码中两次调用函数SendCards,第二次会把第一次的牌覆盖,导致完整的牌实际上是和第一次没有关系,即并不是接着第一次继续发的完整牌。
3.3错误SendCards函数代码如下:
void SendCards(int n)
{
int sign[4][13] = {0};//这里大家可以理解为用数组表示五十二张牌的状态——已发放或者未发放
int k,i,j;
int play1 = 0,play2 = 0,play3 = 0,play4 = 0;
for(k = 0;k < n * 4;)
{
i = rand() % 4;
j = rand() % 13;
if(sign[i][j] == 1)
continue;
else
{
if(k % 4 == 0)
{
Palyer1card[play1] = (char*)malloc(6);//malloc以字节为单位,即这里是申请6个字节
strcpy(Palyer1card[play1],str1[i]);
strcat(Palyer1card[play1],str2[j]);
sign[i][j] = 1;
k++;
play1++;
}
if(k % 4 == 1)
{
Palyer2card[play2] = (char*)malloc(6);
strcpy(Palyer2card[play2],str1[i]);
strcat(Palyer2card[play2],str2[j]);
sign[i][j] = 1;
k++;
play2++;
}
if(k % 4 == 2)
{
Palyer3card[play3] = (char*)malloc(6);
strcpy(Palyer3card[play3],str1[i]);
strcat(Palyer3card[play3],str2[j]);
sign[i][j] = 1;
k++;
play3++;
}
if(k % 4 == 3)
{
Palyer4card[play4] = (char*)malloc(6);
strcpy(Palyer4card[play4],str1[i]);
strcat(Palyer4card[play4],str2[j]);
sign[i][j] = 1;
k++;
play4++;
}
}
}
}
而为了避免导致覆盖,我把SendCards函数进行修改——把参数修改成为两个,一个是起始位置,一个是终止位置,从而使发纸牌能够根据我们需要发,且不会随意覆盖。
3.4SendCards函数代码如下:
void SendCards(int start,int end)//start是起始,也可以看作是提醒现在每个人手中的牌数,end是最终每个人发到的牌数
{
int sign[4][13] = {0};//这里大家可以理解为用数组表示五十二张牌的状态——已发放或者未发放
int k,i,j;
int play1 = start,play2 = start,play3 = start,play4 = start;
for(k = start * 4;k < end * 4;)
{
i = rand() % 4;
j = rand() % 13;
if(sign[i][j] == 1)
continue;
else
{
if(k % 4 == 0)
{
Palyer1card[play1] = (char*)malloc(6);//malloc以字节为单位,即这里是申请6个字节
strcpy(Palyer1card[play1],str1[i]);
strcat(Palyer1card[play1],str2[j]);
sign[i][j] = 1;
k++;
play1++;
}
if(k % 4 == 1)
{
Palyer2card[play2] = (char*)malloc(6);
strcpy(Palyer2card[play2],str1[i]);
strcat(Palyer2card[play2],str2[j]);
sign[i][j] = 1;
k++;
play2++;
}
if(k % 4 == 2)
{
Palyer3card[play3] = (char*)malloc(6);
strcpy(Palyer3card[play3],str1[i]);
strcat(Palyer3card[play3],str2[j]);
sign[i][j] = 1;
k++;
play3++;
}
if(k % 4 == 3)
{
Palyer4card[play4] = (char*)malloc(6);
strcpy(Palyer4card[play4],str1[i]);
strcat(Palyer4card[play4],str2[j]);
sign[i][j] = 1;
k++;
play4++;
}
}
}
}
3.5打印手中纸牌函数Printcards代码如下:
void Printcards(int num , int n)
{
int k;
if(num == 1)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer2card[k]);
printf("\n");
}
if(num == 2)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer3card[k]);
printf("\n");
}
if(num == 3)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer4card[k]);
printf("\n");
}
if(num == 0)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer1card[k]);
printf("\n");
}
}
3.6完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<malloc.h>
char*str1[4] = {"梅花","黑桃","红桃","方块"};
char*str2[13] = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};
char*Palyer1card[13];
char*Palyer2card[13];
char*Palyer3card[13];
char*Palyer4card[13];
void menu(void);
void game(void);
void SendCards(int start,int end);
void Printcards(int num , int n);
int main()
{
int input;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}while(input);
return 0;
}
void menu()
{
printf("*****************************************\n");
printf("**********1.play 0.exit*************\n");
printf("*****************************************\n");
}
void game(void)
{
int num,n,flag;
printf("请选择你想要的位序:");
scanf("%d",&num);
printf("请输入想要查看时的发牌张数:");
scanf("%d",&n);
SendCards(0,n);
Printcards(num , n);
system("pause");
system("cls");
printf("你是否放弃当前的牌?\n1.是 2.否\n");
scanf("%d",&flag);
if(flag == 2 && num != 13)
{
printf("你完整的牌如下\n");
SendCards(n,13);
Printcards(num , 13);
}
}
void SendCards(int start,int end)
{
int sign[4][13] = {0};//这里大家可以理解为用数组表示五十二张牌的状态——已发放或者未发放
int k,i,j;
int play1 = start,play2 = start,play3 = start,play4 = start;
for(k = start * 4;k < end * 4;)
{
i = rand() % 4;
j = rand() % 13;
if(sign[i][j] == 1)
continue;
else
{
if(k % 4 == 0)
{
Palyer1card[play1] = (char*)malloc(6);//malloc以字节为单位,即这里是申请6个字节
strcpy(Palyer1card[play1],str1[i]);
strcat(Palyer1card[play1],str2[j]);
sign[i][j] = 1;
k++;
play1++;
}
if(k % 4 == 1)
{
Palyer2card[play2] = (char*)malloc(6);
strcpy(Palyer2card[play2],str1[i]);
strcat(Palyer2card[play2],str2[j]);
sign[i][j] = 1;
k++;
play2++;
}
if(k % 4 == 2)
{
Palyer3card[play3] = (char*)malloc(6);
strcpy(Palyer3card[play3],str1[i]);
strcat(Palyer3card[play3],str2[j]);
sign[i][j] = 1;
k++;
play3++;
}
if(k % 4 == 3)
{
Palyer4card[play4] = (char*)malloc(6);
strcpy(Palyer4card[play4],str1[i]);
strcat(Palyer4card[play4],str2[j]);
sign[i][j] = 1;
k++;
play4++;
}
}
}
}
void Printcards(int num , int n)
{
int k;
if(num == 1)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer2card[k]);
printf("\n");
}
if(num == 2)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer3card[k]);
printf("\n");
}
if(num == 3)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer4card[k]);
printf("\n");
}
if(num == 0)
{
for(k=0;k<n;k++)
printf("%-10s",Palyer1card[k]);
printf("\n");
}
}
严格说,这里也是简易版(或者说变态版),因为我们能一直换牌,这样是不利于正常玩游戏的,至于具体如何修改,那就交给各位喽!