扑克牌游戏程序设计与测试

扑克牌游戏程序设计与测试

你好!此博客用于uestc学生计算机编程实验二:扑克牌游戏程序设计与测试参考!

实验目的

1.熟悉程序开发环境,熟悉程序的编辑、编译、连接和运行的过程。
2.掌握计算机综合程序设计过程,学习分析问题并将其用程序的方式进行转化。
3.学会综合运用编程语言中的各种知识完成程序设计。
4.掌握较复杂程序的编译调试。
5.掌握循环、函数调用、数组、指针等知识。
6.学习通过算法优化来降低程序运算量。

实验流程

1、编写函数newcard,利用随机数产生函数任意发出5张牌(不包括大王和小王),必须满足在一副牌里的花色和点数,也就是说花色只能是:“红heart、黑spade、梅club、方diamond”四种,点数只能为:1~13;需要设计全局数据结构存放这5张牌,要求尽可能简洁。
2、编写函数analyze,分析5张牌的情况,包括7种情况:同花顺flush(5张点数连续、花色相同的牌)、顺子straight(5张点数连续、花色不同的牌)、四炸four(有4张点数相同、花色不同的牌)、三拖二full_house(5张牌中有3张点数相同和1个对子)、三炸three(3张点数相同、花色不同的牌)、两对two_paires(有2个对子)、一对pair(有1个对子);分析结果以英文字符串存放,以字符指针返回。
3、编写测试函数:
a)调用newcard()发牌,调用analyze()分析,然后输出分析结果;
b)设计简单的交互,使程序运行时可以按输入多次运行或结束运行;
c)测试主函数能够测试到各种情况,包括小概率的同花顺等情况;
d)可设置多名玩家,给出每个玩家的分析结果;(选作)
e)可比较玩家牌的结果,按概率给出胜利情况(选作)

实验代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#pragma warning(disable:4996) 

 

struct POKER {

    int num; //
A:1 , J:11 , Q:12 , K:13

    int color;
//红3,方4,梅5,黑6

}s[52];//定义一个结构体存储52张扑克牌的点数和花色

 

void sort(int* a, int len);//声明排序函数sort(),功能:冒泡法,从小到大排序

void newcard();//声明发牌函数newcard(),功能:先对52张扑克牌进行洗牌操作,然后选取前五张扑克牌作为玩家的牌,因为已经进行了洗牌,所以,选取任意5张都是可以的

void analyze();//声明分析函数analyze(),功能:判断玩家手中的牌属于哪种组合方式(flush, straight,
four, full_house, three, two_pairs, pair, normal)

 

//定义全局变量

int i, num, color;

int flush = 0, straight = 0, four = 0, full_house = 0,
three = 0, two_pairs = 0, pair = 0, normal = 0;

int Num[5];

int Color[5];

char* result;

int add = 0;



int main()

{

    int k = 1;

    int K = 1;

    int
player_num;//该变量存储玩家数量

    char
choice;//该变量存储玩家是否继续游戏的选择

    memset(s, 0,
sizeof(struct POKER) * 52);//分配内存并初始化

   
srand((unsigned)time(NULL));//调用srand(time(NULL))是把当前的时间作为种子,是程序每次运行产生不同的随机数序列

 

 

    int times =
20000;//设置游戏总次数,可以用来测试主函数能够测试到各种情况

    for (int k =
1; k <= times; k++)

    {

 

       
printf("\nROUNDR%6d : ", k);//打印第k次游戏

       
printf("\n");

        printf("\n");

       
printf("Set the number of players:\n");

       
printf("\n");

       
scanf("%d", &player_num);//选择玩家数量,最多10人,最少1人

        int I =
i + add;

       
newcard();//进行洗牌操作,将52张牌随机打乱存储到s[52]中

 

        for (add
= 0; add < 5*player_num; add = add + 5)//由于s[52]是进行了洗牌操作了,所以将前五张发给玩家一,次五张发给玩家二,......

        {

 

           
printf("\n");

           
printf("\nPLAYER%6d : ", add/5+1);

 

            for
(i = 0; i < 5; i++)//打印第k次游戏的扑克牌组合(包括花色和点数)

            {

               
switch (s[i+add].num)

               
{

               
case 1:  printf("%4c",
'A'); break;

               
case 11: printf("%4c", 'J'); break;

               
case 12: printf("%4c", 'Q'); break;

               
case 13: printf("%4c", 'K'); break;

               
default: printf("%4d", s[i + add].num);

               
}

               
switch (s[i + add].color)

               
{

               
case 3: printf("%2c", 3); break;

               
case 4: printf("%2c", 4); break;

                case
5: printf("%2c", 5); break;

               
case 6: printf("%2c", 6); break;

               
default: printf(" ");

               
}

               
printf(" ");

            }

           
printf("\n");

 

            for
(i = 0; i < 5; i++)

            {

               
Num[i] = s[i + add].num;//把玩家的五张牌点数赋给数组Num[]

               
Color[i] = s[i + add].color;//把玩家的五张牌花色赋给数组Color[]

            }

           
printf("\n");

           
sort(Num, 5);//对点数和花色排序,点数排序用于分析顺子、对子

           
sort(Color, 5);//对点数和花色排序,花色排序用于分析同花

           
analyze();//分析玩家手中的牌属于哪种组合方式

           
printf("%10s", result);//打印玩家手牌的组合方式

           
printf("\n");

        }

       
printf("\n");

       
printf("\n");

       
printf("Would you like to play again?\n");

       
printf("\n");

       
printf("A.YES\n");

       
printf("B.NO\n");

       
printf("\n");

       
scanf("%d", &choice);//读取玩家的选择

        choice =
getchar(choice);//直接调用scanf输入时,\n也一并读入,会导致循环多运行一次,因此调用getchar去掉\n

        if
(choice == 'A')//若玩家选择再玩一次,则continue

            K++;

        if
(choice == 'B')//若玩家选择结束,则直接break跳出for循环

           
break;

    }

   
printf("\n");

//输出k次游戏后,各种组合方式出现的次数,由于flush出现次数太少,因此打印的是次数而不是概率

   
printf("\n");

   
printf("  flush   :%5d\n", flush);

   
printf(" straight :%5d\n", straight);

   
printf("  four    :%5d\n", four);

   
printf("full_house:%5d\n", full_house);

   
printf("  three   :%5d\n", three);

   
printf("two_pairs :%5d\n", two_pairs);

   
printf("  pair    :%5d\n", pair);

   
printf("  normal  :%5d\n", normal);

return 0;

}

 

//冒泡法从小到达排序

void sort(int* a, int len)

{

    int i = 0;

    int j;

    int t;

    for (i = 0;
i < len; i++)

    {

        for (j = 0; j < len - i - 1; j++)

        {

            if
(a[j] > a[j + 1])

            {

               
t = a[j];

               
a[j] = a[j + 1];

               
a[j + 1] = t;

            }

        }

    }

}

 

void newcard()

{

    int count =
0;

    //洗牌

    for (i = 0;
i < 52; i++)

    {

        s[i].num
= 0;//初始化结构体s,使得每次发牌之前都洗牌一次,如果不初始化,会导致后序生成的新牌无法覆盖旧牌,洗牌失败

    }

    while (count
< 52)

    {

        num =
rand() % 13 + 1;//随机产生1~13:代表A~K

        color =
rand() % 4 + 3;//随机产生3~6,其ASCⅡ码对应红3,方4,梅5,黑6

        int
flag_skip = 0, flag_end = 0;

        for (i =
0; i < 52; i++)

        {

            if
(s[i].num == num && s[i].color == color)//判断生成的牌是否已经在牌堆s[52]里出现过,若在,则跳出for循环,若不在,则将该牌任意放在牌堆的一个无牌的位置

            {

               
flag_skip = 1;

               
break;

            }

        }

        if
(flag_skip == 1)//生成的牌已经在牌堆s[52]里,跳出for循环,但继续进行while循环

        {

           
continue;

        }

        while
(1)

        {

            i =
rand() % 52;//重新随机生成牌堆s[52]的一个位置,判断该位置是否有牌,若无牌,则将生成的牌放入该位置

            if
(s[i].num == 0)

            {

               
s[i].num = num;

               
s[i].color = color;

               
count++;

               
break;

            }

            else

            {

               
continue;

            }

        }

    }

}

 

void analyze()

{

    if (((Num[0]
< Num[1]) && (Num[1] < Num[2]) && (Num[2] < Num[3])
&& (Num[3] < Num[4]) && ((Num[4] - Num[0]) == 4)) &&
(Color[0] == Color[4]))//判断是否是是flushu

    {

        result =
"flush";//将玩家牌的分析结果以字符串的形式存入result中

       
flush++;//统计flush出现次数

    }

    else

        if
((Num[0] < Num[1]) && (Num[1] < Num[2]) && (Num[2] <
Num[3]) && (Num[3] < Num[4]) && ((Num[4] - Num[0]) == 4)
&& (Color[0] != Color[4]))//判断是否是是straight

        {

           
result = "straight";

            straight++;

        }

        else

            if
(((Num[0] == Num[3]) && (Num[3] < Num[4])) || ((Num[1] == Num[4])
&& (Num[0] < Num[1])))//判断是否是是four

            {

               
result = "four";

               
four++;

            }

            else

               
if (((Num[0] == Num[2]) && (Num[2] < Num[3]) &&
(Num[3] == Num[4])) || ((Num[2] == Num[4]) && (Num[1] < Num[2])
&& (Num[0] == Num[1])))//判断是否是是full_house

               
{

                   
result = "full_house";

                
   full_house++;

               
}

                else

                   
if (((Num[0] == Num[2]) && (Num[2] < Num[3]) &&
(Num[3] < Num[4])) || ((Num[2] == Num[4]) && (Num[1] < Num[2])
&& (Num[0] < Num[1])) || ((Num[1] == Num[3]) && (Num[0] <
Num[1]) && (Num[3] < Num[4])))//判断是否是是three

                   
{

                       
result = "three";

                       
three++;

                   
}

                   
else

                       
if (((Num[0] == Num[1]) && (Num[1] < Num[2]) &&
(Num[2] == Num[3]) && (Num[3] < Num[4])) || ((Num[0] == Num[1])
&& (Num[1] < Num[2]) && (Num[2] < Num[3]) &&
(Num[3] == Num[4])) || ((Num[0] < Num[1]) && (Num[1] == Num[2])
&& (Num[2] < Num[3]) && (Num[3] == Num[4])))//判断是否是是two_pairs

                 
      {

                            result =
"two_pairs";

                            two_pairs++;

                       
}

                       
else

                            if (((Num[0] ==
Num[1]) && (Num[1] < Num[2]) && (Num[2] < Num[3])
&& (Num[3] < Num[4])) || ((Num[0] < Num[1]) && (Num[1] ==
Num[2]) && (Num[2] < Num[3]) && (Num[3] < Num[4])) ||
((Num[0] < Num[1]) && (Num[1] < Num[2]) && (Num[2] ==
Num[3]) && (Num[3] < Num[4]))  || ((Num[0] < Num[1]) && (Num[1]
< Num[2]) && (Num[2] < Num[3]) && (Num[3] == Num[4])))//判断是否是是pair

                            {

                                result =
"pair";

                                pair++;

                            }

                            else//若以上组合方式都不是,则为normal

                            {

                                result =
"normal";

                                normal++;

                            }

    return
result;//返回字符串指针

}



/***************

修改main函数,用于统计各种组合方式的概率:(统计200000次发牌)

int main()

{

    int k = 1;

    int K = 1;

    int
player_num;//该变量存储玩家数量

    char
choice;//该变量存储玩家是否继续游戏的选择

    memset(s, 0,
sizeof(struct POKER) * 52);//分配内存并初始化

   
srand((unsigned)time(NULL));//调用srand(time(NULL))是把当前的时间作为种子,是程序每次运行产生不同的随机数序列

 

 

    int times =
2000;//设置游戏总次数,可以用来测试主函数能够测试到各种情况

    for (int k =
1; k <= times; k++)

    {

       
printf("\nROUNDR%6d : ", k);//打印第k次游戏

       
newcard();//进行洗牌操作,将52张牌随机打乱存储到s[52]中

           
printf("\n");

           
printf("\nPLAYER%6d : ", add/5+1);

            for
(i = 0; i < 5; i++)//打印第k次游戏的扑克牌组合(包括花色和点数)

            {

               
switch (s[i].num)

               
{

               
case 1:  printf("%4c",
'A'); break;

               
case 11: printf("%4c", 'J'); break;

               
case 12: printf("%4c", 'Q'); break;

               
case 13: printf("%4c", 'K'); break;

               
default: printf("%4d", s[i].num);

               
}

               
switch (s[i].color)

               
{

               
case 3: printf("%2c", 3); break;

                case 4: printf("%2c", 4);
break;

               
case 5: printf("%2c", 5); break;

               
case 6: printf("%2c", 6); break;

               
default: printf(" ");

               
}

               
printf(" ");

            }

           
printf("\n");

            for
(i = 0; i < 5; i++)

            {

                Num[i] = s[i].num;//把玩家的五张牌点数赋给数组Num[]

               
Color[i] = s[i].color;//把玩家的五张牌花色赋给数组Color[]

            }

           
printf("\n");

           
sort(Num, 5);//对点数和花色排序,点数排序用于分析顺子、对子

           
sort(Color, 5);//对点数和花色排序,花色排序用于分析同花

            analyze();//分析玩家手中的牌属于哪种组合方式

           
printf("%10s", result);//打印玩家手牌的组合方式

           
printf("\n");

    }

   
printf("\n");

//输出k次游戏后,各种组合方式出现的次数,由于flush出现次数太少,因此打印的是次数而不是概率

   
printf("\n");

   
printf("  flush   :%5d\n", flush);

   
printf(" straight :%5d\n", straight);

   
printf("  four    :%5d\n", four);

   
printf("full_house:%5d\n", full_house);

   
printf("  three   :%5d\n", three);

    printf("two_pairs :%5d\n",
two_pairs);

   
printf("  pair    :%5d\n", pair);

   
printf("  normal  :%5d\n", normal);

return 0;

}



******/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值