24点游戏是经典的纸牌益智游戏。
其游戏规则是:从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1。
基本要求:
随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式。
本程序采用了穷举法列出四个数加上三个运算符号所构成的表达式表达所有可能的结果。
算法说明:
(1)在集合{a1,a2,a3…ak}中,任取两个数字,如a1,a2,与操作符集合进行组合,分别得到一组表达式:a1*a2,a1+a2,a1-a2,a1/a2,a2-a1,a2/a1.共有6种可能的情况(其中由于"-“和”/“操作符,左右互换会导致计算结果不同,所以该组合中,包含”-“和”/"操作符的表达式各有两个,操作数先后顺序不同)。
(2)新得到的每个算式表达式,都可以集合中剩下的元素组合成新的集合,同时,将两个元素所得的运算表达式用()括起来,然后再与剩下的元素一一组合,得到新的元素集合。
(3)基于以上方法,对集合中所有元素进行两两组合,并与剩余元素形成新的集合。由此,我们得到了一组元素为k-1个的集合组。
(4)对新集合组中的每一个集合,重复以上1-3步,可得到一组包含k-2个元素的集合组…以此类推,最后会得到一组集合,其中每个集合都只包含一个元素,这个就是我们合成的最终表达式。
(5)对第四步得到的表达式集合进行求解,判断其是否等于目标数,将符合条件的过滤出来,即得到所有满足条件的表达式。
(6)对于满足条件的表达式进行输出。
以下为源代码:
import java.util.Scanner;
import java.util.Random;
public class _24points {
static int[]arg=new int[4];//四个数字
static int[]op=new int[3];//运算符三种位置
public static void main(String []args)
{
int g;//选择标志
@SuppressWarnings("resource")
Scanner sc=new Scanner(System.in);
System.out.println("*****24点游戏*****");
System.out.println("请输入1开始游戏,输入2退出游戏");
g=sc.nextInt();//获取从键盘输入的数字
//选择0,则退出游戏
if(g==2)
{
System.exit(0);
}
else
{
//用do,while循环实现先执行一次,再循环执行的功能。
do
{
System.out.println("随机生成的四个数");
Random(arg);//调用随机数生成函数,将生成的数放入数组arg[]中
Order(0);//调用排序函数
System.out.println("请选择继续游戏还是退出游戏。继续游戏请选1,退出游戏请选2");
g=sc.nextInt();//获取从键盘输入的数字
}while(g==1);
}
}
/*定义随机数函数并将随机数取余变为1~K之间的牌数*/
public static int Random(int[]arg)
{
Random r=new Random();//定义随机变量
for(int i=0;i=arg.length)
{
calculate(0, 0,"");
return;
}
for (int i = t; i < arg.length; i++)
{
two(i, t);
Order(t + 1);
two(i, t);
}
}
//数组中前两个数交换
public static void two(int i, int j) {
int t = 0;
t = arg[i];
arg[i] = arg[j];
arg[j] = t;
}
//让前两个数的结果与第三个数个数进行计算,以此类推,直到产生一个所有情况的集合
public static void calculate(int t, int num, String s) {
if (t == 4) { //如果四个数都排列组合完毕,则判断表达式是否有满足24的
if (num == 24 && correct(s))//如果表达式满足24则输出
{
System.out.println(s);
}
//else
return;
}
if (t == 0) {//如果从第一个数开始
calculate(t + 1, num + arg[t],
String.valueOf(arg[0]));
return;
}
for (int i = 0; i < 4; i++) {
if (i == 0) { //“+”号满足的条件
op[t-1] = 1;
calculate(t + 1, num + arg[t], s + "+"
+ String.valueOf(arg[t]));
}
if (i == 1) { //“-”号满足的条件
op[t-1] = 1;
if (num - arg[t] > 0) {
calculate(t + 1, num - arg[t],
s + "-" + String.valueOf(arg[t]));
}
else
{
return;
}
}
if (i == 2) { //“*”号满足的条件
op[t - 1] = 2;
calculate(t + 1, num * arg[t], s + "*" +
String.valueOf(arg[t]));
}
if (i == 3) {
op[t - 1] = 2;
if (num % arg[t] == 0) {//“/”号满足的条件
calculate(t + 1, num / arg[t],
s + "/" + String.valueOf(arg[t]));
}
else
{
return;
}
}
}
}
//验证集合中的表达式是否等于,筛选出符合24的表达式
//boolean型,并定义“*”和“/”的优先级
public static boolean correct(String s) {
int t = 0;
//"()"满足的条件及排列组合
if (op[0] == 1 && op[1] == 1 && op[2] == 2 ||
op[0] == 2&& op[1] == 1 && op[2] == 2)
{
t = s.lastIndexOf("*") > s.lastIndexOf("/") ?//定义优先级
s.lastIndexOf("*"): s.lastIndexOf("/");
System.out.println("(" + s.substring( 0,t)
+ ")" + s.substring(t));
return false;
}
else if (op[0] == 1 && op[1] == 2) //"()"满足的条件及排列组合
{
t = s.indexOf("*") > s.indexOf("/") ? //定义运算符的优先级,减少重复
s.indexOf("*") : s.indexOf("/");
System.out.println("(" + s.substring(0, t) +
")" + s.substring(t));
return false;
}
return true;
}
}