题目内容
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
算法分析
(1)首先利用Random类生成四个范围为1~13的随机数代表四张牌;
(2)在数组中存放这四个数的所有排列组合方式;
(3)利用穷举法列出四个数和运算符号的所有组合方式;
(4)构造每种组合方式的计算函数;
(5)利用while循环和for循环的嵌套使用求出所有能算出24点的计算式。
概要设计
利用三层for循环在四个数中间分别插入四则运算符,再调用所构造的计算函数判断能否得到24点。
源代码
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random();//随机数对象
int a = r.nextInt(13) + 1;
int b = r.nextInt(13) + 1;
int c = r.nextInt(13) + 1;
int d = r.nextInt(13) + 1;
System.out.println("随机生成四个1-13的整数");
System.out.println(a + " " + b + " " + c + " " + d);
//num数组存放四个随机数的所有排列组合
int[] num = {a, b, c, d, a, b, d, c, a, c, b, d, a, c, d, b, a, d, b, c, a, d, c, b, b, a, c, d, b, a, d, c, b,
c, a, d, b, c, d, a, b, d, a, c, b, d, c, a, c, a, b, d, c, a, d, b, c, b, a, d, c, b, d, a, c, d, a,
b, c, d, b, a, d, a, b, c, d, a, c, b, d, b, a, c, d, b, c, a, d, c, a, b, d, c, b, a};
System.out.println("所有的算法可能:");
int n = 0;
int x, y, z, w;
char[] sym = {'+', '-', '*', '/'};
int judge = 0; //judge用于判断能否得到24点
while (n < num.length) {
//逐一读取各种排列方式
x = num[n];
y = num[n + 1];
z = num[n + 2];
w = num[n + 3];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
if (express_1(x, y, z, w, sym[i], sym[j], sym[k]) == 24) { //((A_B)_C)_D
judge = 1;
if (sym[i] == sym[j] && sym[i] == sym[k]) {
System.out.println(x + "" + sym[i] + "" + y + "" + sym[j] + "" + z + "" + sym[k] + "" + w + " = 24");
continue;
} else {
System.out.println("((" + x + "" + sym[i] + "" + y + ")" + sym[j] + "" + z + ")" + sym[k] + "" + w + " = 24");
}
}
if (express_2(x, y, z, w, sym[i], sym[j], sym[k]) == 24) { //(A_(B_C))_D
judge = 1;
if (sym[i] == sym[j] && sym[i] == sym[k]) {
System.out.println(x + "" + sym[i] + "" + y + "" + sym[j] + "" + z + "" + sym[k] + "" + w + " = 24");
continue;
} else {
System.out.println("(" + x + "" + sym[i] + "(" + y + "" + sym[j] + "" + z + "))" + sym[k] + "" + w + " = 24");
}
}
if (express_3(x, y, z, w, sym[i], sym[j], sym[k]) == 24) { //A_((B_C)_D)
judge = 1;
if (sym[i] == sym[j] && sym[i] == sym[k]) {
System.out.println(x + "" + sym[i] + "" + y + "" + sym[j] + "" + z + "" + sym[k] + "" + w + " = 24");
continue;
} else {
System.out.println(x + "" + sym[i] + "((" + y + "" + sym[j] + "" + z + ")" + sym[k] + "" + w + ") = 24");
}
}
if (express_4(x, y, z, w, sym[i], sym[j], sym[k]) == 24) { //A_(B_(C_D))
judge = 1;
if (sym[i] == sym[j] && sym[i] == sym[k]) {
System.out.println(x + "" + sym[i] + "" + y + "" + sym[j] + "" + z + "" + sym[k] + "" + w + " = 24");
continue;
} else {
System.out.println(x + "" + sym[i] + "(" + y + "" + sym[j] + "(" + z + "" + sym[k] + "" + w + ")) = 24");
}
}
if (express_5(x, y, z, w, sym[i], sym[j], sym[k]) == 24) { //(A_B)_(C_D)
judge = 1;
System.out.println("(" + x + "" + sym[i] + "" + y + ")" + sym[j] + "(" + z + "" + sym[k] + "" + w + ") = 24");
}
}
}
}
n = n + 4;
}
if (judge == 0) {
System.out.println("无法得到24点!");
}
}
//通过cal函数求解两个数的加减乘除运算
public static int cal(int a, int b, char symbol) {
int z = 0;
if (symbol == '+')
z = a + b;
else if (symbol == '-')
z = a - b;
else if (symbol == '*')
z = a * b;
else if (symbol == '/')
if (b != 0)
z = a / b;
return z;
}
// 通过express_1()函数计算表达式((A_B)_C)_D
public static int express_1(int a, int b, int c, int d, char ope1, char ope2, char ope3) {
int x1, x2, x3;
x1 = cal(b, c, ope2);
x2 = cal(a, x1, ope1);
x3 = cal(x2, d, ope3);
return x3;
}
// 通过express_2()函数计算表达式(A_(B_C))_D
public static int express_2(int a, int b, int c, int d, char ope1, char ope2, char ope3) {
int x1, x2, x3;
x1 = cal(b, c, ope2);
x2 = cal(a, x1, ope1);
x3 = cal(x2, d, ope3);
return x3;
}
// 通过express_3()函数计算表达式A_((B_C)_D)
public static int express_3(int a, int b, int c, int d, char ope1, char ope2, char ope3) {
int x1, x2, x3;
x1 = cal(b, c, ope2);
x2 = cal(x1, d, ope3);
x3 = cal(a, x2, ope1);
return x3;
}
// 通过express_4()函数计算表达式A_(B_(C_D))
public static int express_4(int a, int b, int c, int d, char ope1, char ope2, char ope3) {
int x1, x2, x3;
x1 = cal(c, d, ope3);
x2 = cal(b, x1, ope2);
x3 = cal(a, x2, ope1);
return x3;
}
// 通过express_5()函数计算表达式(A_B)_(C_D)
public static int express_5(int a, int b, int c, int d, char ope1, char ope2, char ope3) {
int x1, x2, x3;
x1 = cal(a, b, ope1);
x2 = cal(c, d, ope3);
x3 = cal(x1, x2, ope2);
return x3;
}
}
测试
运行三次所得结果如下:
调试
Test1:运行程序,测试数组存放随机数:
Test2:运行程序测试判断能否得到24过程中各项赋值。
心得体会
在这次程序设计过程中,利用Random类随机生成四个数,利用穷举法解决了计算思路问题,再利用for循环的嵌套使用求解计算表达式,整体大的框架没有遇到大的问题,能够顺利得出结果,但仍存在的问题就是不能去掉结果中重复的表达式,后期还需要继续完善代码。