`
he91_com
  • 浏览: 373448 次
文章分类
社区版块
存档分类
最新评论

24点游戏算法

 
阅读更多

24点游戏算法

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

24点游戏的说明:

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

算法描述

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

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

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

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

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

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

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

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

/**
		 * 他的主要想法是
		 * 先对四个数中的任意两个数进行四则运算,得到的结果加剩余的两个数还有三个数
		 * 再对三个数中的任意两个数进行四则运算,得到的结果加剩余的一个数还有二个数
		 * 再对剩余的两个数进行四则运算,得到的结果如果是24,就说明该表达式能得到24,表达式正确;
		 * 如果结果不是24,则说明表达式不正确
		 * @param n
		 * @return
		 */
		public boolean is24(int n) {
			if (n == 1)
				return (Math.abs(number[0] - 24) < EPISON);
			for (int i = 0; i < n; i++) {
				for (int j = i + 1; j < n; j++) { // 进行组合
					double a, b;
					String expa, expb;
					a = number[i]; // 保存起来,在方法最后再恢复,以便继续计算
					b = number[j]; // 保存起来,在方法最后再恢复,以便继续计算
					number[j] = number[n - 1]; // 将最后一个数挪过来
					expa = exp[i]; // 保存起来,在方法最后再恢复,以便继续计算
					expb = exp[j]; // 保存起来,在方法最后再恢复,以便继续计算
					exp[j] = exp[n - 1]; // 将最后一个式子挪过来j'
					exp[i] = "(" + expa + "+" + expb + ")"; // 看看加法能否算出,如果能算出,返回true
					number[i] = a + b;
					if (is24(n - 1))
						return true;
					exp[i] = "(" + expa + "-" + expb + ")"; // 看看减法能否算
					number[i] = a - b;
					if (is24(n - 1))
						return true;
					exp[i] = "(" + expb + "-" + expa + ")";
					number[i] = b - a;
					if (is24(n - 1))
						return true;
					exp[i] = "(" + expa + "*" + expb + ")"; // 看看乘法能否算
					number[i] = a * b;
					if (is24(n - 1))
						return true;
					if (b != 0) {
						exp[i] = "(" + expa + "/" + expb + ")"; // 看看除法能否算
						number[i] = a / b;
						if (is24(n - 1))
							return true;
					}
					if (a != 0) {
						exp[i] = "(" + expb + "/" + expa + ")";
						number[i] = b / a;
						if (is24(n - 1))
							return true;
					}
					//如果以上的加、减、乘、除都不能得到有效的结果,则恢复数据进行下一轮的计算。 
					number[i] = a; // 恢复
					number[j] = b;
					exp[i] = expa;
					exp[j] = expb;
				}
			}
			return false;
		}

循环的过程如下


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics