实现思想

使用结构体创建一个扑克的对象,对象中有扑克的值、花色,数量等属性。结构体中*_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
}

更多推荐

c语言实现斗地主