热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

24点纸牌智力挑战:经典数学益智游戏

24点纸牌智力挑战是一款广受欢迎的经典数学益智游戏。玩家需要从一副扑克牌中随机抽取四张牌,通过加、减、乘、除等运算,在最短时间内计算出结果为24,最先达成目标的玩家获胜。游戏中,J、Q、K分别代表11、12、13,增加了游戏的复杂性和趣味性。

一、题目要求

24点游戏是经典的纸牌益智游戏

从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。

用户初始生命值为一给定值,初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。

1.程序风格良好(使用自定义注释模板)

2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。

3.所有成绩均可记录在TopList.txt文件中。

二、问题分析

    根据题目,我们可以用一个数组存储随机生成的四张牌。由于用户输入的表达式为前缀表达式,因此我们需要将其转化为后缀表达式进行计算。计算过程可以使用栈实现一个简单的计算器。而计时器的实现,我们可以使用简单方式获取开始时间和结束时间,控制二者之差进行时间控制。

三、调试

1.随机生成四张牌

 

 

 

 

2.表达式输入

四、测试

1.测试计算器功能

2.测试成绩录入文件功能

五、程序代码

#include
#include
#include 

#define MAX 100 
#define MCHAR 20

typedef struct CharStack                //字符栈 
{
    char data[MAX];
    int top;
}cStack;
 
typedef struct DoubleStack                //数据栈 
{
    int data[MAX];
    int top;
}dStack;

struct use        //用户的结构体
{
    char id[MCHAR];    //用户名称 
    int HP;        //生命值 
    int score;        //分数 
}user[MAX];

int unum;
void play();
int Isop(char );                //当前扫描元素优先级 
int Inop(char );                //栈顶元素优先级 
void Initc(cStack *);                //初始化字符栈 
int Pushc(cStack *,char);            //字符栈压栈 
char Gettopc(cStack *);                //返回栈顶元素 
char Popc(cStack *);                //出栈 
void Initd(dStack *);                //初始化数据栈              
int Pushd(dStack *,int);    //数据压栈
int Popd(dStack *);        //出栈 
void Trans(char*s1,char*s2);        //转化为后缀表达式 
int Calculate(char *s2);        //后缀表达式求值
void readTopfile();
void writeTopfile();
void grade(int t,int s); 

int main()
{
    readTopfile();
    srand((unsigned)time(NULL)); //随机数
    play();    
    return 0;
}

void play()
{
    int j=unum;
    int t=0,s=0;
    int a[4];
    int i; 
    int fun=0,choice=0;
    int start,end; 
    char s1[MAX];            //用于存储前缀表达式 
    char s2[MAX];            //用于存储转换后的表达式 
    printf("24点游戏欢迎您!\n\n"); 
    printf("请输入您的用户名:");
    scanf("%s",&user[j].id); 
    while(1)   //主界面    
    { 
        printf("请输入相应选项:1开始游戏,2结束游戏\n"); 
        scanf("%d",&fun); 
        printf("您的初始生命值为100,答错或超时减10,每答对1次记10分\n"); 
        while(fun==1) 
        {
            printf("您抽到的四张牌是:"); 
            for(i&#61;0;i<4;i&#43;&#43;) 
            { 
                a[i]&#61;rand()%13&#43;1; //获得随机数 
                if(a[i]&#61;&#61;1)
                    printf("A ");
                else if(a[i]&#61;&#61;11)
                    printf("J ");
                else if(a[i]&#61;&#61;12)
                    printf("Q ");
                else if(a[i]&#61;&#61;13)
                    printf("K ");
                else
                    printf("%d ",a[i]); 
            } 
            printf("您可以进行以下选择&#xff1a;1.作答  2.跳过\n");
            scanf("%d",&choice);
            while(choice&#61;&#61;1)
            { 
                printf("A&#61;1,J&#61;11,Q&#61;12,K&#61;13\n");
                printf("请在60秒内完成作答。");
                printf("请输入表达式:");
                start&#61;clock();
                scanf("%s",s1);
                Trans(s1,s2);                //处理字符串&#xff0c;并转化为后缀表达式,存放在s2中 
                printf("\n计算结果为: %d",Calculate(s2));        //后缀表达式求值
                printf("\n");
                end&#61;clock();
                if(Calculate(s2)!&#61;24)
                {
                    printf("您输入的表达式运算不正确&#xff01;\n"); 
                    t&#61;t&#43;1;
                    break; 
                }
                else
                {
                    if((end-start)>60000)
                    {
                        printf("您输入的表达式正确&#xff0c;不过很遗憾您已超时&#xff01;");
                        t&#61;t&#43;1;
                        break; 
                    }
                    else
                    {
                        printf("恭喜你&#xff0c;回答正确&#xff01;\n");
                        s&#61;s&#43;1;
                        break; 
                    }
                }
            }
            if(t&#61;&#61;10)
            {
                printf("您的生命值已为0&#xff0c;游戏结束&#xff01;");
                printf("您的成绩为&#xff1a;%d",s*10);
                break; 
            }
            else
            { 
                printf("您可以选择&#xff1a;1.继续游戏  2.结束游戏\n") ;
                scanf("%d",&fun);
                if(fun&#61;&#61;1)
                    continue;
                else
                {
                    grade(t,s);
                    printf("用户名&#xff1a;%s 生命值&#xff1a;%d 成绩&#xff1a;%d",user[j].id,user[j].HP,user[j].score);
                    break;    
                }
            } 
        }
        break; 
    } 
    printf("\n谢谢使用"); 
}

void grade(int t,int s)
{
    int j&#61;unum;
    user[j].HP&#61;100-t*10;
    user[j].score&#61;s*10;
    unum&#43;&#43;;
    writeTopfile();
}

void  readTopfile()
{
   FILE *fp;        //声明文件
   int i&#61;0;            //定义变量
   fp&#61;fopen("TopList.txt","r");        //打开存放记错单词文件库
   if(!fp)        //如果文件不存在
   {
       printf("\n打开文件TopList.txt失败!");

   }
  
   while(fscanf(fp,"%s %d %d ",user[i].id,&user[i].HP,&user[i].score)&#61;&#61;3)//读取下一个用户 
   {
       i&#43;&#43;;//计数器&#43;1
   }
   unum&#61;i;//记录用户总数
   fclose(fp);//关闭文件

}

//向用户文件写入用户信息的函数
void writeTopfile(){
       FILE *fp;//声明文件
       int i&#61;0;
       fp&#61;fopen("TopList.txt","w");//打开文件
       if(!fp)//如果文件存在
       {
               printf("\n打开文件TopList.txt失败!");
           }
           for(i&#61;0;i            {
        fprintf(fp,"\n%s    %d  %d ",user[i].id,user[i].HP,user[i].score);//fprintf&#xff08;可以从一个文件流中格式化写入数据&#xff09;
        }
           printf("\n");
           fclose(fp);//关闭文件
            
}

//初始化 
void Initc(cStack *s1)
{
    s1->top&#61;-1;
}
 
 //字符栈压栈 
 int Pushc(cStack *c1,char op)
 {
     if(c1->top      {
         c1->data[&#43;&#43;c1->top]&#61;op;
         return 1;
    }
    else return 0;
}
 
//GET栈顶元素 
char Gettopc(cStack *c1)
{
    return c1->data[c1->top];
}
 
//字符栈出栈 
char Popc(cStack *c1)
{
    return c1->data[c1->top--];
}
 
//初始化数据栈 
void Initd(dStack *d1)
{
    d1->top&#61;-1;
}
 
//数据栈压栈 
int Pushd(dStack *d1,int data)
{
    if(d1->top     {
        d1->data[&#43;&#43;d1->top]&#61;data;
        return 1;
    }
    else return 0;
}
 
//数据栈出栈 
int Popd(dStack *d1)
{
    return d1->data[d1->top--];
}
 
int Isop(char op)        //当前扫描运算符优先级
{
    switch(op)
    {
        case &#39;(&#39;: return 6;
        case &#39;&#43;&#39;: case &#39;-&#39;: return 2;
        case &#39;*&#39;: case &#39;/&#39;: return 4;
    }
}
int Inop(char op)        //当前扫描运算符优先级
{
    switch(op)
    {
        case &#39;(&#39;: return 1;
        case &#39;&#43;&#39;: case &#39;-&#39;: return 3;
        case &#39;*&#39;: case &#39;/&#39;: return 5;
    }
}
 
void Trans(char *s1,char *s2)
{
    int i&#61;0;
    int j&#61;0;
    int flag1&#61;-1;                //flag1为0表示上次输出为数字&#xff0c;flag1为1表示上次输出为字符
    int flag2&#61;-1;                 //flag2为0表示上次扫描为数字&#xff0c;flag为1表示上次扫描为运算符&#xff0c;用于区分数字后加空格
    cStack st1;                //暂放运算符 
    Initc(&st1);
    while(s1[i]!&#61;&#39;\0&#39;)
    {
        if(flag1&#61;&#61;0&&flag2&#61;&#61;1)        //若上次的输出为数字&#xff0c;上次循环扫描为字符&#xff0c;则表示该数字串结束&#xff0c;则在数字后加空格区分 
        {
            s2[j&#43;&#43;]&#61;&#39; &#39;;
            flag1&#61;1; 
        }
        if(s1[i]>&#61;&#39;0&#39;&&s1[i]<&#61;&#39;9&#39;)
        {
            s2[j&#43;&#43;]&#61;s1[i];
            flag2&#61;0;
            flag1&#61;0;
        }
        else if(s1[i]&#61;&#61;&#39;&#43;&#39;||s1[i]&#61;&#61;&#39;-&#39;||s1[i]&#61;&#61;&#39;*&#39;||s1[i]&#61;&#61;&#39;/&#39;||s1[i]&#61;&#61;&#39;(&#39;)
        {
            flag2&#61;1;
            if(st1.top<0||Isop(s1[i])>Inop(Gettopc(&st1)))
            {
                Pushc(&st1,s1[i]);
            }
            else
            {
                while(st1.top>&#61;0&&Isop(s1[i])                 {
                        s2[j&#43;&#43;]&#61;Popc(&st1);
                        flag1&#61;1;
                }
                if(st1.top<0||Isop(s1[i])>Inop(Gettopc(&st1)))            //当前字符优先级大于栈顶优先级或栈空时当前字符压入字符栈内 
                {
                    Pushc(&st1,s1[i]);
                }
                
            }
        }
        else if(s1[i]&#61;&#61;&#39;)&#39;)                 
        {
            flag2&#61;1;
            if(Gettopc(&st1)!&#61;&#39;(&#39;)        //若括号仅包含数字则没有输出运算符 
            {
                flag1&#61;1;
            }
            while(Gettopc(&st1)!&#61;&#39;(&#39;)
            {
                s2[j&#43;&#43;]&#61;Popc(&st1);
            }
            Popc(&st1);        //将&#39;(&#39;出栈 
        }
        i&#43;&#43;;
    }
    while(st1.top>&#61;0)        //将栈内剩余的运算符依次退栈输出 
    {
        s2[j&#43;&#43;]&#61;Popc(&st1);
    }
    s2[j]&#61;&#39;\0&#39;;
}
 
//表达式求值 
int Calculate(char *s1)
{
    int i&#61;0;
    int flag;                //char类型转换为int类型数据标记 
    int data1,data2;
    int sum;
    dStack ds1;
    Initd(&ds1);
    while(s1[i]!&#61;&#39;\0&#39;)
    {
        if(s1[i]&#61;&#61;&#39;&#43;&#39;||s1[i]&#61;&#61;&#39;-&#39;||s1[i]&#61;&#61;&#39;*&#39;||s1[i]&#61;&#61;&#39;/&#39;)            //若为运算符获取栈顶两个元素进行计算 
        {
            data1&#61;Popd(&ds1);
            data2&#61;Popd(&ds1);
            if(s1[i]&#61;&#61;&#39;&#43;&#39;) Pushd(&ds1,data2&#43;data1);
            else if(s1[i]&#61;&#61;&#39;-&#39;) Pushd(&ds1,data2-data1);
            else if(s1[i]&#61;&#61;&#39;*&#39;) Pushd(&ds1,data2*data1);
            else if(s1[i]&#61;&#61;&#39;/&#39;) Pushd(&ds1,data2/data1);
        }
        else
        {
            flag&#61;0;                    //初始化为0为整数部分标记&#xff0c;1为小数部分标记 
            sum&#61;0;
            int divider&#61;1;
            while(s1[i]!&#61;&#39; &#39;&&s1[i]!&#61;&#39;&#43;&#39;&&s1[i]!&#61;&#39;-&#39;&&s1[i]!&#61;&#39;*&#39;&&s1[i]!&#61;&#39;/&#39;)
            {
                if(flag&#61;&#61;0)
                    sum&#61;sum*10&#43;(int)(s1[i]-&#39;0&#39;);
                else
                {
                    divider&#61;divider*10;
                    sum&#61;sum&#43;((int)(s1[i]-&#39;0&#39;))/divider;
                }
                i&#43;&#43;;
            }
            if(s1[i]&#61;&#61;&#39;&#43;&#39;||s1[i]&#61;&#61;&#39;-&#39;||s1[i]&#61;&#61;&#39;*&#39;||s1[i]&#61;&#61;&#39;/&#39;) i--;//转化成功一个数据&#xff0c;若下个字符为运算符&#xff0c;则i--&#xff0c;回到当前运算的数据位置 
            Pushd(&ds1,sum);
        }
        i&#43;&#43;;        //i&#43;&#43;准备下一个字符的转换 
    }
     return Popd(&ds1);
}
 

六、运行结果


推荐阅读
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本文介绍如何利用栈数据结构在C++中判断字符串中的括号是否匹配。通过顺序栈和链栈两种方式实现,并详细解释了算法的核心思想和具体实现步骤。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文详细介绍了8051系列微控制器的中断系统,特别是C51编译器中interrupt和using关键字的作用及其使用方法。通过深入分析这两个关键字的功能,帮助开发者更好地理解和优化中断程序的设计。 ... [详细]
  • 本文详细解释了为什么在成功执行移动赋值操作后,对象的析构函数会被调用,并提供了代码示例和详细的分析。 ... [详细]
  • 本文探讨了符号三角形问题,该问题涉及由相同数量的“+”和“-”符号组成的三角形。通过递归回溯法,可以有效地搜索并计算符合条件的符号三角形的数量。 ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
author-avatar
手机用户2502929967
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有