Java24点游戏
24点游戏
游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
程序的实现:
-中缀表达式转后缀表达式
/**
*
* @Description:中缀表达式转后缀表达式
* @param array
* @return 后缀表达式
*/
public String[] toSuffixExpression(String[] array) {
List<String> newArry = new ArrayList<String>();// 用来存储后缀表达式
Stack<String> stack = new Stack<String>();
for (int i = 0; i < array.length; i++) {
if ("(".equals(array[i])) { // 如果是左括号,则入栈
stack.push(array[i]);
} else if ("+".equals(array[i]) || "-".equals(array[i]) || "*".equals(array[i]) || "/".equals(array[i])) {
if (!stack.empty()) {
String s = stack.pop();// 先取出栈顶的运算符
if (comparePrior(array[i], s)) { // 如果栈值优先级小于要入栈的值,则继续压入栈
stack.push(s);
} else { // 否则取出值
newArry.add(s);
}
}
stack.push(array[i]);
} else if (")".equals(array[i])) { // 如果是")",则出栈,一直到遇到"("
while (!stack.empty()) {
String s = stack.pop();
if (!"(".equals(s)) {
newArry.add(s);
} else {
break;
}
}
} else {
newArry.add(array[i]);// 如果是数字直接放入后缀表达式中
}
}
while (!stack.empty()) {
String s = stack.pop();// 将栈中剩余的运算符依次取出放入后缀表达式中
newArry.add(s);
}
return newArry.toArray(new String[0]);
}
- 后缀表达式的计算
/**
*
* @Description:计算后缀表达式
* @param output
* @return 计算结果
*/
public int calculate(String[] output) {
LinkedList temp = new LinkedList();// 定义一个临时栈用来保存中间结果
for (int i = 0; i < output.length; i++) {
if (isOperation(output[i])) {// 遍历output若遇到操作符,则从栈中退出两个数字
int num1 = Integer.parseInt(String.valueOf(temp.pop()));
int num2 = Integer.parseInt(String.valueOf(temp.pop()));
int res = cal(num2, num1, output[i]);// 计算运算结果
temp.push(res);// 将计算结果入栈
} else {// 若遇到操作数则直接入栈
temp.push(output[i]);
}
}
int i = 0;
try{
i=Integer.parseInt(String.valueOf(temp.pop()));
}
catch (Exception e) {
// TODO: handle exception
System.out.println("");
}
return i;
}
/**
*
* @Description:进行运算符运算
* @param num2
* @param num1
* @param ts
* @return 运算结果
*/
private int cal(int num2, int num1, String ts) {
switch (ts) {
case "+":
return num2 + num1;
case "-":
return num2 - num1;
case "*":
return num2 * num1;
case "/":
if (num1 != 0)
return num2 / num1;
}
return 0;
}
/**
*
* @Description:判断字符是否为运算符
* @param c
* @return true|false
*/
private boolean isOperation(String c) {
if (c.equals("-") || c.equals("+") || c.equals("*") || c.equals("/") || c.equals("#") || c.equals("(")
|| c.equals(")")) {
return true;
} else
return false;
}
- 具体规则的实现
/**
*
*<p>Title:GameMenu</p>
*<p>Description:实现游戏交互功能</p>
* @author dynamic
* @date 2018年9月26日 下午8:19:08
* */
public class GameMenu {
int score;
int live = 3;
StringBuilder s;
public StringBuilder getS() {
return s;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getLive() {
return live;
}
public void setLive(int life) {
this.live = life;
}
/**
*
* @Description:模拟纸牌
* @return(展示方法参数和返回值)
*/
public StringBuilder randomCards() {
Random r = new Random();
s = new StringBuilder();
String a[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
int i = 4;
while (--i >= 0) {
s.append(a[r.nextInt(13)]);
s.append("\t");
}
return s;
}
/**
*
* @Description:接受用户输入的表达式并计算是否正确
* @param game(展示方法参数和返回值)
*/
public void menu(GameMenu game) {
MyStack stack = new MyStack();
boolean flag = false;
System.out.println("您抽到的纸牌为:" + game.randomCards());
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// 分割成表达式数组
String[] arry = input.split(" ");
String[] newArry = new MyStack().toSuffixExpression(arry);
int res = stack.calculate(newArry);
if (res == 24) {
System.out.println("正确,加分 ");
game.score += 5;
} else {
--game.live;
System.out.println("错误,生命值减一,您还有 " + game.live + "次机会");
}
}
/**
*
* @Description:保存分数
* @param g
* @throws IOException(展示方法参数和返回值)
*/
public void save(GameMenu g) throws IOException {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Scanner scanner = new Scanner(System.in);
FileWriter fWriter = new FileWriter(new File("TopList.txt"), true);
BufferedWriter bWriter = new BufferedWriter(fWriter);
StringBuilder s = new StringBuilder();
s.append("账号:");
s.append(String.valueOf(df.format(new Date())));
s.append("\t成绩:\t");
s.append(g.getScore());
bWriter.write(String.valueOf(s));
bWriter.newLine();
bWriter.close();
System.out.println("保存已成功");
}
/**
*
* @Description:实现计时器功能要求用户在规定时间内输入表达式
* @param gameMenu(展示方法参数和返回值)
*/
public void show(GameMenu gameMenu){
Scanner scanner = new Scanner(System.in);
new Thread() {
public void run() {
gameMenu.menu(gameMenu);
if(gameMenu.getLive()<1){
System.exit(0);
}
}
}.start();
new Thread() {
public void run() {
for (int i = 0; i <100; ) {
try {
Thread.sleep(1000);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
gameMenu.live--;
System.out.println("时间到!,进入下一题");
if(gameMenu.getLive()>=1){
show(gameMenu);
}
if(gameMenu.getLive()<1){
if (gameMenu.getLive() < 1) {
System.out.println("游戏结束");
int choose = 1;
if (choose == 1) {
try {
gameMenu.save(gameMenu);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.exit(0);
}
}
}.start();
}
public static void main(String[] args) throws InterruptedException, IOException {
GameMenu g = new GameMenu();
g.show(g);
}
}
- 运行结果: