一、问题描述:
24点游戏是经典的纸牌益智游戏。游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1)
随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式。
二、问题分析与设计:
随机生成的4张牌存在一数组中,这4个数分别用a1、a2、a3、a4表示,这4个数可以两两随机组合,得到的表达式有a+b、a-b、a*b、a/b、b-a、b/a这6种形式。每当一组计算完毕可以和剩下的方式任意组合,(前两个数和第三个数再组合)计算所有数的排列组合,然后在验证该表达式的结果是否为24,若是则输出该表达式,定义运算符的优先级来减少重复。
package practice;
import java.util.Scanner;
import java.util.Random;
public class Practice3_24points {
static int[]ran=new int[4];//随机取的4个数字
static int[]op=new int[3];//运算符operator三种位置
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();
if(g==2)
{
System.exit(0);
}
else
{
while(g==1)
{
System.out.println("随机生成的四个数");
Random(ran);//调用随机数生成函数,将生成的数放入数组ran[]中
Order(0);//调用排序函数
System.out.println("请选择继续游戏还是退出游戏。继续游戏请选1,退出游戏请选2");
g=sc.nextInt();//获取从键盘输入的数字
}
}
}
//定义随机数函数并将随机数取余变为1~K之间的牌数
public static int Random(int[]ran)
{
Random r=new Random();//定义随机变量
for(int i=0;i<ran.length;i++)
{
ran[i]=(int)(Math.abs(r.nextInt())%13+1);//返回数的绝对值
System.out.println(cards(ran[i]));
}
return 0;
}
/*
* 定义将数字变成牌数的函数,11为“J”,12为“Q”,13为“K”
*/
public static char cards(int p)
{
/*判断产生的随机数是否为1,如果为1,则返回字符*/
if(p==1)
return 'A';
else if(p<10)
return (char)(p+'0');
else if(p==10)
{
System.out.print(Integer.parseInt("10",10)); //输出(第二个)10进制数“10”在10进制下的数;
return 10;
}
else if(p==11)
return 'J';
else if(p==12)
return 'Q';
else if(p==13)
return 'K';
else
return 0;
}
public static void Order(int t) {//所有数的排列组合
//如果从第5个数开始,则计算无结果
if (t >=ran.length)
{
calculate(0, 0,"");
return;
}
for (int i = t; i < ran.length; i++)
{
two(i, t);
Order(t + 1);
two(i, t);
}
}
public static void two(int i, int j) {//数组中前两个数交换
int t = 0;
t = ran[i];
ran[i] = ran[j];
ran[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+"=24");
}
return;
}
if (t == 0) {//如果从第一个数开始
calculate(t + 1, num + ran[t],String.valueOf(ran[0])); //用法同parseInt(string a)默认返回十进制 ,返回对象原始值对象
return;
}
for (int i = 0; i < 4; i++) {
if (i == 0) { //“+”号满足的条件
op[t-1] = 1;
calculate(t + 1, num + ran[t], s +"+"+ String.valueOf(ran[t]));
}
if (i == 1) { //“-”号满足的条件
op[t-1] = 1;
if (num - ran[t] > 0) {
calculate(t + 1, num - ran[t],s + "-" + String.valueOf(ran[t]));
}
else
{
return;
}
}
if (i == 2) {//“*”号满足的条件
op[t - 1] = 2;
calculate(t + 1, num * ran[t], s + "*" +String.valueOf(ran[t]));
}
if (i == 3) {
op[t - 1] = 2;
if (num % ran[t] == 0) {//“/”号满足的条件
calculate(t + 1, num / ran[t],s + "/" + String.valueOf(ran[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("/") ?//定义优先级 lastIndexOf(String) 报告指定的 String 在此实例内的最后一个匹配项的索引位置。
s.lastIndexOf("*") : s.lastIndexOf("/");
System.out.println("("+s.substring(0,t)+")"+s.substring(t));//substring(int a,int b )从此实例检索子字符串。子字符串从指定的字符位置开始(a)且具有指定的长度(b)。
return false;
}
else if (op[0] == 1 && op[1] == 2) //"()"满足的条件及排列组合
{
t = s.indexOf("*") > s.indexOf("/") ? //定义运算符的优先级,减少重复 indexOf(String) 返回第一次出现的指定子字符串在此字符串中的索引。
s.indexOf("*") : s.indexOf("/");
System.out.println("("+s.substring(0,t)+")"+s.substring(t));
return false;
}
return true;
}
}
Continue Enhance