24點遊戲的java實現
阿新 • • 發佈:2019-01-28
這是本人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)、結果列印耦合在核心計算方法中