[c语言]制作一个扑克牌小游戏

本文档描述了一个简单的扑克牌游戏的实现,包括洗牌、发牌和玩家对弈功能。游戏设有四个电脑玩家,每个玩家初始拥有13张牌,通过随机洗牌后进行分配。游戏过程中,玩家轮流出牌,若无法出牌则需等待下一轮。当所有玩家中有一方的牌出完,游戏结束,该玩家获胜。
摘要由CSDN通过智能技术生成

扑克牌游戏

一、问题阐述

实现一个简单的扑克牌游戏,可以洗牌、发牌,还有玩家打牌等功能,具体任务如下:

(1)一副扑克52张牌(去掉大小王),分别是A、2、3、4、5、6、7、8、9、10、J、Q、K,每种4张(不考虑花色);

(2)由电脑随机洗牌,并分成4份(4个电脑玩家),并设计出一个对弈函数,每家调用该函数实现自动出牌;出牌后,若所有下家都没有牌出,则当前这一家可以选择出其它牌。

二、流程图

 

三、设计思路 

(1)利用结构体定义扑克牌以及玩家

(2)通过random随机写洗牌函数

(3)基本代码完成玩家之间的对弈,再写出一个删除牌的函数

四、代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

struct Poker{   
    int num;
};
struct Poker allpoker[52];  //一整副牌 52张

struct poker{  //一个玩家13张牌 
    int cards[13];
};
struct poker player[4];  //设置玩家,一共四个玩家

void wash();  //洗牌函数
int seekmin(int cnt);  //找手牌中最小牌 
void remove(int minimum, int cn);  //移除出过的牌 
int judge(int inde);  //转到下一个玩家 
int seek(int o, int p);  //找到比上一家出的牌大的牌 
int search(int r[],int g);  //从比上一家出的牌大的牌里面找到最小的牌 

const char *face[] = {"2","3","4","5","6","7","8","9","10","J","Q","K","A"};  //牌面的设置( 0-12)

int main()
{
    printf("扑克牌游戏来啦!"); 
    wash();
    int index1[13];
    int index2[4];
    int m1, m2, m3=0, m4;
    int n=0;
    srand((unsigned)time(NULL));
    for(int k=0;k<52;k++)  //这个for循环一整个为发牌 
    {
        if(k%13==0)
        {
            for(int j=k, h=0;j<(k+13)&&h<13;j++,h++)
            {
                player[n].cards[h] = allpoker[j].num%13;  //通过对0-51取余13得到1-13,通过0-12去表达牌面 
            }
            printf("\n玩家%d:",k/13+1);
            index2[n] = (k/13+1);  //将玩家存起来 (0-3) 
            for(int m=0;m<13;m++)
            {
                printf("%s ",face[player[n].cards[m]]);  //手牌 
            }
            n++; //下一个玩家 
        }
    }
    printf("\n!!游戏开始!!\n");
    m1 = rand()%4;  //随机挑选一个玩家作为庄 
    printf("玩家%d先出牌:", index2[m1]);
    m2 = seekmin(m1);  //寻找庄主手中最小的牌 
    printf("%s \n",face[m2]);
    remove(m2, m1);  //移除这一张出过的牌 
    if(m1==3)
    {
        m1 = 0;  //如果m1=3的话,加1就变为了4 ,而储存玩家的数组中是0-3 。当m1=3时是玩家4,下一个玩家应为玩家1,所以判断m1是否为3 
    }
    else if(m1>=0&&m1<3)
    {
        m1++;  //如果m1!=3,则加一即可 
    }
    while(player[m1].cards[0]!=88)
    {
        m2 = seek(m2, m1);  //寻找比上一家出的牌大的牌,seek函数的返回值有两种,一种是返回玩家手中最小牌,二是没有找到比上一家大的牌返回-1 
        if(m2>=0)  //有比上一家大的牌,则进入这个if 
        {
            printf("玩家%d出牌:%s \n",index2[m1], face[m2]);
            m4 = m2;  //将m2保存起来,方便于下一家的使用,如果不存起来,下一次循环会改变m2的值 
            remove(m2, m1);  //移除这张出过的牌 
            m1 = judge(m1);  //转到下一家 
            m3 = 0;  //通过后面再了解这一步,这里是避免有玩家可以出牌但是却会进入要不起的判断 
            continue;  //当玩家出了牌,就跳回到循环头部,不要继续走下去 
        }
        else if(m2==-1)  //当m2返回值为-1,则是该玩家要不起 
        {
            printf("玩家%d要不起\n",index2[m1]);
            m2 = m4;  //这里就将上一个if里面的m4再给回m2,就可以用于找大于上家的牌,否则这里返回的m2是-1; 
            m1 = judge(m1);
            if(player[m1].cards[0]==88)  //判断是否有玩家已经出完了牌,如果出完直接跳出循环 
            {
                break;
            }
            m3++;
            if(m3%3==0)  //当有连续三个玩家要不起,就会回到出最大牌的那名玩家,但是每当可以%3的时候都会进入这里,所以上一个if里面要加m3=0,就是避免进入这个if 
            {
                m2 = seekmin(m1);  //寻找这名玩家手中最小牌 
                printf("玩家%d出牌:%s\n",index2[m1], face[m2]);
                remove(m2, m1);  //移除这张出过的牌 
                m1 = judge(m1);  //到下一个玩家 
                continue;  //回到循环头部 
            }
        }
    }
    printf("赢家是%d,恭喜他!!",index2[m1]);
    return 0;
}

void wash()
{
    int number;
    int count;
    srand((unsigned)time(NULL));
    for(int i=0;i<52;i++)  //得到一副牌 
    {
        allpoker[i].num = i;
    }
    for(int i=0;i<52;i++)  //打乱牌的顺序 
    {
        number = rand()%52;
        count = allpoker[number].num;
        allpoker[number].num = allpoker[i].num;
        allpoker[i].num = count; 
    }
}
int seekmin(int cnt)
{
    int min = player[cnt].cards[0];  //设置最小值 
    for(int k=1;k<13;k++)
    {
        if(min>player[cnt].cards[k]&&min!=88)
        {
            min = player[cnt].cards[k];
        }
    }
    return min;
}
void remove(int minimum, int cn)
{
    int l, x=0;
    for(int k=0;k<13;k++)
    {
        if((player[cn].cards[k])==minimum)
        {
            for(l=k;l<13;l++)
            {
                x=1;
                player[cn].cards[l] = player[cn].cards[l+1];  //通过将后一个数移到前一个数,从而达到移除的效果 
            }
            player[cn].cards[l-1] = 88;  //让最后一张牌的位置,也就是12这个位置为88 
        }
        if(x==1)
        break;
    }
}
int judge(int inde)  //利用switch语句转到下一个玩家 
{
    int num;
    switch(inde)
    {
        case 0:num=1;break;
        case 1:num=2;break;
        case 2:num=3;break;
        case 3:num=0;break;
    }
    return num;

int seek(int o, int p)
{
    int w=0, t[13], e[13], q;
    int result;
    for(int k=0;k<13;k++)
    {
        t[k] = player[p].cards[k];  //先将下一家的手牌存到这个数组中 
    }
    for(int i=0;i<13;i++)
    {
        if(t[i]>o&&t[i]!=88)  //判断这个玩家手牌中大于上一家的出的牌 
        {
            e[w] = t[i];  //将这些大的牌存到这个数组之中 
            w++;
        }
    }
    if(w!=0)  //若是有大的牌,那w肯定不为0 
    {
        q = search(e, w);  //进入到这个函数中去寻找这些大的牌里面的最小牌 
        return q;
    }
    else if(w==0)  //没有大的牌就返回-1 
    {
        return -1;
    }
}
int search(int r[],int g)  //用于寻找大的牌里面最小的牌 
{
    int min;
    min = r[0];
    for(int i=0;i<g;i++)
    {
        if(min>=r[i]&&r[i]!=88)
        {
            min = r[i];
        }
    }
    return min;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值