`

24点游戏的java实现

阅读更多

这是本人2年前业余时间写的application版本的24点游戏的简单实现。共享出来,希望能起到抛砖引玉的作用,一起探讨24点的实现。

1、计算方式的改变——引入分数计算概念

求24点涉及到除法,所以必须转变直接计算的思路。经过一段时间的摸索,本人发现可以采用分数计算。任何两个数的计算都可以转换成对应的分数计算形式。

 例如:3 / 8 可以转换成 (3/1) / (8/1)

1.1 待计算数字的初始化

于是待计算的4个值必须先转换成分数:

	private int[] aArray = new int[2];
	private int[] bArray = new int[2];
	private int[] cArray = new int[2];
	private int[] dArray = new int[2];

当然,我们得初始化它们: 效果就是2->2/ 1

		aArray[0] = a;
		aArray[1] = 1;
		bArray[0] = b;
		bArray[1] = 1;
		cArray[0] = c;
		cArray[1] = 1;
		dArray[0] = d;
		dArray[1] = 1;

 1.2 分数的计算

小学的时候就学过,分数的加减法用到最小公倍数和最大公约数。

	/**
	 * 求最小公倍数
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int leaseCommonMultiple(int a, int b) {
		return a * b / greatestCommonDivisor(a, b);
	}

	/**
	 * 求最大公约数
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int greatestCommonDivisor(int a, int b) {
		if (0 == a && 0 == b) {
			return 1;
		}
		if (0 == a) {
			return b;
		}
		if (0 == b) {
			return a;
		}
		if (a > b) {
			int c = a;
			a = b;
			b = c;
		}
		for (int c = a % b; c > 0; c = a % b) {
			a = b;
			b = c;
		}
		return b;
	}

 对应的加减方法如下:

	/**
	 * 加
	 */
	public int[] plus(int[] a, int[] b) {

		if (0 == a[1]) {
			return new int[] { 0, 0 };
		}
		if (0 == b[1]) {
			return new int[] { 0, 0 };
		}
		int denominator = leaseCommonMultiple(a[1], b[1]);

		return new int[] {
				denominator / a[1] * a[0] + denominator / b[1] * b[0],
				denominator };
	}

	/**
	 * 减
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int[] reduce(int[] a, int[] b) {
		if (0 == a[1]) {
			return new int[] { 0, 0 };
		}
		if (0 == b[1]) {
			return new int[] { 0, 0 };
		}
		int denominator = leaseCommonMultiple(a[1], b[1]);

		return new int[] {
				denominator / a[1] * a[0] - denominator / b[1] * b[0],
				denominator };
	}

 相对来说,乘除方法就简单多了:

	/**
	 * 乘
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int[] multiply(int[] a, int[] b) {
		return new int[] { a[0] * b[0], a[1] * b[1] };
	}

	/**
	 * 除
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public int[] divide(int[] a, int[] b) {
		return new int[] { a[0] * b[1], a[1] * b[0] };
	}

 

 

2、计算规则

2.1 算法——穷举法

24点的计算涉及到以下三种元素:

 待计算的4个数、三个计算符号(加减乘除)、括号

 本人采用的是穷举法,进行一个一个数值和符号的尝试——这样的话,在循环中数值和符号都必须是动态的。

	/**
	 * 动态加载符号数
	 * @param i
	 * @param a
	 * @param b
	 * @return
	 */
	public  int[] dispose(int i, int a[], int[] b){
		if(i == 0){
			return plus(a, b);
		}else if(i == 1){
			return reduce(a, b);
		}else if(i == 2){
			return multiply(a, b);
		}else{
			return divide(a, b);
		}
	}
	
	/**
	 * 动态加载计算数
	 * @param i
	 * @param a
	 * @param b
	 * @param c
	 * @param d
	 * @return
	 */
	public int[] number(int i, int[] a, int[] b, int[] c, int[] d){
		if(i == 0){
			return a;
		}else if(i == 1){
			return b;
		}else if(i == 2){
			return c;
		}else if(i == 3){
			return d;
		}else{
			return new int[]{0,1};
		}
	}

 

2.2 括号规则:

类型1:A(A(A(a,b),c),d)

类型2:A(A(a,A(b,c)),d)

类型3:A(a,A(b,A(c,d)))

类型4:A(a,A(A(b,c),d))

类型5:A(A(a,b),A(c,d))

注:A就是1个符号,A(a,b)就是指:a+b, a-b, a*b, a/b四种情况

 

2.3 数值与符号的穷举

把每个数值和符号一个进行尝试:

i,j,k        :符号

m,n,o,p  :数值

		for(int i = 0; i < 4; i++){
			for(int j = 0; j < 4; j++){
				for(int k = 0; k < 4; k++){
					for(int m = 0; m < 4; m++){
						for(int n = 0; n < 4; n++){
							if(n == m)
								continue;
							for(int o = 0; o < 4; o++){
								if(o == m || o == n)
									continue;
								for(int p = 0; p < 4; p++){
									if(p == m || p == n || p == o)
										continue;
                                                                                                                                       。。。计算方法。。。
								    
								}
							}
						}
					}
				}
			}
		}

 

计算方法:

									//类型1:A(A(A(a,b),c),d)
									int[] result1 = dispose(k,dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),number(o,a,b,c,d)),number(p,a,b,c,d));
									//类型2:A(A(a,A(b,c)),d)
									int[] result2 = dispose(k,dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),number(o,a,b,c,d))),number(p,a,b,c,d));
									//类型3:A(a,A(b,A(c,d)))
									int[] result3 = dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d))));
									//类型4:A(a,A(A(b,c),d))
									int[] result4 = dispose(i,number(m,a,b,c,d),dispose(k,dispose(j,number(n,a,b,c,d),number(o,a,b,c,d)),number(p,a,b,c,d)));									
									//类型5:A(A(a,b),A(c,d))
									int[] result5 = dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d)));
									if (0 != result1[1]) {
										if (result1[0] % result1[1] == 0) {
											if (result1[0] / result1[1] == 24) {
												if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
													map.put(new Integer(i),new Integer(i));
													map.put(new Integer(j),new Integer(j));
													map.put(new Integer(k),new Integer(k));
													count += 1;
													System.out.println("((" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + printNumber(o) + ")" + printSymbol(k) + printNumber(p));
												}
											}
										}
									}
									if (0 != result2[1]) {
										if (result2[0] % result2[1] == 0) {
											if (result2[0] / result2[1] == 24) {
												if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
													map.put(new Integer(i),new Integer(i));
													map.put(new Integer(j),new Integer(j));
													map.put(new Integer(k),new Integer(k));
													count += 1;
													System.out.println("(" + printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + printNumber(o) + "))" + printSymbol(k) + printNumber(p));
												}
											}
										}
									}
									if (0 != result3[1]) {
										if (result3[0] % result3[1] == 0) {
											if (result3[0] / result3[1] == 24) {
												if ((!map.containsKey(new Integer(i))) || (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
													map.put(new Integer(i),new Integer(i));
													map.put(new Integer(j),new Integer(j));
													map.put(new Integer(k),new Integer(k));
													count += 1;
													System.out.println(printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + "(" + printNumber(o) +  printSymbol(k) + printNumber(p) + "))");
												}
											}
										}
									}
									if (0 != result4[1]) {
										if (result4[0] % result4[1] == 0) {
											if (result4[0] / result4[1] == 24) {
												if ((!map
														.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
													map.put(new Integer(i),new Integer(i));
													map.put(new Integer(j),new Integer(j));
													map.put(new Integer(k),new Integer(k));
													count += 1;
													System.out.println(printNumber(m) + printSymbol(i) +"((" + printNumber(n) + printSymbol(j) + printNumber(o) + ")" +  printSymbol(k) + printNumber(p) + ")");
												}
											}
										}
									}
									if (0 != result5[1]) {
										if (result5[0] % result5[1] == 0) {
											if (result5[0] / result5[1] == 24) {
												if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
													map.put(new Integer(i),new Integer(i));
													map.put(new Integer(j),new Integer(j));
													map.put(new Integer(k),new Integer(k));
													count += 1;
													System.out.println("(" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + "(" + printNumber(o) + printSymbol(k) + printNumber(p) + ")");
												}
											}
										}
									}

 该程序目前存在的一些问题:

1)、存在括号多余的情况——如:1 + (2 + (3 * 7))和((2 + 7) - 1) * 3

2)、结果打印耦合在核心计算方法中

8
2
分享到:
评论
3 楼 cw550284 2010-06-25  
顶 一 下 !!!!!!!!
2 楼 wu_yaowen 2009-05-22  
在下已经把核心逻辑和打印分开了。
1 楼 wu_yaowen 2009-05-19  
估计是这个论坛回复要求太高了,浏览了这么多次的帖子,竟然我是第一个回帖的人。。。
不过我想请问的是,如果编写这个程序的测试用例,希望楼主尽快添加上来。

相关推荐

    24点游戏Java实现

    24点游戏Java实现,界面Javafx实现,一副牌中抽去大小王剩下 52 张(如果初练也可只用 1~10 这 40 张牌),任意抽取 4 张牌 (称牌组),用加、减、乘、除(可加括号)把牌面上的数算成 24。每张牌必须用一次且只能用 一...

    Java 实现24点游戏

    既可以实现24点游戏,也可以实现其他数值的游戏

    Java实现生命游戏.zip

    Java实现生命游戏Java实现生命游戏Java实现生命游戏 Java实现生命游戏Java实现生命游戏Java实现生命游戏 Java实现生命游戏Java实现生命游戏Java实现生命游戏 Java实现生命游戏Java实现生命游戏Java实现生命游戏 Java...

    java实现扫雷游戏.zip

    java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java...

    Java 实现小游戏21点

    用对话框实现游戏游玩 一共有4个Java文件 输入姓名 选择发牌或者停牌 与电脑玩家 对比 胜出或者失败

    Java实现大富翁游戏.zip

    Java实现大富翁游戏Java实现大富翁游戏Java实现大富翁游戏 Java实现大富翁游戏Java实现大富翁游戏Java实现大富翁游戏 Java实现大富翁游戏Java实现大富翁游戏Java实现大富翁游戏 Java实现大富翁游戏Java实现大富翁...

    Java实现贪吃蛇小游戏.zip

    Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏 Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏Java实现贪吃蛇小游戏 Java实现贪吃蛇小游戏Java实现贪吃蛇小...

    24点小游戏的可执行文件 - java

    这是我们利用java编写的24点小程序,生成的可执行文件。 为了得到一个24点的小游戏,首先我们需要正确的获取外界的输入,包括他们对数字、符号的选择,以及他们提交答案、获取提示等一系列的操作。其次,我们需要对...

    速算24游戏Java实现

    本资源是用Java实现的速算24游戏(老师布置的作业的代码),代码简单易懂,

    Java实现小游戏.zip

    Java实现小游戏.zipJava实现小游戏.zipJava实现小游戏.zipJava实现小游戏.zip Java实现小游戏.zipJava实现小游戏.zipJava实现小游戏.zipJava实现小游戏.zip Java实现小游戏.zipJava实现小游戏.zipJava实现小游戏.zip...

    AI五子棋游戏,Java实现.zip

    AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI五子棋游戏,Java实现AI...

    Java实现扫雷游戏.zip

    Java实现扫雷游戏.zipJava实现扫雷游戏.zipJava实现扫雷游戏.zipJava实现扫雷游戏.zip Java实现扫雷游戏.zipJava实现扫雷游戏.zipJava实现扫雷游戏.zipJava实现扫雷游戏.zip Java实现扫雷游戏.zipJava实现扫雷游戏....

    java实现五子棋游戏.zip

    java实现五子棋游戏.zipjava实现五子棋游戏.zipjava实现五子棋游戏.zip java实现五子棋游戏.zipjava实现五子棋游戏.zipjava实现五子棋游戏.zip java实现五子棋游戏.zipjava实现五子棋游戏.zipjava实现五子棋游戏.zip...

    2048小游戏的JAVA实现.zip

    2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现2048小游戏的JAVA实现...

    21点小游戏(黑杰克) java实现

    该游戏来源于21点游戏,实现人机对战。游戏说明如下: (1)该游戏需要两副牌,没有Joker,共104张。每张“纸牌”应具有花色与数字两个属性。 (2)游戏在机器与人类玩家之间进行。游戏一开始应先洗牌(将104张牌...

    java代码实现游戏连连看.zip

    java代码实现游戏连连看java代码实现游戏连连看 java代码实现游戏连连看java代码实现游戏连连看 java代码实现游戏连连看java代码实现游戏连连看 java代码实现游戏连连看java代码实现游戏连连看 java代码实现游戏...

    Java实现的扫雷游戏.zip

    Java实现的扫雷游戏.zipJava实现的扫雷游戏.zipJava实现的扫雷游戏.zip Java实现的扫雷游戏.zipJava实现的扫雷游戏.zipJava实现的扫雷游戏.zip Java实现的扫雷游戏.zipJava实现的扫雷游戏.zipJava实现的扫雷游戏.zip...

Global site tag (gtag.js) - Google Analytics