24点小游戏游戏

24点游戏是经典的纸牌益智游戏。
常见游戏规则: 从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
一:基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
二:提高要求:
1.用户初始生命值为一给定值(比如3),初始分数为0。
2.随机生成4个代表扑克牌牌面的数字或字母。
3.由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
a. 程序风格良好(使用自定义注释模板)
b.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
c.所有成绩均可记录在TopList.txt文件中。
三:算法设计
a.定义一个结构体,来存放两个数字和符号。
b.产生4个随机数进行运算,将能得出24的4个数和表达式放在数组f[i]里,将4个随机数输出,作为数据供用户计算。
c.用户输入表达式,用栈来实现。
d.判断表达式是否正确,判断结果是否为24。
e.正确则分数加一,错误则生命减一。
f.生命值小于0,则游戏结束。将分数存入Toplist.txt文件中。
四:流程图
在这里插入图片描述
五:源程序

#include <iostream.h>
#include<stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MaxSize 1000
    int card[MaxSize],flag;
    struct
    {
    int op1[MaxSize];//第一个数
    int    op2[MaxSize];//第二个数
    int    value[MaxSize];//两个数做运算的结果
    char op[MaxSize];//加减乘除
    }solu;
void Init(int n) //随机产生n个随机数
{
    int i;
    for (i=1;i<=n;++i)
    card[i]=rand()%13+1;
    }
void work(int f[],int k,int n)//判断 产生的随机数是否能通过加减乘除等于24
    {
    int i,j,temp[MaxSize],t;
    if (k==n)
    {
        if (f[1]==24) flag=1; //当得到的结果为24时退出
    }
    else 
    {
        for (i=1;i<=n-k+1;++i) //控制外部循环
            for (j=i+1;j<=n-k+1;++j)
            {
                if (flag==0)
                {
                    int p;t=1;
                    for (p=1;p<=n-k+1;++p)
                        if (p!=j&&p!=i)
                        {                            
                            temp[t]=f[p];
                            ++t;
                        }                    
                }
                if (flag==0)//两个数进行加法运算
                {
                    temp[t]=f[i]+f[j];
                    solu.op1[k]=f[i];solu.op2[k]=f[j];
                    solu.op[k]='+';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
                if (flag==0)//两个数进行减法运算
                {
                    temp[t]=f[i]-f[j];
                    solu.op1[k]=f[i];solu.op2[k]=f[j];
                    solu.op[k]='-';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
                if (flag==0)
                {
                    temp[t]=f[j]-f[i];
                    solu.op1[k]=f[j];solu.op2[k]=f[i];
                    solu.op[k]='-';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
                if (flag==0)  //两个数进行乘法运算
                {
                    temp[t]=f[i]*f[j];
                    solu.op1[k]=f[i];solu.op2[k]=f[j];
                    solu.op[k]='*';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
                if (f[j]!=0&&f[i]%f[j]==0&&flag==0)  //两个数进行除法运算
                {
                    temp[t]=f[i]/f[j];
                    solu.op1[k]=f[i];solu.op2[k]=f[j];
                    solu.op[k]='/';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
                if (f[i]!=0&&f[j]%f[i]==0&&flag==0)
                {
                    temp[t]=f[j]/f[i];
                    solu.op1[k]=f[j];solu.op2[k]=f[i];
                    solu.op[k]='/';solu.value[k]=temp[t];
                    work(temp,k+1,n);
                }
            }
    }
    }
void print(int n)  //将得出24的步骤列举出来

   {
    for (int i=1;i<=n-1;++i)
    {
        if (solu.op2[i]<0) cout<<"第"<<i<<"步 : "<<solu.op1[i]<<solu.op[i]<<'('<<solu.op2[i]<<")="<<solu.value[i]<<endl;
        else cout<<"第"<<i<<"步 : "<<solu.op1[i]<<solu.op[i]<<solu.op2[i]<<'='<<solu.value[i]<<endl;
    }
    }
    bool IsOperator(char ops)
    {
    if(ops == '+' || ops == '-' || ops == '*' || ops == '/' || ops == '^' || ops == '(' || ops == ')')
        return(true);
    else
        return(false);
    }
bool IsOperand(char ch) 
    {
    if ((ch >= '0') && (ch <= '13'))
        return true;
    else
        return false;
     }
int isok(char exp[])//判断输入的符号是否错误
   {
    char check;
    int error=0;
    int lb=0;
    int rb=0;
    for(int m=0;m < strlen(exp); m++)
    {
        check = exp[m];
        if(IsOperand(check))
        {
        }
        else if(IsOperator(check))
        {
            if(check == ')')
            {
                rb++;
                if(IsOperator(exp[m+1]) && (exp[m+1]=='+' || exp[m+1]=='-' || exp[m+1]=='*' 
                    || exp[m+1]=='/' || exp[m+1]=='^' || exp[m+1]==')')) //将表达式的符号存起来
                {
                    m++;
                    if(exp[m] == ')')   //遇见右括号 rb++
                        rb++;
                }
                else if(IsOperator(exp[m+1]))
                    error++;
            }
            else if(check == '(')//遇见左括号 lb++
            {
                lb++;
                if(IsOperator(exp[m+1]) && exp[m+1] =='(')
                {
                    m++;
                    lb++;
                }
                else if(IsOperator(exp[m+1]))
                    error++;
            }
            else
            {
                if(IsOperator(exp[m+1]) && exp[m+1] == '(')
                {
                    m++;
                    lb++;
                }
                else if(IsOperator(exp[m+1]))
                    error++;
            }
        }
        else
            error++;
    }
    if(error == 0 && lb==rb) //  当错误为零,左括号数等于右括号数
        return(1);  //返回为1
    else
        return(0);
    }
void trans(char *exp,char postexp[])

    {
    struct 
    {
        char data[MaxSize];
        int top;
    }op;
    int i=0;
    op.top=-1;
    while (*exp!='\0')
    {
        switch(*exp)
        {
        case '(':
            ++op.top;
            op.data[op.top]=*exp;
            ++exp;
            break;
        case ')':
            while (op.data[op.top]!='(')
            {
                postexp[i++]=op.data[op.top];
                --op.top;
            }
            --op.top;
            ++exp;
            break;
        case '+':
        case '-':
            while (op.top!=-1 && op.data[op.top]!='(')
            {
                postexp[i++]=op.data[op.top];
                --op.top;
            }
            ++op.top;
            op.data[op.top]=*exp;
            ++exp;
            break;
        case '*':
        case '/':
            while (op.data[op.top]=='*'||op.data[op.top]=='/')
            {
                postexp[i++]=op.data[op.top];
                --op.top;
            }
            ++op.top;
            op.data[op.top]=*exp;
            ++exp;
            break;
        case ' ':
            ++exp;
            break;
        default:
            while (*exp>='0' && *exp<='13')
            {
                postexp[i++]=*exp;
                ++exp;
            }
            postexp[i++]='#';
        }
    }
    while (op.top!=-1)
    {
        postexp[i++]=op.data[op.top];
        --op.top;
    }
    postexp[i]='\0';
    }
float cal(char *postexp)
    {
    struct
    {
        float data[MaxSize];
        int top;
    }st;
    float d,a,b,c;
    st.top=-1;
    while (*postexp!='\0')
    {
        switch (*postexp)
        {

        case '+':

            a=st.data[st.top];
            --st.top;
            b=st.data[st.top];
            --st.top;
            c=a+b;
            ++st.top;
            st.data[st.top]=c;
            break;
        case '-':
            a=st.data[st.top];
            --st.top;
            b=st.data[st.top];
            --st.top;
            c=b-a;
            ++st.top;
            st.data[st.top]=c;
            break;
        case '*':
            a=st.data[st.top];
            --st.top;
            b=st.data[st.top];
            --st.top;
            c=a*b;
            ++st.top;
            st.data[st.top]=c;
            break;
        case '/':
            a=st.data[st.top];
            --st.top;
            b=st.data[st.top];
            --st.top;
            if (a!=0)
            {
                c=b/a;
                ++st.top;
                st.data[st.top]=c;
            }
            else 
            {
                cout<<"除零错误!!"<<endl;
                exit(0);
            }
            break;
        default:
            d=0;
            while (*postexp>='0' && *postexp<='13')
            {
                d=10*d+*postexp-'0';
                ++postexp;
            }
            ++st.top;
            st.data[st.top]=d;
            break;
        }
        ++postexp;
    }
    return (st.data[st.top]);
    }

    int NumMatch(char *postexp)//用户输入表达式

    {

    int f[5]={0,0,0,0,0},i=1; //初始值为零
    while (*postexp!='\0')
    {
        switch (*postexp)
        {
        case '#':
            ++postexp;
            ++i;                
            break;
        case '+':
        case '-':
        case '*':
        case '/':
            ++postexp;
            break;
        default:
            if (i>=5) return 0;
            f[i]=f[i]*10+*postexp-'0';
            ++postexp;
            break;
        }
    }
    for (i=1;i<=4;++i)
        for (int j=i+1;j<=4;++j)
        {
            if (f[i]>f[j])
            {
                int temp=f[i];
                f[i]=f[j];
                f[j]=temp;                
            }
            if (card[i]>card[j])
            {

                int temp=card[i];
                card[i]=card[j];
                card[j]=temp;
            }
        }

        for (i=1;i<=4;++i) //将输入的表达式与已经计算好的表达式作比较  若相同表达式正确
            if (f[i]!=card[i]) return 0;
            return 1;
    }

    int main()

    {

    char exp[MaxSize],postexp[MaxSize],temp[MaxSize];
    int cardnum=4,HardLevel=2,Score=0,tt=1,life=3;//扑克牌的数量为4     分数为0   生命为3
    system("cls");//清屏
     cout<<"游戏正式开始"<<endl<<endl;
     while(tt!=0) //生命中为0时游戏结束
     {
     srand(time(NULL));    
     while (Score>=0) 
        {        
        flag=0;
        Init(cardnum);
        work(card,1,cardnum);
        while (flag==0) 
         {
            Init(cardnum);
             work(card,1,cardnum);
         }        

        cout<<"产生的随机数如下"<<endl;
        for (int i=1;i<=cardnum;++i) cout<<card[i]<<"   ";
        cout<<endl<<endl;
            cout<<"请输入表达式"<<endl;
        cin.getline(temp,MaxSize);
        int j=0;
        for (i=0;i < strlen(temp);++i)
            if (temp[i]!=' ')
            {
                exp[j]=temp[i];
                ++j;
            }
            exp[j]='\0';
            cout<<endl<<endl<<endl;
            if (isok(exp))
            {
                trans(exp,postexp);
                if (cal(postexp)==24&&NumMatch(postexp)) 
                {
                    cout<<"太棒了,完全正确!"<<endl;
                    ++Score;
                }
                else 
                {
                    cout<<"很遗憾,您的回答错误。"<<endl<<"这里有一种可行的算法:"<<endl;
                    print(cardnum);
                    --life;
                }
            }
            cout<<endl<<"您现在的得分为   "<<Score<<endl;
            cout<<endl<<"您现在的生命为   "<<life<<endl;
            cout<<endl<<"开始下一局 "<<endl;
         if (life<0) 
          {
        system("cls");
        cout<<"游戏结束"<<endl<<"你的成绩保存在TopList.txt文件里"<<endl;
        tt=0;
        break;
          }
      }
    }
     char *p="Toplist.txt";  //将你的成绩保存在TopList.txt文件里
     FILE *fp;
     fp=fopen("TopList.txt","a");
     fprintf(fp,"%d\n",Score);
     fclose(fp);
    return 0;
    }

六:调试测试
游戏开始

在这里插入图片描述
回答正确

在这里插入图片描述
回答错误
在这里插入图片描述
游戏结束
在这里插入图片描述
七:心得体会
1.通过这次的学习实践,了解了结构体的使用和其他基本功能的巩固,加深了我对C语言更深层的理解。
2.了解了数据结构栈的使用
3.了解了fopen()函数,文件使用方式由r,w,a,t,b,+六个字符拼成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值