JAVA 24点游戏
题目:24点游戏
题目分析:
采用判断是否是24,四张牌用a,b,c,d来代替,中间连接的运算符有3个,中间连接的运算符op1,op2,op3;a op1 b op2 c op3 d表达式,为了简化问题,先4张牌的顺序不变,运算符4种,表达式组合情况有64种,4*4*4 = 64;加上括号之后的情况,5种情况
1、((a op1 b)op2 c)op3 d
2、(a op1 b)op2 (c op3 d)
3、(a op1 (b op2 c)op3 d)
4、a op1((b op2 c) op3 d)
5、a op1 (b op2(c op3 d))
两种情况综合,每次是给4张牌,构成表达式64*5=320,找到计算结果为24的,然后打印
算法设计:
源代码:
package TwentyFour;
import java.util.Random;
import java.util.Scanner;
/*
* 扑克牌二十四点:任意给4张扑克牌,只能够用加、减、乘、除以及适当的括号连接四张牌。
* 无论顺序,使计算结果为24,或者宣布无解。每张牌必须运算,并且只能运算一次。
* A,J,Q,K可设置为1,11,12,13
* */
public class TwentyFour
{
static char op[] = { '#', '+', '-', '*', '/' };// 存储运算符
// 定义随机产生的四个数
static int number[] = new int[4];
// 计算x op y的值
static float cal(float x, float y, int op)
{
float result = 0;
switch (op)
{
case 1:
result = x + y;
break;
case 2:
result = x - y;
break;
case 3:
result = x * y;
break;
case 4:
result = x / y;
break;
}
return result;
}
// 1计算((a op1 b)op2 c)op3 d表达式
static float cal_expression1(float i, float j, float k, float t, int op1, int op2, int op3)
{
float r1, r2, r3;
r1 = cal(i, j, op1);
r2 = cal(r1, k, op2);
r3 = cal(r2, t, op3);
return r3;
}
// 2计算(a op1 b)op2 (c op3 d)表达式
static float cal_expression2(float i, float j, float k, float t, int op1, int op2, int op3)
{
float r1, r2, r3;
r1 = cal(i, j, op1);
r2 = cal(k, t, op3);
r3 = cal(r1, r2, op2);
return r3;
}
// 3、(a op1 (b op2 c)op3 d)
static float cal_expression3(float i, float j, float k, float t, int op1, int op2, int op3)
{
float r1, r2, r3;
r1 = cal(j, k, op2);
r2 = cal(i, r1, op1);
r3 = cal(r2, t, op3);
return r3;
}
// 4、a op1((b op2 c) op3 d)
static float cal_expression4(float i, float j, float k, float t, int op1, int op2, int op3)
{
float r1, r2, r3;
r1 = cal(j, k, op2);
r2 = cal(r1, t, op3);
r3 = cal(i, r2, op1);
return r3;
}
// 5、a op1 (b op2(c op3 d))
static float cal_expression5(float i, float j, float k, float t, int op1, int op2, int op3)
{
float r1, r2, r3;
r1 = cal(k, t, op3);
r2 = cal(j, r1, op2);
r3 = cal(i, r2, op1);
return r3;
}
// 求24点,
static int get(int i, int j, int k, int t)
{
int op1, op2, op3;
int flag = 0;// 是否得到24标志,0表示未得到
// 穷举未加括号的64个表达式
for (op1 = 1; op1 <= 4; op1++)
for (op2 = 1; op2 <= 4; op2++)
for (op3 = 1; op3 <= 4; op3++)
{
// 调用表达式1计算方法
if (cal_expression1(i, j, k, t, op1, op2, op3) == 24)
{// 得到24,输出标志
System.out.println("((" + i + op[op1] + j + ")" + op[op2] + k + ")" + op[op3] + t + "=24");
flag = 1;
}
// 调用表达式2计算方法(a op1 b)op2 (c op3 d)
if (cal_expression2(i, j, k, t, op1, op2, op3) == 24)
{// 得到24,输出标志
System.out.println("(" + i + op[op1] + j + ")" + op[op2] + "(" + k + op[op3] + t + ")=24");
flag = 1;
}
// 调用表达式3计算方法(a op1 (b op2 c)op3 d)
if (cal_expression3(i, j, k, t, op1, op2, op3) == 24)
{// 得到24,输出标志
System.out.println("(" + i + op[op1] + "(" + j + op[op2] + k + ")" + op[op3] + t + ")=24");
flag = 1;
}
// 调用表达式4计算方法a op1((b op2 c) op3 d)
if (cal_expression4(i, j, k, t, op1, op2, op3) == 24)
{// 得到24,输出标志
System.out
.println("(" + i + op[op1] + "((" + j + op[op2] + k + ")" + op[op3] + t + ")" + ")=24");
flag = 1;
}
// 调用表达式5计算方法a op1 (b op2(c op3 d))
if (cal_expression5(i, j, k, t, op1, op2, op3) == 24)
{// 得到24,输出标志
System.out.println(
"(" + i + op[op1] + "(" + j + op[op2] + "(" + k + op[op3] + t + ")" + ")" + ")=24");
flag = 1;
}
}
return flag;
}
// 随机生成四个数
public static void Random(int[] p)
{
Random rand = new Random();
for (int i = 0; i < 4; i++)
{
number[i] = rand.nextInt(13) + 1;// 随机生成四个int型数
if (number[i] == 1)
{
System.out.println("A");// 如果随机生成的数为1,则显示为扑克牌牌面中的A
} else if (number[i] == 11)
{
System.out.println("J");// 如果随机生成的数为11,则显示为扑克牌牌面中的J
} else if (number[i] == 12)
{
System.out.println("Q");// 如果随机生成的数为12,则显示为扑克牌牌面中的Q
} else if (number[i] == 13)
{
System.out.println("K");// 如果随机生成的数为13,则显示为扑克牌牌面中的K
} else
{
System.out.println(number[i]);
}
}
}
public static void main(String[] args)
{
int c;
Scanner scn = new Scanner(System.in);
System.out.println("--------------------------------------------");
System.out.println("*******24点纸牌游戏******");
System.out.println("--------------------------------------------");
do
{
System.out.println("随机生成的纸牌为:\n");
Random(number);// 函数调用
if (get(number[0], number[1], number[2], number[3]) == 1)
;
else
System.out.println("对不起,这四个数得不到24");
System.out.println("1.继续游戏 2.结束\n");
c = scn.nextInt();
} while (c == 1);
}
}
调试:在运算的规程中,发现有一部分是自己算错误,如下图中的((11-1)-12)/5=24;
利用测试函数,设置断点,进行单步调试
发现变量栏里的op1,p2,op3正确,但输出不正确,发现两者不对应,改错
结果与测试:
结果:
测试代码:
public static void main(String[] args)
{
int i, j, k, t;
Scanner in = new Scanner(System.in);
System.out.println("请输入四个数(1~13):");
do
{
i = in.nextInt();
j = in.nextInt();
k = in.nextInt();
t = in.nextInt();
if (i < 1 || i > 13 || j < 1 || j > 13 || k < 1 || k > 13 || t < 1 || t > 13)
System.out.println("输入错误,请重新输入");
} while (i < 1 || i > 13 || j < 1 || j > 13 || k < 1 || k > 13 || t < 1 || t > 13);
if (get(i, j, k, t) == 1)
;
else
System.out.println("对不起,这四个数得不到24");
}
测试结果: