一、题目分析
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
二、算法构造
设计思路:
1.利用Random类随机产生4个随机纸牌数
2.利用Thread类,使用多线程,进行游戏倒计时
3.由用户输入包括这4个数的算数表达式的字符串
4.利用javascript中的eval()函数,通过一定途径来执行javascript,将字符串转化为算数表达式 ,得到 结果为Interger包装类,赋值给result
5.定义t=24,将其自动装箱
6.创建文件TopList.txt
7.若result与t相等,则得分加10,将结果写入TopList.txt中;若不等,则生命值减少一(初始生命值为5),将结果也写入TopList.txt中。
8.当生命值或时间减少为零时,弹出“是否游戏继续”,若继续,则再玩一次;若退出,将所有结果存入文件,退出游戏。
三、流程图
四、调试
- 对javascript中的eval()函数调试
- 对产生随机数的测试
- 对文件保存功能的测试
五、测试
- 产生4个随机数
- 将数字表达式字符串转为数字表达式
- 对文件的处理
- 多线程的使用
六、运行结果
将游戏结果保存在TopList.txt中
七、经验归纳
1.在这次编程中,最大的亮点在于:
由于程序要求中需要输入包含随机产生数字的表达式来使运算结果为24,所以,会思考——如何使带有算数式的字符串转换为算数表达式,再将结果输出?在Python和JavaScript都存在eval()函数,可实现如上功能。但是java中没有eval()函数,所以通过其他途径来执行javascript即可。
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName(“js”);
engine.eval(字符串);
2.对包装类进行练习。
3.对线程的使用。由于程序要一边进行24点计算,一边倒计时,所以使用线程完成多任务。
八、源代码
package com.game;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Point24 {
static int[] a = new int[4];
private static void time() {
int time = 10;
System.out.println("游戏只有10秒钟....游戏开始:");
System.out.println();
while (time > 0) {
time--;
int score = 0;
int life = 3;
try {
Random r = new Random();// 随机生成4个随机数
int k = 0;
while (k < 4) {
a[k] = r.nextInt(13) + 1;
k++;
}
System.out.println("随机产生的纸牌数为:"+Arrays.toString(a));
System.out.println("请输入包含上述数字的表达式(可包含括号): ");
while (true) {
Thread.sleep(1000);
time--;
int ss = time % 60;
System.out.println("还剩" + ss + "秒");
Scanner sc = new Scanner(System.in);// 输入算术符号
String s = sc.next();
//字符串转化为算数表达式
//java无法解决,但javascript中有一个eval()函数,可以执行,所以, 通过其他途径来执行javascript即可
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Integer result = null;
result = (Integer) engine.eval(s);
System.out.println(result);
int t = 24;
Integer w = new Integer(t);
// 判断表达式的值是否为24
if (result.equals(w)) {
score += 10;
System.out.println("回答正确! 加10分,当前得分为: " + score);
try {
File file = new File("./TopList.txt");
// 文件不存在时,主动创建文件
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file, true);//append为true,可保证刚才游戏记录存在
BufferedWriter bw = new BufferedWriter(fw);
bw.write("还剩" + time + "s时" + "游戏得分:" + score);//游戏得分写入文件
bw.write("\n");
bw.close();
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
life--;
System.out.println("回答错误! 生命值减1! 当前剩余生命值为: " + life);
try {
File file = new File("./TopList.txt");
// 文件不存在时,主动创建文件
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file, true);//append为true,可保证刚才游戏记录存在
BufferedWriter bw = new BufferedWriter(fw);
bw.write("当前生命值为:" + life);//将生命值写入文件
bw.write("\n");
bw.close();
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (life == 0) {
System.out.println();
System.out.println("生命值已用尽!!! 继续游戏--1,退出游戏--2");
System.out.println("游戏记录以保存至文件");
int go1 = sc.nextInt();
if (go1 == 2) {
System.out.println("游戏已结束");
break;
} else {
time();
}
}
if (time == 0) {
System.out.println();
System.out.println("时间到!!! 继续游戏--1,退出游戏--2");
System.out.println("游戏记录以保存至文件");
int go2 = sc.nextInt();
if (go2 == 2) {
System.out.println("游戏已结束");
break;
} else {
time();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ScriptException e) {
e.printStackTrace();
}
break;
}
}
public static void main(String[] args) {
//若文件不存在,则创建;若存在,清空已有的文件内容,以便下次重新写入新的内容
File file = new File("./TopList.txt");
try {
if ( !file.exists() ) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file);
fileWriter.write("");
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
time();
}
}