24点游戏

第3章 作业
一、题目说明
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
二、算法设计思路
此次作业可以自己设置4个数字保存在input.txt文件中,然后在期间添加运算符和括号,计算结果是否等于24。其中加了括号涉及一个优先级的问题,即确定对哪4个数进行运算。
我们首先要确定相邻的两个数的计算,计算完成后,就剩下了3个数字,然后再决定剩下的这3个数中相邻的两个数进行计算。括号的优先级高于加减乘除。在循环过程中,我们可以依次进行三次计算,然后得到结果,判断结果是否为24。
三、源程序

```c#include<iostream>
#include<fstream>
#include<cmath> 
using namespace std;
char oper[4]={'+','-','*','/'};
class Game	//24点游戏 
{
	private:
	double a[4];	//可以精确计算 
	public:
	Game();	//构造函数 
	double calcute(double,double,char);	//计算函数 
	void search();	//搜索函数,找到合适解 
	void print();	//打印4张牌数值 
};
Game::Game()
{
	char ch[4];
	ifstream infile("input.txt");
	if(!infile)
	{
		cout<<"打开文件input.txt失败"<<endl;
		exit(1); 
	}
	for(int i=0;i<4;i++)
		infile>>ch[i];
	cout<<"*********************************"<<endl;
	cout<<"****正在从input.txt中读取数据****"<<endl;
	for(int i=0;i<4;i++)
	{
		if(ch[i]=='A') a[i]=1;
		else if(ch[i]=='2') a[i]=2;
		else if(ch[i]=='3') a[i]=3;
		else if(ch[i]=='4') a[i]=4;
		else if(ch[i]=='5') a[i]=5;
		else if(ch[i]=='6') a[i]=6;
		else if(ch[i]=='7') a[i]=7;
		else if(ch[i]=='8') a[i]=8;
		else if(ch[i]=='9') a[i]=9;
		else if(ch[i]=='10') a[i]=10;
		else if(ch[i]=='J') a[i]=11;
		else if(ch[i]=='Q') a[i]=12;
		else if(ch[i]=='K') a[i]=13;
		else
		{
			cout<<"第"<<i+1<<"个数据输入有误"<<endl;
			exit(1); 
		}
	 } 
	 infile.close();
}
double Game::calcute(double a,double b,char index)
{
	if(index=='+') return a+b;	//若为+,则返回相应结果 
	else if(index='-') return a-b;	
	else if(index='*') return a*b;
	else if(index='/') if(b!=0) return a/b;	//只有当分母为0时,返回结果 
}
void Game::search()
{
	double temp[3],tem[2];	//第一个符号放置后,经过计算后相当于剩下三个数,这个数组用于存储这三个数 
	double sum;
	int judge=0;
	ofstream outfile("output.txt",ios::app);
	if(!outfile)
	{
		cout<<"打开文件output.txt失败"<<endl;
		exit(1); 
	}
	cout<<"*********************************"<<endl;
	cout<<"正在计算结果"<<endl;
	outfile<<"================="<<endl;
	outfile<<"本次24点游戏结果如下:"<<endl;
	for(int i=0;i<4;i++)  //第一次放置的符号 
	{
		for(int j=0;j<4;j++)  //第二次放置的符号 
		{
			for(int k=0;k<4;k++)  //第三次放置的符号 
			{
				for(int m=0;m<3;m++)	//首先计算两个相邻数字有三种情况,相当于括号的作用 
				{
					if(a[m+1]==0&&oper[i]=='/') break;
					temp[m]=calcute(a[m],a[m+1],oper[i]);
					temp[(m+1)%3]=a[(m+2)%4];
					temp[(m+2)%3]=a[(m+3)%4];
					for(int n=0;n<2;n++)	//三个数中选出先计算的相邻的两个数,两种情况,相当于第二个括号 
					{
					if(temp[n+1]==0&&oper[i]=='/') break;
					tem[n]=calcute(temp[n],temp[n=1],oper[j]);
					temp[(n+1)%2]=temp[(n+2)%3]; 
					if(tem[1]==0&&oper[k]=='/') break;
					sum=calcute(tem[0],tem[1],oper[k]);
					if(sum==24)
					{
						judge=1;	//已求得解 
						if(m==0&&n==0)
						outfile<<"(("<<a[0]<<oper[i]<<a[1]<<")"<<oper[j]<<a[2]<<")"<<oper[k]<<a[3]<<"="<<sum<<endl;
						else if(m==0&&n==1)
						outfile<<"("<<a[0]<<oper[i]<<a[1]<<")"<<oper[k]<<"("<<a[2]<<oper[j]<<a[3]<<")="<<sum<<endl;
						else if(m==1&&n==0)
						outfile<<"("<<a[0]<<oper[j]<<"("<<a[1]<<oper[i]<<a[2]<<")"<<oper[k]<<a[3]<<"="<<sum<<endl;
						else if(m==1&&n==1)
						outfile<<a[0]<<oper[k]<<"(("<<a[1]<<oper[i]<<a[2]<<")"<<oper[j]<<a[3]<<")="<<sum<<endl;
						else if(m==2&&n==0)
						outfile<<"("<<a[0]<<oper[j]<<a[1]<<")"<<oper[k]<<"("<<a[2]<<oper[i]<<a[3]<<")="<<sum<<endl;
						else if(m==2&&n==0)
						outfile<<a[0]<<oper[k]<<"("<<a[1]<<oper[j]<<"("<<a[2]<<")"<<oper[i]<<a[3]<<"))="<<sum<<endl;
					}
				}
			}
		}
	 } 
}
	 if(judge==0) outfile<<"这四张扑克牌无解"<<endl;
	 outfile.close();
	 cout<<"计算完成,结果已保存在output.txt文件中"<<endl; 
}
void Game::print()
{
	cout<<"读取成功"<<endl;
	for(int i=0;i<4;i++)
	{
		cout<<"第"<<i+1<<"张牌"<<a[i]<<endl; 
	 } 
}
int main(void)
{
	Game obj;
	obj.print();
	cout<<endl;
	obj.search();
	cout<<endl;
	system("pause");
	return 0;
}

四、运行结果
1、不能得出解的情况
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.能得出解的情况

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、总结
实现本次24点游戏的过程中,要结合现实情况中的13张扑克牌式样,还要求能算出24的表达式,运算符有+,-,*,/,若有解则输出正确解,如果无解则输出相应信息。此次使用input.txt来保存信息,然后在程序运行后在output.txt中输出结果,可以查漏补缺。在编码过程中,要结合多方面知识与考虑,在处理符号与优先级问题方面经过了很长时间的思考,先提一个符号与两个数计算,再依次计算下面的3位数,这种想法比较巧妙。程序看起来繁琐,不简洁,这也是以后所需要优化的地方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值