计算24游戏课程设计.docx
《计算24游戏课程设计.docx》由会员分享,可在线阅读,更多相关《计算24游戏课程设计.docx(14页珍藏版)》请在冰豆网上搜索。
计算24游戏课程设计
游戏24点设计
1.算法描述(源代码里有更详尽解释):
主要方法:
遍历与递归。
2.主要思路:
把输入的四个数放在一个数组n[4]中,然后任取其中任意两个(不能取同一个--既不能出现自己和自己运算的情况),然后用一个for和一个switch语句来实现这两个数的加减乘除运算,然后把运算的结果放到另一个数组b[4]中并记录此运算的表达式(放到一个大一点的数组tm[4][25]中),同时把其他两个没用到的数也放到该数组中,然后重复以上过程(用遍历实现),最后先判定是不是最后一层运算,是的话在判定最后结果是不是等于24,等于24的话就把那个纪录运算式的数组输出。
然后考虑到不能出现重复的(例如:
1*2*3*4和2*4*3*1等等)我在遍历的同时记录了第一次运算的结果,第一次运算的运算符,第二次运算的结果,第二次运算的运算符和第三次运算的运算符,对输出的时候做限定(例如:
对运算符全*的只输出一遍等等)。
在有一次输出后我还定义了另外两个数组用来分别保存上一次输出的第一次运算的结果,第一次运算的运算符,第二次运算的结果,第二次运算的运算符和第三次运算的运算符,来解决重复输出的问题,不过此种做法有可能导致输出的时候不全。
(此问题尚未解决)即还不能同时保证全面性与不重复性。
3.主要函数与数组:
主要有两个函数,一个主函数,用来输入四个数,并且完成初始化。
还有一个count(floata[],chartem[][25],intn)函数,用来完成遍历,递归,与输出,其中a[]中存放要输入的4个数,tem[][25]中放计算步骤,n是a[]中元素的个数。
在函数体内还定义了b[4]和tm[4][25]用来完成递归,函数一开始先判定输出条件(是否是第三次运算,结果是否等于24),如果不满足条件就做遍历与递归,遍历用了3个for循环和1个switch语句来完成,然后为递归准备数据,用sprintf函数将运算式输出到数祖tm[]中,在输入运算式的同时把括号输到tm[]中,然后提取第一次运算的运算符与运算结果,提取第二次运算的运算符与运算结果和提取第三次运算的运算符,然后备份没用到的数据(为递归之用)。
接下来进行递归重复上述过程。
4.算法流程图:
(简化的流程图,源代码里有更详尽解释)
5.源代码及其分析
#include
#include
#include
#include
#include
#include
#defineMAX4;//最大输入个数。
intk=0;//全局变量用来判定是否有解
chartp[4]={0,0,0,0},tpt[2000]={0},tptt[2000]={0},tre[2000]={0};//用来消除重复。
tp[1-3]用来记录运算式中的3个运算符。
charop[4]={'+','*','-','/'};
voidcount(floata[],chartem[][25],intn);//a[]中存放要输入的4个数,tem[][25]中放计算步骤,n是a[]中元素的个数。
intq=0,p=0,e=0,w=0,t=0,r=0,g=0,h=0,v=0,u=0,tu=0,te=0;//用于消除重复。
floatgroup[2]={0,0},flow[20]={0},flo[20]={0};//
//tem[][25]中放计算步骤,n是a[]中元素的个数。
voidmain()
{
charbr=1;
intd;
while(br==1)
{floatnumber[4];//放四个数。
chartemp[4][25];//放运算式,初始化放四个数。
cout<<"pleaseinsertfournumbers:
";
cout<for(d=0;d<4;d++)
cin>>number[d];//输入四个数
for(d=0;d<4;d++)
{
sprintf(temp[d],"%d",(int)number[d]);
}//初始化temp[d];
count(number,temp,4);//调用count函数。
if(k==0)
cout<<"noanswer";
cout<cout<<"press0end"<scanf("%d",&br);
}
}
voidcount(floata[],chartem[][25],intn)
{
floatb[4];
chartm[4][25];//b[4]和t[4][]作用同上(为递归之用)。
inti,j,l,x,y;//i,j用来作双循环;l用来作加减乘除的开关;x,y为后面准备递归数据之用。
/************************************************************************************/
//输出部分
if(n==1)
{
if(fabs(a[0]-24)<0.00001)//因为要考虑除法所以用fabs函数求绝对值与24比较。
//相当于等于24时的情况。
{
/************************************************************************************/
//以下是限定输出条件:
if(tp[3]=='-'&&tp[2]=='-'&&tp[1]=='*')
{
if(te==0)
{
cout<<"\n有解为"<k=1;
te=1;
}
}//对运算符全*的只输出一遍。
elseif(tp[3]=='+'&&(tp[2]=='+'||tp[0]=='+')&&tp[1]=='+')
{
if(t==0)
{
cout<<"\n有解为"<k=1;
t=1;
}
}//对运算符全+的只输出一遍。
elseif(tp[3]=='+'&&(tp[2]=='*'||tp[0]=='*')&&tp[1]=='+')
{
if(g==0)
{
cout<<"\n有解为"<k=1;
g=1;
}
}
elseif((tp[3]=='-'&&tp[2]=='+')||(tp[3]=='+'&&tp[2]=='-'))
{
if(w==0)
{
cout<<"\n有解为"<k=1;
w=1;
}
}//对于第二次运算时取到b[0]时,第一第二个运算符是+,-或-,+的只输出一遍。
elseif(tp[3]=='+'&&tp[2]=='+')
{
if(u==0)
{
cout<<"\n有解为"<k=1;
u=1;
}
}//对于第二次运算时取到b[0]时,第一第二个运算符是+,+的只输出一遍
elseif(tp[3]=='*'&&tp[2]=='*')
{
if(r==0)
{
cout<<"\n有解为"<k=1;
r=1;
}
}
elseif(tp[3]=='*'&&tp[0]=='*'&&tp[1]=='+')
{
if(tu==0)
{
cout<<"\n有解为"<k=1;
tu=1;
}
}
else
{for(h=0;h{
if(group[0]==flow[h])
{
if(tp[3]==tpt[h])
{
if(tp[2]=tptt[h])
{
if(group[1]==flo[h])
{
if(p==0)
{
cout<<"\n有解为"<k=1;
p=1;
}
}
}
}
}
elseif(h==q-1)
{
cout<<"\n有解为"<k=1;
}
}
}
flo[q]=group[1];//限定条件初始化。
flow[q]=group[0];//限定条件初始化。
tpt[q]=tp[3];//限定条件初始化。
tptt[q]=tp[2];//限定条件初始化。
tre[q]=tp[1];//限定条件初始化。
tp[0]=0;
tp[1]=0;
tp[2]=0;
tp[3]=0;
q=q+1;
}
}
/************************************************************************************/
//运算部分:
if(n>1)//该条件语句用来结束一次递归。
{
for(i=0;i{
for(j=0;j{
if(i==j)
continue;
for(l=0;l<4;l++)//进行四则运算。
{
switch(l)
{
case(0):
if(n==2)
{
b[0]=a[0]+a[1];
break;
}
elseb[0]=a[i]+a[j];
break;
case
(1):
if(n==2)
{
b[0]=a[0]*a[1];
break;
}
elseb[0]=a[i]*a[j];
break;
//对加和乘做遍历时去除a[i]+a[j]与a[j]+a[i]等情况。
case
(2):
b[0]=a[i]-a[j];
break;
case(3):
if(a[j]==0)
break;
b[0]=a[i]/a[j];
break;//对'-'和'/'做遍历时考虑a[i]-a[j]与a[j]-a[i]的不同。
default:
break;
}//switch
if(l!
=3||a[j]!
=0)//为递归准备数据(把没用到的数也放到b[]与tm[]中)。
{
{if(l==0||l==2||l==3)//用sprintf函数将运算式输出到数祖tm[]中。
//在输入运算式的同时把括号输到tm[]中。
sprintf(tm[0],"(%s%c%s)",tem[i],op[l],tem[j]);
if(l==1)
sprintf(tm[0],"%s%c%s",tem[i],op[l],tem[j]);
}
{if(n==3)//提取第一次运算的运算符与运算结果。
{
group[1]=b[0];
if(i!
=0&&j!
=0)
tp[0]=op[l];
else
tp[n-1]=op[l];
}
elseif(n==4)//提取第二次运算的运算符与运算结果。
{
tp[n-1]=op[l];
group[0]=b[0];
}
else//提取第三次运算的运算符。
tp[n-1]=op[l];
}
for(x=0,y=1;x{
if(x!
=i&&x!
=j)
{
b[y]=a[x];
strcpy(tm[y],tem[x]);//复制字符串。
y++;
}//if
}//for
}//if
count(b,tm,n-1);
}//第三层for循环结束。
}//第二层for循环结束。
}//for循环结束。
}//if结束。
}//count函数结束。
6.运行数据测试
5.1输入数据(以空格分开)
5.2回车后出运行结果
5.3按0退出
东华理工大学
学年课程设计报告评分表
学生姓名:
吴青山学号:
201120360211班级:
1123602
课程设计题目:
计算24游戏
项目内容
满分
实评
选
题
能结合所学课程知识、有一定的能力训练。
符合选题要求
(3人一题)
5
工作量适中,难易度合理
10
能
力
水
平
能熟练应用所学知识,有一定查阅文献及运用文献资料能力
10
理论依据充分,数据准确,公式推导正确
10
能应用计算机软件进行编程、资料搜集录入、加工、排版、制图等
10
能体现创造性思维,或有独特见解
15
成
果
质
量
模型正确、合理,各项技术指标符合要求。
15
摘要叙述简练完整,假设合理、问题分析正确、数学用语准确、结论严谨合理;问题处理科学、条理分明、语言流畅、结构严谨、版面清晰
15
课程设计报告主要部分齐全、合理,符号统一、编号齐全。
格式、绘图、表格、插图等规范准确,符合课程设计报告要求
10
正文字数不少于2000字,不超过15000字
5
总分
100
指导教师评语:
指导教师签名:
年月日