24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
import java.util.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class th {
private double[] poker = new double[4];
private int lives = 3; //生命值
private int score = 0; //分数
private final char [] symbol = {'1', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', 'J', 'Q', 'K'}; //显示牌面数组
private String answer = new String();
public static String playerName = new String();
//随机生成4个在1~13内的数字
public void randomPoker()
{
int i = 0;
while(i != 4)
{
poker[i] = (int)(Math.random()*14);
if(poker[i] != 0) //判断生成的数字为0跳出本次循环
i++;
else
continue;
}
}
//数字对应牌名输出
public void showPoker()
{
System.out.println("随机四张牌为:");
for(int i = 0; i < 4; i++)
{
if(poker[i] == 10)
System.out.print("10 ");
else
System.out.print(symbol[(int)poker[i]] + " ");
}
}
//判断运算符优先级
public static int getValue(String op)
{
int result;
switch (op)
{
case "+":
result=1;
break;
case "-":
result=1;
break;
case "*":
result=2;
break;
case "/":
result=2;
break;
default:
// System.out.println("不存在该运算符");
result=0;
}
return result;
}
public static List<String> toInfixExpression(String s)
{
List<String> ls = new ArrayList<String>();//存储中序表达式
int i = 0;
String str;
char c;
do
{
if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57)
{
ls.add("" + c);
i++;
} else {
str = "";
while (i < s.length() && (c = s.charAt(i)) >= 48
&& (c = s.charAt(i)) <= 57)
{
str += c;
i++;
}
ls.add(str);
}
} while (i < s.length());
Stack<String> s1=new Stack<String>();
List<String> lss = new ArrayList<String>();
for (String ss : ls)
{
if (ss.matches("\\d+"))
{
lss.add(ss);
}
else if (ss.equals("("))
{
s1.push(ss);
}
else if (ss.equals(")"))
{
while (!s1.peek().equals("("))
{
lss.add(s1.pop());
}
s1.pop();
}
else
{
while (s1.size() != 0 && getValue(s1.peek()) >= getValue(ss))
{
lss.add(s1.pop());
}
s1.push(ss);
}
}
while (s1.size() != 0) {
lss.add(s1.pop());
}
return lss;
}
public static int calculate(List<String> ls)
{
Stack<String> s=new Stack<String>();
for (String str : ls)
{
if (str.matches("\\d+"))
{
s.push(str);
}
else
{
int b = Integer.parseInt(s.pop());
int a = Integer.parseInt(s.pop());
int result=0;
if (str.equals("+"))
{
result = a + b;
}
else if (str.equals("-"))
{
result = a - b;
}
else if (str.equals("*"))
{
result = a * b;
}
else if (str.equals("\\"))
{
result = a / b;
}
s.push("" + result);
}
}
// System.out.println(s.peek());
return Integer.parseInt(s.pop());
}
//判断玩家输入运算式结果是否为24
public boolean judge(String a)
{
String rpnStr="";
for(String str:toInfixExpression(answer))
{
rpnStr+=str;
}
if(calculate(toInfixExpression(answer)) == 24)
return true;
else
return false;
}
//判断生成4个数有无运算出24的可能
public boolean pokerJudge(double[]a, int n)
{
double[] b = new double [5];
//当数组a里面的元素只剩一个的时候 对a[0]进行判断
if(n == 1)
{
if((a[0] - 24) <=1e-6 && (a[0] - 24) >= (1e-6) * -1.0)
return true;
else
return false;
}
else
{
for(int i = 0; i < n-1; i++)
{ //任选两数进行枚举
for(int j = i+1; j < n; j++)
{
int m = 0;
for(int k = 0;k < n;k++)
{
if(k != i && k != j) b[m++] = a[k]; //将剩余的数放入b数组
}
b[m] = a[i] + a[j] ; //将两数加进行递归
if(pokerJudge(b,m+1))
return true;
b[m] = a[i] - a[j] ; //将两数差进行递归
if(pokerJudge(b,m+1))
return true;
b[m] = a[j] - a[i] ; //将两数差进行递归
if(pokerJudge(b,m+1))
return true;
b[m] = a[j] * a[i] ; //将两数积进行递归
if(pokerJudge(b,m+1))
return true;
if(a[i] != 0)
{ //将两数商进行递归
b[m] = a[j]/a[i];
if(pokerJudge(b,m+1)) return true;
}
if(a[j] != 0)
{ //将两数商进行递归
b[m] = a[i]/a[j];
if(pokerJudge(b,m+1)) return true;
}
}
}
}
return false ;
}
public void play()
{
Scanner getAnswer = new Scanner(System.in);
while(lives != 0)
{
randomPoker();
if(pokerJudge(poker, 4))
{
showPoker();
System.out.println("输入你的答案");
answer = getAnswer.nextLine();
if(judge(answer))
{
score += 10;
System.out.println("回答正确");
System.out.println("当前分数" + score);
}
else
{
lives--;
System.out.println("回答错误,还有" + lives + "生命值");
}
}
else
continue;
}
System.out.println("游戏结束,分数已保存");
File file = new File("D:/TopList.txt");
FileWriter fw = null;
try {
//如果文件存在,则追加内容;如果文件不存在,则创建文件
File f=new File("D:\\TopList.txt");
fw = new FileWriter(f, true);
} catch (IOException e) {
e.printStackTrace();
}
PrintWriter pw = new PrintWriter(fw);
pw.println("玩家姓名 " + playerName + " 成绩 " + score);
pw.flush();
try {
fw.flush();
pw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void replay()
{
lives = 3;
score = 0;
}
public static void main(String[] args)
{
th Game = new th();
Scanner getName = new Scanner(System.in);
while(true)
{
System.out.println("请输入玩家姓名:");
th.playerName = getName.nextLine();
Game.play();
Game.replay();
}
//Game.outPut();
}
}