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的,然后打印

算法设计:

JAVA 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;

JAVA 24点游戏

利用测试函数,设置断点,进行单步调试

JAVA 24点游戏

发现变量栏里的op1,p2,op3正确,但输出不正确,发现两者不对应,改错

JAVA 24点游戏

结果与测试:

结果:

JAVA 24点游戏

测试代码:

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");
}

测试结果:

JAVA 24点游戏