24点游戏算法

现在我们在做一个24点的小游戏,我主要负责算法部分,前面有章博客已经讲解了加括号的四则表达式的计算算法,现在要解决就是24点的算法。

24点游戏的说明:

54张牌去掉大小王2张牌,剩余52张。任意发1-K之间的4张牌(也就是有1-13的四个数字),用+-*/()连结成算式,使得式子的计算结果为24.

算法描述

24点的算法还处比较复杂的,网上有各种别人写的现成代码,大部分都写的不太好。

 

主要的思想是穷举法,列举出所有4个数字+3个运算符+括号的组合;在计算的过程利用剪枝把一些不可能的情况去除掉。

 

网上有很多算法,主要来讲一下,像以下有几个比较一下。

如:http://843788041.iteye.com/blog/1117558

这种方式没有考虑加括号的情况,不能很好地解决问题

再有:http://www.iteye.com/topic/312476

还是没有完整地解决问题,这里只对前两个数及后两个数进行了加括号,即先计算两个数,再计算后两个数,最后把两个结果进行计算。没有计算的顺序和加括号。

后然还是找到一种比较好的解决方案,基本上可以解决的问题。这算法逻辑比较复杂,但是基本都看懂了,既然已经别人都已经写好了,我就不再花时间了,直接贴代码吗。

 

[java]  view plain  copy
  1. /** 
  2.          * 他的主要想法是 
  3.          * 先对四个数中的任意两个数进行四则运算,得到的结果加剩余的两个数还有三个数 
  4.          * 再对三个数中的任意两个数进行四则运算,得到的结果加剩余的一个数还有二个数 
  5.          * 再对剩余的两个数进行四则运算,得到的结果如果是24,就说明该表达式能得到24,表达式正确; 
  6.          * 如果结果不是24,则说明表达式不正确 
  7.          * @param n 
  8.          * @return 
  9.          */  
  10.         public boolean is24(int n) {  
  11.             if (n == 1)  
  12.                 return (Math.abs(number[0] - 24) < EPISON);  
  13.             for (int i = 0; i < n; i++) {  
  14.                 for (int j = i + 1; j < n; j++) { // 进行组合  
  15.                     double a, b;  
  16.                     String expa, expb;  
  17.                     a = number[i]; // 保存起来,在方法最后再恢复,以便继续计算  
  18.                     b = number[j]; // 保存起来,在方法最后再恢复,以便继续计算  
  19.                     number[j] = number[n - 1]; // 将最后一个数挪过来  
  20.                     expa = exp[i]; // 保存起来,在方法最后再恢复,以便继续计算  
  21.                     expb = exp[j]; // 保存起来,在方法最后再恢复,以便继续计算  
  22.                     exp[j] = exp[n - 1]; // 将最后一个式子挪过来j'  
  23.                     exp[i] = "(" + expa + "+" + expb + ")"// 看看加法能否算出,如果能算出,返回true  
  24.                     number[i] = a + b;  
  25.                     if (is24(n - 1))  
  26.                         return true;  
  27.                     exp[i] = "(" + expa + "-" + expb + ")"// 看看减法能否算  
  28.                     number[i] = a - b;  
  29.                     if (is24(n - 1))  
  30.                         return true;  
  31.                     exp[i] = "(" + expb + "-" + expa + ")";  
  32.                     number[i] = b - a;  
  33.                     if (is24(n - 1))  
  34.                         return true;  
  35.                     exp[i] = "(" + expa + "*" + expb + ")"// 看看乘法能否算  
  36.                     number[i] = a * b;  
  37.                     if (is24(n - 1))  
  38.                         return true;  
  39.                     if (b != 0) {  
  40.                         exp[i] = "(" + expa + "/" + expb + ")"// 看看除法能否算  
  41.                         number[i] = a / b;  
  42.                         if (is24(n - 1))  
  43.                             return true;  
  44.                     }  
  45.                     if (a != 0) {  
  46.                         exp[i] = "(" + expb + "/" + expa + ")";  
  47.                         number[i] = b / a;  
  48.                         if (is24(n - 1))  
  49.                             return true;  
  50.                     }  
  51.                     //如果以上的加、减、乘、除都不能得到有效的结果,则恢复数据进行下一轮的计算。   
  52.                     number[i] = a; // 恢复  
  53.                     number[j] = b;  
  54.                     exp[i] = expa;  
  55.                     exp[j] = expb;  
  56.                 }  
  57.             }  
  58.             return false;  
  59.         }  

 循环的过程如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值