实现思想
使用结构体创建一个扑克的对象,对象中有扑克的值、花色,数量等属性。结构体中*_count属性是用来判断当前扑克值得的该花色是否被发出
typedef struct pokers
{
char *arr;//扑克值:2 3 4 5 6 7 8 9 T J Q K A W w,T代表10,W代表大王w代表小王
int R_count;//红桃和大小王的辅助判断
int B_count;//黑桃
int F_count;//方块
int H_count;//梅花
int count;
}pokers;
为保证发牌具有随机性,需要使用随机函数,故需要生成随机数的一个时间种子。
srand(time(NULL));
接下来就是初始化一副牌,num为生成的随机数值,color用来代表花色,sum用来统计已经发出去的牌的数量,flag用来判断每一次发牌是否有牌发出
char a[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A','W','w'};
int i,num,color,sum=0;
int flag;
//num:牌值,color:花色,sum:牌总数,flag:判断是否有牌发出去
//创建对象
struct pokers *poker=(struct pokers *)malloc(sizeof(pokers)*15);
for(i=0;i<15;i++)
{
poker[i].arr=malloc(sizeof(char));
*(poker[i].arr)=a[i];
poker[i].R_count=1;
poker[i].B_count=1;
poker[i].F_count=1;
poker[i].H_count=1;
poker[i].count=4;
}
接下来便是发牌,使用while(1){num=rand()%15;......}来实现,因为num是随机产生的,故需要条件进行判断该发什么牌。一共有两种情况。
首先是对对大王小王的发牌:
因为大小王均只有一张,故都只发一次,所以借助R_count来做控制保证只发一次;
num=rand()%15;
if(num==13&&poker[num].R_count==1)
{
printf("大王W ");
poker[num].R_count=0;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
if(sum>=54)
{
printf("------------牌已发完,请开始游戏-------------\n");
break;
}
continue;
}
if(num==14&&poker[num].R_count==1)
{
printf("小王w ");
poker[num].R_count=0;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
if(sum>=54)
{
printf("------------牌已发完,请开始游戏-------------\n");
break;
}
continue;
}
其次是其他的牌:
if(poker[num].count>0&&num<13)
{
//该牌还有,必须发出去一个花色
flag=1;//允许发牌
while(flag)
{
color=rand()%4+1;
//此处省略switch语句
}
使用switch--case语句来做4中花色的发牌选择,以红桃为例,
switch(color)
{
case 1:
if(poker[num].R_count)
{
if(num==10)
printf("红桃10 ");
else
printf("红桃%c ",*(poker[num].arr));
poker[num].R_count=0;
poker[num].count--;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
}
flag=0;//牌已成功发出或者该牌已不存在
break;
//省略其他case语句,大同小异,完整代码在文末给出
}
实现效果;
以上便是斗地主游戏的实现过程,以面向对象的思维来做实现,代码逻辑简单,但是过于冗杂,若是以面向过程的思想来实现,代码的空间复杂度和时间复杂度都会减小多,后期再进行修改优化。
下面附上完整代码;
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct pokers
{
char *arr;//牌值:2 3 4 5 6 7 8 9 T J Q K A W w,T代表10,W代表大王w代表小王
int R_count;//红桃和大小王的辅助判断
int B_count;//黑桃
int F_count;//方块
int H_count;//梅花
int count;
}pokers;
int main()
{
srand(time(NULL));
char a[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A','W','w'};
int i,num,color,sum=0;
int flag;
//num:牌值,color:花色,sum:牌总数,flag:判断是否有牌发出去
//创建对象
struct pokers *poker=(struct pokers *)malloc(sizeof(pokers)*15);
for(i=0;i<15;i++)
{
poker[i].arr=malloc(sizeof(char));
*(poker[i].arr)=a[i];
poker[i].R_count=1;
poker[i].B_count=1;
poker[i].F_count=1;
poker[i].H_count=1;
poker[i].count=4;
}
printf("---------------游戏已就绪----------------\n");
printf("player_1:\n");
//发牌
while(1)
{ //sleep(0.01);
num=rand()%15;
if(num==13&&poker[num].R_count==1)
{
printf("大王W ");
poker[num].R_count=0;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
if(sum>=54)
{
printf("------------牌已发完,请开始游戏-------------\n");
break;
}
continue;
}
if(num==14&&poker[num].R_count==1)
{
printf("小王w ");
poker[num].R_count=0;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
if(sum>=54)
{
printf("------------牌已发完,请开始游戏-------------\n");
break;
}
continue;
}
if(poker[num].count>0&&num<13)
{
//该牌还有,必须发出去一个花色
flag=1;//允许发牌
while(flag)
{
color=rand()%4+1;
switch(color)
{
case 1:
if(poker[num].R_count)
{
if(num==10)
printf("红桃10 ");
else
printf("红桃%c ",*(poker[num].arr));
poker[num].R_count=0;
poker[num].count--;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
}
flag=0;//牌已成功发出或者该牌已不存在
break;
case 2:
if(poker[num].B_count)
{
if(num==10)
printf("黑桃10 ");
else
printf("黑桃%c ",*(poker[num].arr));
poker[num].B_count=0;
poker[num].count--;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
}
flag=0;//牌已成功发出或者该牌已不存在
break;
case 3:
if(poker[num].F_count)
{
if(num==10)
printf("方块10 ");
else
printf("方块%c ",*(poker[num].arr));
poker[num].F_count=0;
poker[num].count--;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
}
flag=0;//牌已成功发出或者该牌已不存在
break;
case 4:
if(poker[num].H_count)
{
if(num==10)
printf("梅花10 ");
else
printf("梅花%c ",*(poker[num].arr));
poker[num].H_count=0;
poker[num].count--;
sum++;
if(sum%6==0)
printf("\n");
if(sum%17==0)
{
printf("\n");
(sum/17+1)<4?printf("player_%d:\n",sum/17+1):printf("底牌:\n");
}
}
flag=0;//牌已成功发出或者该牌已不存在
break;
}//switch->end
}//while(flag)->end
}//if->end
if(sum>=54)
{
printf("\n------------牌已发完,请开始游戏-------------\n");
//printf("\n");
break;
}
}//while(1)->end
}