24点卡牌游戏C++实现

问题描述:
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。

算法分析

一、采用srand()和rand()配合使用随机生成1~13之间的四个数字,分别为a,b,c,d将4个整数放入数组num[ ]中

二、 在字符数组中存入 +– * / – -/运算符,分别对应flag的0,1,3,4,5。因为除法和减法不存在交换律,所以定义了反除和反减。

三、将用户输入的4个数字与4个运算符进行穷举组合排列,以构成多种不同的表达式,计算每一种表达式的值。

四、若表达式计算结果为24,则输入该表达式,程序运行结果输出所有可能性的排列组合

程序代码

//	+	-	*	/	--	-/
//	0	1	2	3	4	5
#include <iostream>
#include<stdio.h>
#include<math.h>
#include <cstdlib>
#include <ctime>
using namespace std;
#define random(a,b) (rand() % (b-a+1))+ a  //random的宏定义,便于rand()的计算
int calculate(float a,float b,float c,float d);  //24点计算函数
float myF(int flag,float m,float n);
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d);

int temp=0;
int main()
{
	int i,j,k,t,again,res,flag;
	float num[4]; //用于存放四个数字
    srand((int)time(0));  // 产生随机种子  把0换成NULL也行
    for (int i = 0; i < 4; i++)
    {

        num[i]= random(1, 13);    //生成1-13间四个随机数存入num数组中
        cout<<num[i]<<" "<<endl;
    }

		for (i=0;i<4;i++)
			for (j=0;j<4;j++)
				if (j!=i)
					for (k=0;k<4;k++)
						if (k!=j && k!=i)
							for (t=0;t<4;t++)
								if (t!=i && t!=j && t!=k)        //循环对四个数字的计算进行组合
								{
									res=calculate(num[i],num[j],num[k],num[t]);
								}
	if (res==0)
		printf ("\nNo answer\n");
	return 0;
}

int calculate(float a,float b,float c,float d)
{
	int i,j,k;
	float sum1,sum2,sum3;
	for (i=0;i<4;i++)
		for (j=0;j<6;j++)
			for (k=0;k<6;k++)
			{
				if ((!(i==3 && b==0)) && (!(j==3 && c==0)) && (!(k==3 && d==0)))
				{
					sum1=myF(i,a,b);   //  (((a#b)#c)#d)
					sum2=myF(j,sum1,c);
					sum3=myF(k,sum2,d);
					if (fabs(sum3-24)<0.1)
					{
						temp++;  //type==1
						myPrint(1,i,j,k,a,b,c,d);   //类型1的输出

					}
				}
				if (k==2)
				{
					sum1=myF(i,a,b);  //(a#b)*(c#d)
					sum2=myF(j,c,d);
					sum3=sum1*sum2;
				 	if (fabs(sum3-24)<0.1)
					{
						temp++;
						myPrint(2,i,j,k,a,b,c,d);
					}
				}

				if (k==3)
				{
					sum1=myF(i,a,b);   //(a#b)/(c#d)
					sum2=myF(j,c,d);
					if (sum2!=0)
					{
						sum3=sum1/sum2;
				 		if (fabs(sum3-24)<0.1)
						{
							temp++;
							myPrint(3,i,j,k,a,b,c,d);
						}
					}
				}
			}
	if (temp==0)        //没有能计算出24点的结果
		return 0;
	else
		return 1;
}

float myF(int flag,float m,float n)   //判断运算符功能
{
	if (flag==0)
		return (m+n);
	if (flag==1)
		return (m-n);
	if (flag==2)
		return (m*n);
	if (flag==3)
		if (n==0)
			return 30000;
		else
			return (m/n);
	if (flag==4)      //反减
		return (n-m);
	if (flag==5)     //反除
		if (m==0)
			return 30000;
		else
			return (n/m);
	return 0;
}

void myPrint(int type,int i,int j,int k,float a,float b,float c,float d)
{
	char sigle[6];
		sigle[0]='+';
		sigle[1]='-';
		sigle[2]='*';
		sigle[3]='/';
		sigle[4]='-';
		sigle[5]='/';
	if (type==1){
		if(j==4 || j==5)
		{
			if (k==4 || k==5)
				printf("%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
			else
				printf("(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
		}
		else if (k==4 || k==5)
		{
			printf("%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
		}
		else
			printf("((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
	}
	if (type==2 || type==3)
	{

			printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
	}
}

概要设计

概要设计
一、主函数程序流程图
在这里插入图片描述

二、Calculate函数流程图

在这里插入图片描述

calculat函数对四个数字a,b,c,d进行穷举,对每一种的运算结果进行判断,若等于24则该表达式是结果之一。

三、myF函数流程图
在这里插入图片描述

myF函数通过形参得到的flag值进行判断,从而进行相应的运算。

调试

测试
一、测试一:随机数产生测试
测试代码:

srand((int)time(0));  // 产生随机种子  把0换成NULL也行
for (int i = 0; i < 4; i++)
 {
    num[i]= random(1, 13);    //生成1-13间四个随机数存入num数组中
 }

测试结果:
在这里插入图片描述

可以看到,程序成功的生成了四个随机数,并且由于srand函数产生随机种子使得每次都可成功产生完全随机的数字。
二、测试主程序输出结果
测试代码:

int main()
{
   int i,j,k,t,again,res,flag;
   float num[4]; //用于存放四个数字
    srand((int)time(0));  // 产生随机种子  把0换成NULL也行
    for (int i = 0; i < 4; i++)
    {

        num[i]= random(1, 13);    //生成1-13间四个随机数存入num数组中
        cout<<num[i]<<" "<<endl;
    }

      for (i=0;i<4;i++)
         for (j=0;j<4;j++)
            if (j!=i)
               for (k=0;k<4;k++)
                  if (k!=j && k!=i)
                     for (t=0;t<4;t++)
                        if (t!=i && t!=j && t!=k)        //循环对四个数字的计算进行组合
                        {
                           res=calculate(num[i],num[j],num[k],num[t]);
                        }
   if (res==0)
      printf ("\nNo answer\n");
   return 0;
}

测试结果:
在这里插入图片描述

程序成功将系统随机生成的数字1,3,5,13进行了穷举,列出了所有可能的表达式,根据验证,输出结果正确。

三、测试无法组成24点的数据
在这里插入图片描述

经过多次运行,对于系统随机生成的8,7,12,10这四个数据,无法组成24点,程序输出No answer运行正确。

心得体会

对于此次程序的编写,考虑到的因素较多,在没有思路的初期在网上借鉴了相关的算法思路,对题目的要求进行了分析,对需要的程序模块进行了分解,细化了问题的解法。使得程序的编写变得更为简单,同时学会了在c++中利用srand以及rand函数生成随机数的方法,更加深刻的认识到了程序设计的标准以及流程方法。对以后的学习打下基础。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值