C语言实现24点小游戏

问题描述

        游戏规则:
        从键盘输入任意1-13的4个数,然后用算术运算符“+、一、*、/”将这四个数组成一一个算术表达式(可加括号,每个数字只能使用1次),使得该式的运算结果为24,每输入一次表达式,系统给出该式的运算结果,如果结果是24,则游戏结束;如果不是,则继续组合表达式,直到结果为24为止。

问题分析

        本题最简单的解法就是应用穷举法搜索整个解的空间,然后筛选出符合项的全部解,因此关键就是如何确定该题的解题空间。

        假设输入4个整数,A,B,C,D,如果只考虑括号不考虑优先级的情况,有一下几种情况:

     (1). ((A□B)□C)□D
     (2). (A□(B□C))□D
     (3). A□(B□(C□D))
     (4). A□((B□C)□D)
     (5). (A□B)□(C□D)

        即在□输入“+、-、*、/”中的任意一种。我们就是在填入的所有式子中所得到的答案里面找出答案为24的表达式。

算法设计

        我们在不同的地方设置不同的变量,即:op1、op2、op3,并且规定A和B之间的运算符为op1,B和C之间的运算符为op2,C和D之间的运算符为op3。即:

      A op1 B op2 C op3 D

        又规定op1、op2、op3的取值范围为1、2、3、4分别为加减乘除,如表所示:

op1、op2、op3变量值表示的运算
1+
2-
3*
4/

此时就得到了以下算法:

	for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)
             {得到一种不含括号的表达式情形:A op1 B op2 C op3 D
}

        下面我们要填入符号,根据括号和优先级的限制,我们有以下的填入方式
     (1). ((A+B)-C)×D
     (2). (A+(B-C))×D
     (3). A+(B-(C×D))
     (4). A+((B-C)×D)
     (5). (A+B)-(C×D)

        根据优先级来说,以上五种情况包括了全部的算式,我们只需计算出每个表达式的值,将其与24进行比较。

float calculate_model1(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  ((A□B)□C)□D */
   float r1,r2,r3;
   r1 = cal(i,j,op1);
   r2 = cal(r1,k,op2);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model2(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  (A□(B□C))□D */
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(i,r1,op1);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model3(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式   A□((B□C)□D) */
   float r1,r2,r3 ;
   r1 = cal(k,t,op3);
   r2 = cal(j,r1,op2);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model4(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  ((A□B)□C)□D */
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(r1,t,op3);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model5(float i,float j,float k,float t,
int op1,int op2,int op3)
{ /*对应关系式  (A+B)-(C×D) */
   float r1,r2,r3 ;
   r1 = cal(i,j,op1);
   r2 = cal(k,t,op3);
   r3 = cal(r1,r2,op2);
   return r3;
 }

        上述算法中,每一个函数对应一种表达式类型, 其返回值为表达式的值,原表达式式的形式为i opl j op2 k op3 t,不同的表达式类型,根据其运算时优先级的不同进行不同的运算。其中函数cal()的作用是通过每种表达式的状态计算出对应的表达式的值。

     int op1,op2,op3;
     int flag=0;
     for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)

op1、op2、op3都是取 “+”,“-”,“*”,“/”四个选项

        函数cal()包括3个参数,第3个参数为运算符变量,它标志着不同种类的运算符,前两个参数为运算数。该函数的作用是使用前两个参数指定的操作数进行第3个参数指定的运算,并返回其运算结果。例如函数调用cal(2,3.1)的作用是计算2+3=5.并返回5。函数cal0的代码如下:

float cal(float x,float y,int op)
{
  switch(op)
  {
    case 1:return x+y;
    case 2:return x-y;
    case 3: return x*y;
    case 4: return x/y;
  }
}

        将上面所讲的算法进行结合,可以遍历由4个操作数(范围:1-13), 3个运算符(+,-,*,/),这样就缩小了搜索空间,提高查询效率。

主函数

main()
{
         int i,j,k,t;
         printf("Please input four integer (1~13)\n");

输入 i,j,k,t四位数。

 loop:    scanf("%d %d %d %d",&i,&j,&k,&t);
         if(i<1||i>13 || j<1||j>13 || k<1||k>13 || t<1||t>13){
           printf("Input illege, Please input again\n");
           goto loop;
   }

如果这四位数小于1或者大于13,则报错。

      if(i==j||i==k || i==t||j==k || j==t||k==t){
         printf("Input wrong, Please input again\n");
         goto loop;
 }

如果这四位数有一位以上的数输入了2遍,则报错(题目要求只能用一次)

         if(get24(i,j,k,t));
         else 
			 {printf("Sorry, the four integer cannot be calculated to get 24\n");
			  goto loop;} 
 }

如果这四个数通过运算不等于24,则需要重新输入4位数重新计算

goto loop;表示继续执行不退出。

完整代码

以下是完整代码:

#include<stdio.h>
char op[5]={'#','+','-','*','/',};
float cal(float x,float y,int op)
{
   switch(op)
   {
     case 1:return x+y;
     case 2:return x-y;
     case 3: return x*y;
     case 4: return x/y;
   }
 }

float calculate_model1(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(i,j,op1);
   r2 = cal(r1,k,op2);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model2(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(i,r1,op1);
   r3 = cal(r2,t,op3);
   return r3;
 }

float calculate_model3(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3 ;
   r1 = cal(k,t,op3);
   r2 = cal(j,r1,op2);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model4(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3;
   r1 = cal(j,k,op2);
   r2 = cal(r1,t,op3);
   r3 = cal(i,r2,op1);
   return r3;
 }

float calculate_model5(float i,float j,float k,float t,int op1,int op2,int op3)
{
   float r1,r2,r3 ;
   r1 = cal(i,j,op1);
   r2 = cal(k,t,op3);
   r3 = cal(r1,r2,op2);
   return r3;
 }

get24(int i,int j,int k,int t)
{
     int op1,op2,op3;
     int flag=0;
     for(op1=1;op1<=4;op1++)
         for(op2=1;op2<=4;op2++)
             for(op3=1;op3<=4;op3++)
             {
				 if(calculate_model1(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("((%d%c%d)%c%d)%c%d=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model2(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("(%d%c(%d%c%d))%c%d=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model3(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("%d%c(%d%c(%d%c%d))=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model4(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("%d%c((%d%c%d)%c%d)=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
				 if(calculate_model5(i,j,k,t,op1,op2,op3)==24)
				 {
					 printf("(%d%c%d)%c(%d%c%d)=24\n",i,op[op1],j,op[op2],k,op[op3],t);
					 flag = 1;
				 }
			 }
			 return flag;
} 

main()
{
         int i,j,k,t;
         printf("Please input four integer (1~13)\n");
 loop:    scanf("%d %d %d %d",&i,&j,&k,&t);
         if(i<1||i>13 || j<1||j>13 || k<1||k>13 || t<1||t>13){
           printf("Input illege, Please input again\n");
           goto loop;
   }
        if(i==j||i==k || i==t||j==k || j==t||k==t){
           printf("Input wrong, Please input again\n");
           goto loop;
   }
         if(get24(i,j,k,t));
         else 
			 {printf("Sorry, the four integer cannot be calculated to get 24\n");
			  goto loop;} 
 }

        此时改程序已经可以成功实现。

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值