求教-----关于24点游戏的算法思想(200分)

  • 主题发起人 主题发起人 lbeast_2001
  • 开始时间 开始时间
L

lbeast_2001

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在写一个自动计算24点的小游戏,也参考过了一些资料
但是其中的算法总是不对,请大家指教
24点游戏就是取4个数,按任意+ - * /四则运算得结果24
复源码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Button1: TButton;
Button2: TButton;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
function caculate(j,k:real;operator:integer;var answer:real):boolean;
function operate(op:integer):string;
function change(t:integer):real;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
num1,num2,num3,num4:integer;
op1,op2,op3:integer;
answer1,answer2,answer3:real;
//const zero=0.00000001;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
form1.Edit1.Text:='';
form1.Edit2.Text:='';
form1.Edit3.Text:='';
form1.Edit4.Text:='';
form1.Edit1.enabled:=true;
form1.Edit2.enabled:=true;
form1.Edit3.enabled:=true;
form1.Edit4.enabled:=true;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
x,y,z,w:integer;
begin
form1.Edit1.enabled:=false;
form1.Edit2.enabled:=false;
form1.Edit3.enabled:=false;
form1.Edit4.enabled:=false;
num1:=strtoint(form1.edit1.Text);
num2:=strtoint(form1.edit2.Text);
num3:=strtoint(form1.edit3.Text);
num4:=strtoint(form1.edit4.Text);
form1.edit5.text:='无解';
form1.edit6.Text:='无解';
form1.edit7.Text:='无解';
form1.edit8.Text:='无解';
form1.edit9.Text:='无解';
for x:=1 to 4do
for y:=1 to 4do
if y<>x then
for z:=1 to 4do
if (z<>x) and (z<>y) then
for w:=1 to 4do
if (w<>x) and (w<>y) and (w<>z) then
begin
for op1:=1 to 4do
for op2:=1 to 4do
for op3:=1 to 4do
begin
if caculate(change(x),change(y),op1,answer1) and
caculate(answer1,change(z),op2,answer2) and
caculate(answer2,change(w),op3,answer3) then
begin
if answer3=24 then
begin
form1.Edit5.Text:='(('+inttostr(round(change(x)))+operate(op1)+inttostr(round(change(y)))+')'+operate(op2)
+inttostr(round(change(z)))+')'+operate(op3)+inttostr(round(change(w)))+'=24';
//exit;
end;
end;
if caculate(change(x),change(y),op1,answer1) and
caculate(change(z),change(w),op3,answer2) and
caculate(answer1,answer2,op2,answer3) then
begin
if answer3=24 then
begin
form1.Edit6.Text:='('+inttostr(round(change(x)))+operate(op1)+inttostr(round(change(y)))+')'+operate(op2)+'('+inttostr(round(change(z)))+operate(op3)+inttostr(round(change(w)))+')'+'=24';
//exit;
end;
end;
if caculate(change(y),change(z),op2,answer1) and
caculate(change(x),answer1,op1,answer2) and
caculate(answer2,change(w),op3,answer3) then
begin
if answer3=24 then
begin
form1.Edit7.Text:='('+inttostr(round(change(x)))+operate(op1)+'('+inttostr(round(change(y)))+operate(op2)
+inttostr(round(change(z)))+'))'+operate(op3)+inttostr(round(change(w)))+'=24';
//exit;
end;
end;
if caculate(change(y),change(z),op2,answer1) and
caculate(answer1,change(w),op3,answer2) and
caculate(change(x),answer2,op1,answer3) then
begin
if answer3=24 then
begin
form1.Edit8.Text:=inttostr(round(change(x)))+operate(op1)+'(('+inttostr(round(change(y)))+operate(op2)
+inttostr(round(change(z)))+')'+operate(op3)+inttostr(round(change(w)))+')'+'=24';
//exit;
end;
end;
if caculate(change(z),change(w),op3,answer1) and
caculate(change(y),answer1,op2,answer2) and
caculate(change(x),answer2,op1,answer3) then
begin
if answer3=24 then
begin
form1.Edit9.Text:=inttostr(round(change(x)))+operate(op1)+'('+inttostr(round(change(y)))+operate(op2)
+'('+inttostr(round(change(z)))+operate(op3)+inttostr(round(change(w)))+'))'+'=24';
exit;
end;
end;
end;

end;
end;

function tform1.caculate(j,k:real;operator:integer;var answer:real):boolean;
begin
case operator of
1: answer:=j+k;
2: answer:=j-k;
3: answer:=j*k;
4: if k<0 then
begin
result:=false;
exit;
end;
else
answer:=j/k;
end;
result:=true;
end;

function tform1.operate(op:integer):string;
begin
case op of
1: result:='+';
2: result:='-';
3: result:='*';
4: result:='/';
end;
end;

function tform1.change(t:integer):real;
begin
case t of
1: result:=num1;
2: result:=num2;
3: result:=num3;
4: result:=num4;
end;
end;

end.
 
有什么问题? 我试了几个组合,没什么问题呀。
 
有的排列没问题
但有的有
好比1 5 5 5就不行了
 
怎么了,这么久都没人回帖,
各位大虾,帮帮忙了

...................................着急的我
 
我也想知道!看看小孩手里都拿着那玩具……
 
值得关注
 
我没有认真看你的源程序,但觉得该用穷举吧……你是这样的吗?
 
楼上的说穷举法,可一副牌54张中抽出4张来有多少种可能,能穷举的完吗
 
用穷举法!但不是穷举牌,而是穷举牌的排列和运算符!
牌的排列一共有4*3*2*1=24种,但ABCD与DCBA是一
样的,所以实际是12种!
运算符:我没看你的程序,我想你只用了+、-、*、/、
()、[]这几种,没用开方与次方,所以运算符的排列
为4*16*16*16*4=65536种,优化一下,大约有10000左
右。这样你看可以吗?
 
我也想知道
 
我有一个是用穷举法算的,可以输入四个数及一个答案,自动计算这四个数是否可算出此答案
只用了+ - * / ()
要的话请找个地方让我上传,然后让大家下载
因为我实在没空一个个发啊。
 
xianjun, 请上传到
http://delphi.mychangshu.com
 
[:D]已经上传
 
http://delphi.mychangshu.com
[:(]Internet Explorer 无法连接到您请求的页。可能该页目前不可用。[:(]
 
[:D]你的鸡有问题![:D]
我这上得很快啊。
 
来自http://www.programsalon.com:
// Fantastic FIRE of Tiny Bug Studio 郁明
//联络:F_FIRE@990.net bp:52330*750999
#include <stdio.h>
#include <stdlib.h> //system(),exit()
#include <conio.h> // clrscr()
#define DA 24
float op(float,float,float);
//运算
int pai[4]; //四张牌pai[1]--pai[4]
void suanfa(int pai[]);
//主算法(穷举)
char *fh(int t); //显示符号
void main(void)
{
clrscr(); //清屏
printf ("/t/t傻瓜法算%d点 (穷举计算) /n>=|> Fantastic FIRE 异火制作 F_FIRE@990.net <|=</n",DA);
do {printf ("/n请输入第一张牌:");
if(scanf("%d",&amp;pai[1])==0) exit(1);}while(pai[1]==0);
//不允许输入0
do {printf ("/n请输入第二张牌:");
if(scanf("%d",&amp;pai[2])==0) exit(1);}while(pai[2]==0);
do {printf ("/n请输入第三张牌:");
if(scanf("%d",&amp;pai[3])==0) exit(1);}while(pai[3]==0);
do {printf ("/n请输入第四张牌:");
if(scanf("%d",&amp;pai[4])==0) exit(1);}while(pai[4]==0);
suanfa(pai);
clrscr();
system ("type 24.log|more");
//分页显示24.log结果文件
}
char *fh(int t)
{
switch (t){
case 4:return " 加 " ;break;
case 2:return " 减 " ;break;
case 3:return " 乘 " ;break;
case 1:return "除以" ;break;
default:{ printf("Bug!/n");
exit(1);} //内部测试使用
}}
int op(int x,int y,int n)
{
switch (n) {
case 4: return x+y;break;
case 2: return x-y;break;
case 3: return x*y;break;
case 1: if(y==0){return 0.1;break;}else
return x/y;break;
//过滤掉 y=0 时候的计算
default:{ printf("Bug!/n");
exit(1);}
}}

void suanfa(int pai[])
{
FILE *out;
// 24.log
out=fopen("24.log","w+");
fprintf (out,"/n您输入的四张牌是:%d %d %d %d/n答案如下:/n/n",pai[1],pai[2],pai[3],pai[4]);
register int jsq=0;
//计数器
register int i,j,k, l,m,n,o;
//3个符号,4张牌
for (i=4;i>=1;i--)
for (j=4;j>=1;j--)
for (k=4;k>=1;k--)
for (l=4;l>=1;l--) // 穷举
for (m=4;m>=1;m--)
for (n=4;n>=1;n--)
for (o=4;o>=1;o--)
{ if((l!=m)&amp;&amp;(l!=n)&amp;&amp;(l!=o)&amp;&amp;(m!=n)&amp;&amp;(m!=o)&amp;&amp;(n!=o)&amp;&amp;
op(
op(
op(pai[l],pai[m],i)
,pai[n],j)
,pai[o],k)==24)
{
printf (">");
fprintf (out,"[(%d%s",pai[l],fh(i));
fprintf (out,"%d)%s",pai[m],fh(j));
fprintf (out,"%d)%s",pai[n],fh(k));
fprintf (out,"%d] 等于%d",pai[o],DA);
fprintf (out,"/n/n");jsq++;
}
else
if((l!=m)&amp;&amp;(l!=n)&amp;&amp;(l!=o)&amp;&amp;(m!=n)&amp;&amp;(m!=o)&amp;&amp;(n!=o)&amp;&amp;
op(pai[l],
op(pai[m],
op(pai[n],pai[o],i)
,j)
,k)==DA) //过滤1
{
printf (">");
fprintf (out,"%d%s",pai[l],fh(k));
fprintf (out,"[%d%s",pai[m],fh(j));
fprintf (out,"(%d%s",pai[n],fh(i));
fprintf (out,"%d)] 等于%d",pai[o],DA);fprintf (out,"/n/n");jsq++;
}
else
{register int q,r,k;
q=op(pai[n],pai[o],j);
r=op(pai[l],pai[m],i);
if((l!=m)&amp;&amp;(l!=n)&amp;&amp;(l!=o)&amp;&amp;(m!=n)&amp;&amp;(m!=o)&amp;&amp;(n!=o)&amp;&amp;op(q,r,k)==DA) //第二种情况过滤
{
printf (">");
fprintf (out,"(%d%s",pai[n],fh(j));
fprintf (out,"%d)%s",pai[o],fh(k));
fprintf (out,"(%d%s",pai[l],fh(i));
fprintf (out,"%d) 等于%d",pai[m],DA);fprintf (out,"/n/n");jsq++;
}
}
}
fprintf (out,"您要的正确答案总共有 %d 种",jsq);
fclose(out);
}
 
显然是穷举
我用c++编过,要否?
 

Similar threads

I
回复
0
查看
763
import
I
I
回复
0
查看
762
import
I
I
回复
0
查看
485
import
I
I
回复
0
查看
2K
import
I
后退
顶部