我们首先利用random函数,随机从1~13中挑选数字,挑选四次。
public static void main(String[] args) {
Random r = new Random();
int r1 = r.nextInt(13) + 1;
int r2 = r.nextInt(13) + 1;
int r3 = r.nextInt(13) + 1;
int r4 = r.nextInt(13) + 1;
int[] num = new int[]{
r1, r2, r3, r4};
}
为了让它更像卡牌,我们将1变换成A,将11,12,13变换为J、Q、K。
可以创建一个changeNum方法。
public static String changeNum(int num) {
if (num == 1) {
return "A";
} else if (num == 11) {
return "J";
} else if (num == 12) {
return "Q";
} else if (num == 13) {
return "K";
} else {
return "" + num;
}
}
这样一个随机生成的24点游戏就做好了,只需要在开头psvm处输出四个结果就好了。
比如
System.out.println(changeNum(r1) + " " + changeNum(r2) + " " + changeNum(r3) + " " + changeNum(r4));
J 8 8 Q (随机生成的)
然后我们要想办法制作一个能够自主解决的程序。计算机优势在于它的运算速度,因此我们可以使用穷举法。
首先创建一个未知数,用finalNum命名。最后我们要让它为24时输出整个式子。
然后我们需要创建三个变量,分别是math1,math2,math3,用以代表加减乘除的符号。
我试用了多层for循环嵌套,目的也是为了实现加减乘除的穷举法。但是当我写完代码后,我发现它只能按顺序来算。
比如
J 8 8 Q
会算成
-> ((11+8)/8)*12
即为: -> ((J+8)/8)*Q
注意,java的运算符中,如果使用int变量计算,除法是无法得到小数的。5/2=2而非2.5。所以我们可以在算式前加上(double)将int转换为double(灵感来自英英)。
它不能调换一下顺序,算成诸如:
-> ((11* 12)/8)+8
即为: -> ((J*Q)/8)+8
因此如何解决这个问题,成了接下来程序设计的重点。
我在原有嵌套中又多加了两层for循环嵌套,代码如下:
for (int l = 0; l < 4; l++) {
for (int m = 1; m < 4 - l; m++) {
//first
if (i == 0) {
finalNum = num[l] + num[l + m];
math1 = "+";
} else if (i == 1) {
finalNum = num[l] - num[l + m];
math1 = "-";
} else if (i == 2) {
finalNum = num[l] * num[l + m];
math1 = "*";
} else {
finalNum = num[l] / num[l + m];
math1 = "/";
}
这样,我们只需要让后面运算的两个数字不要和num[l]以及num[l+m]撞车就好啦。
我采用了这样的写法:
if (n != l && n != l + m)
总体代码再经过大体细节雕琢,全部如下:
package S1;
import java.util.Random;
public class S1 {
public static void main(String[] args) {
Random r = new Random();
int r1 = r.nextInt(13) + 1;
int r2 = r.nextInt(13) + 1;
int r3 = r.nextInt(13) + 1;
int r4 = r.nextInt(13) + 1;
int[] num = new int[]{
r1, r2, r3, r4};
System.out.println(changeNum(r1) + " " + changeNum(r2) + " " + changeNum(r3) + " " + changeNum(r4));
calculator(num);
}
public static String changeNum(int num) {
if (num == 1) {
return "A";
} else if (num == 11) {
return "J";
} else if (num == 12) {
return "Q";
} else if (num == 13) {
return "K";
} else {
return "" + num;
}
}
public static void calculator(int[] num) {
double finalNum = 0;
String math1 = "", math2 = "", math3 = "";
int times = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
for (int l = 0; l < 4; l++) {
for (int m = 1; m < 4 - l; m++) {
//first
if (i == 0) {
finalNum = num[l] + num[l + m];
math1 = "+";
} else if (i == 1) {
finalNum = num[l] - num[l + m];
math1 = "-";
} else if (i == 2) {
finalNum = num[l] * num[l + m];
math1 = "*";
} else {
finalNum = (double)num[l] / num[l + m];
math1 = "/";
}
//second
int num1;
int num2;
for (int n = 0; n < 4; n++) {
if (n != l && n != l + m) {
num1 = num[n];
if (j == 0) {
finalNum += num1;
math2 = "+";
} else if (j == 1) {
finalNum -= num1;
math2 = "-";
} else if (j == 2) {
finalNum *= num1;
math2 = "*";
} else {
finalNum /= num1;
math2 = "/";
}
for (int o = 3; o > n; o--) {
if (o != l && o != l + m) {
num2 = num[o];
//third
if (k == 0) {
finalNum += num2;
math3 = "+";
} else if (k == 1) {
finalNum -= num2;
math3 = "-";
} else if (k == 2) {
finalNum *= num2;
math3 = "*";
} else {
finalNum /= num2;
math3 = "/";
}
if (finalNum == 24) {
times += 1;
System.out.println("找到第" + times + "个解决方法:");
System.out.println(" -> ((" + num[l] + "" + math1 + num[l + m] + ")" + math2 + num1 + ")" + math3 + num2);
System.out.println("即为:" + " -> ((" + changeNum(num[l]) + "" + math1 + changeNum(num[l + m]) + ")" + math2 + changeNum(num1) + ")" + math3 + changeNum(num2));
System.out.println();
}
}
}
}
}
}
}
}
}
}
}
}
测试几个结果如下:
K 3 K 8
找到第1个解决方法:
-> ((13 + 3) - 13) * 8
即为: -> ((K + 3) - K ) * 8
找到第2个解决方法:
-> ((3 + 13) - 13) * 8
即为: -> ((3 + K) - K ) * 8
找到第3个解决方法:
-> ((13 + 8) - 13) * 3
即为: -> ((K + 8) - K ) * 3
找到第4个解决方法:
-> ((13 - 13) + 3) * 8
即为: -> ((K - K) + 3 ) * 8
找到第5个解决方法:
-> ((3 - 13) + 13) * 8
即为: -> ((3 - K) + K ) * 8
找到第6个解决方法:
-> ((3 * 8) + 13) - 13
即为: -> ((3 * 8) + K ) - K
找到第7个解决方法:
-> ((3 * 8) - 13) + 13
即为: -> ((3 * 8) - K ) + K
找到第8个解决方法:
-> ((13 * 8) * 3) / 13
即为: -> ((K * 8) * 3 ) / K
找到第9个解决方法:
-> ((3 * 8) * 13) / 13
即为: -> ((3 * 8) * K ) / K
找到第10个解决方法:
-> ((13 * 3) / 13) * 8
即为: -> ((K * 3) / K ) * 8
找到第11个解决方法:
-> ((3 * 13) / 13) * 8
即为: -> ((3 * K) / K ) * 8
找到第12个解决方法:
-> ((3 * 8) / 13) * 13
即为: -> ((3 * 8) / K ) * K
找到第13个解决方法:
-> ((13 * 8) / 13) * 3
即为: -> ((K * 8) / K ) * 3
找到第14个解决方法:
-> ((13 / 13) * 3) * 8
即为: -> ((K / K) * 3 ) * 8
找到第15个解决方法:
-> ((3 / 13) * 13) * 8
即为: -> ((3 / K) * K ) * 8
K 7 5 K
找到第1个解决方法:
-> ((5 + 13) + 13) - 7
即为: -> ((5 + K) + K) - 7
找到第2个解决方法:
-> ((13 + 5) - 7) + 13
即为: -> ((K + 5) - 7) + K
找到第3个解决方法:
-> ((13 + 13) - 7) + 5
即为: -> ((K + K) - 7) + 5
找到第4个解决方法:
-> ((13 - 7) + 5) + 13
即为: -> ((K - 7) + 5) + K
6 3 5 3
找到第1个解决方法:
-> ((6 + 5) - 3) * 3
即为: -> ((6 + 5) - 3) * 3
找到第2个解决方法:
-> ((6 - 3) + 5) * 3
即为: -> ((6 - 3) + 5) * 3
找到第3个解决方法:
-> ((5 - 3) + 6) * 3
即为: -> ((5 - 3) + 6) * 3
找到第4个解决方法:
-> ((3 * 5) + 6) + 3
即为: -> ((3 * 5) + 6) + 3
找到第5个解决方法:
-> ((5 * 3) + 6) + 3
即为: -> ((5 * 3) + 6) + 3
找到第6个解决方法:
-> ((6 * 5) - 3) - 3
即为: -> ((6 * 5) - 3) - 3
7 A 5 K
找到第1个解决方法:
-> ((5 + 13) + 7) - 1
即为: -> ((5 + K) + 7) - A
找到第2个解决方法:
-> ((7 + 5) - 1) + 13
即为: -> ((7 + 5) - A) + K
找到第3个解决方法:
-> ((7 + 13) - 1) + 5
即为: -> ((7 + K) - A) + 5
找到第4个解决方法:
-> ((7 - 1) + 5) + 13
即为: -> ((7 - A) + 5) + K
…
//(不知道为什么CSDM的乘号*有点bug,经常会显示错误,所以有一些我就在乘号两边加上空格了)
我还在学习之中,代码一定是不够优化的甚至可能存在bug。也希望大家对我批评纠正,互相学习。