c语言写的一个小游戏。

//calc 24 . CPP:定义控制台应用程序的入口点。

//

/*

6-6

二十一点游戏

*/

#包含“conio.h”

#包含" stdlib.h "

#包含“time.h”

#包含“math.h”

#include "string.h"/*

从一副扑克牌中任选四张。

2-10按点数计算(为方便起见,10用T表示),J、Q、K、A统一按1计算。

要求通过加减乘除四则运算得到数字24。

这个程序可以随机抽卡,用试错法求解。

*/void GivePuzzle(char* buf)

{

char card[] = {'A ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',' 9 ',' T ',' J ',' Q ',' K ' };for(int I = 0;我& lt4;i++){

buf[I]= card[rand()% 13];

}

}

无效洗牌(char * buf)

{

for(int I = 0;我& lt5;i++){

int k = rand()% 4;

char t = buf[k];

buf[k]= buf[0];

buf[0]= t;

}

}

int GetCardValue(int c)

{

if(c=='T ')返回10;

if(c & gt;= ' 0 ' & amp& ampc & lt='9 ')返回c-' 0 ';

返回1;

}

char GetOper(int n)

{

开关(n)

{

案例0:

返回“+”;

案例1:

返回'-';

案例二:

返回“*”;

案例三:

返回“/”;

} return“”;

} double my calc(double op 1,double op2,int oper)

{

开关(操作)

{

案例0:

返回op 1+op2;

案例1:

返回op 1-op2;

案例二:

返回op 1 * op2;

案例三:

if(fabs(op2)>0.0001)

返回op 1/op2;

其他

返回100000;

}返回0;

}

void MakeAnswer(char* answer,int type,char* question,int* oper)

{

char p[4][3];

for(int I = 0;我& lt4;i++)

{

if(问题[i] == 'T ')

strcpy(p[i]," 10 ");

其他

sprintf(p[i]," %c ",问题[I]);

}

开关(类型)

{

案例0:

sprintf(答案," %s %c (%s %c (%s %c %s))",

p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);

打破;

案例1:

sprintf(答案," %s %c ((%s %c %s) %c %s)",

p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);

打破;

案例二:

sprintf(答案,"(%s %c %s) %c (%s %c %s)",

p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);

打破;

案例三:

sprintf(答案,“((%s %c %s) %c %s) %c %s”,

p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);

打破;

案例4:

sprintf(答案,"(%s %c (%s %c %s)) %c %s ",

p[0],GetOper(oper[0]),p[1],GetOper(oper[1]),p[2],GetOper(oper[2]),p[3]);

打破;

}

}

bool TestResolve(char* question,int* oper,char*答案)

{

//等待考生完成。

int type[5]={0,1,2,3,4 };//计算类型

双p[4];

double sum = 0;

//

for(int I = 0;我& lt4;I++) //循环获得积分。

{

p[I]= GetCardValue(int(question[I]));

} for(I = 0;我& lt5;i++)

{

MakeAnswer(答案,类型[i],问题,操作);//获得可能的答案

开关(类型[i])

{

案例0:

sum=MyCalcu(p[0],MyCalcu( p[1],MyCalcu(p[2],p[3],oper[2]),oper[1],oper[0]);//A*(B*(c*D))

打破;

案例1:

sum=MyCalcu(p[0],MyCalcu(MyCalcu(p[1],p[2],oper[1]),p[3],oper[2],oper[0]);//A *(B * C)* D)

打破;

案例二:

sum=MyCalcu(MyCalcu(p[0],p[1],oper[0]),MyCalcu(p[2],p[3],oper[2],oper[1]);// (A*B)*(C*D)

打破;

案例三:

sum = my calcu(my calcu(my calcu(p[0],p[1],oper[0]),p[2],oper[1]),p[3],oper[2]);//((A*B)*C)*D

打破;

案例4:

sum=MyCalcu(MyCalcu(p[0],MyCalcu(p[1],p[2],oper[1]),oper[0],p[3],oper[2]);//(A*(B*C))*D

打破;

}

if(sum==24)返回true

}

返回false

}

/*

使用随机试错法:是通过随机数生成加减乘除组合,并通过大量测试命中的解决方案。

提示:

1.需要考虑用括号控制计算顺序的问题,比如:(10-4) * (3+A),其实计算顺序的个数是有限的:

A*(B*(c*D))

a *(B * C)* D)

(A*B)*(C*D)

((A*B)*C)*D

(A*(B*C))*D

2.需要考虑计算结果是一个分数的情况:(3+(3/7)) * 7。

3.标题中卡片的位置可以随意交换。

*/

bool TryResolve(char* question,char* answer)

{

int oper[3];//存储运算符,0:加法1:减法2:乘法3:除法。

for(int I = 0;我& lt1000 * 1000;i++)

{

//打乱卡片的顺序

洗牌(问题);

//随机生成的运算符

for(int j = 0;j & lt3;j++)

oper[j]= rand()% 4;if( TestResolve(question,oper,answer))返回true

}返回false

}

int main(int argc,char* argv[])

{

//初始化随机种子

srand((无符号)时间(空));char buf 1[4];//主题

char buf 2[30];//回答

printf(" * * * * * * * * * * * * * * * * * * * * * * * * * * * \ n ");

Printf("计算24 \ n ");

Printf("A J Q K按1计算,其他按卡点计算\ n ");

Printf("目标是通过四次运算组合结果:24 \ n ");

printf(" * * * * * * * * * * * * * * * * * * * * * * * * * \ n \ n ");

for(;;)

{

give puzzle(buf 1);//给出一个问题

printf(" Title:");

for(int j = 0;j & lt4;j++){

if( buf1[j] == 'T ')

printf(" 10 ");

其他

printf("%c ",buf 1[j]);

} printf(" \ n按任意键查看答案...\ n ");

getch();If (try resolve (buf1,buf 2))//解决问题

Printf ("reference: %s\n ",buf 2);

其他

Printf("可能无解...\ n ");Printf("按任意键进入下一个主题,按X键退出...\ n ");

if(getch()= = ' x ')break;

}返回0;

}