有趣的代码——发纸牌的实现
相信大家在现实生活中都玩过纸牌游戏,今天带大家实现一下发纸牌并查看自己的牌是什么。(默认4个人玩纸牌游戏+没有大小王)至于更高级的人机对弈功能暂时就没办法讲解了,大家可以期待一手,不过,当前还是看看我们的老伙伴——纸牌游戏之发纸牌在程序中是如何实现的吧!
目录
1.发纸牌的大致流程
2.发纸牌的实现思路
3.发纸牌的代码实现
3.2game函数的代码如下:
3.3错误SendCards函数代码如下:
3.4SendCards函数代码如下:
3.5打印手中纸牌函数Printcards代码如下:
3.6完整代码如下:
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");}
}
严格说,这里也是简易版(或者说变态版),因为我们能一直换牌,这样是不利于正常玩游戏的,至于具体如何修改,那就交给各位喽!