纯java打字游戏/QuickHit/java课程阶段练习
压缩包可以去我的github下载
https://github.com/CienYu/QucikHit/tree/master
项目结构图

使用说明
#测试环境: jdk1.8
#测试软件: idea
#编码格式: utf-8
#version: 2.0
#version note:
2.0
no和role的功能存在重复,将no和role分开,no为玩家等级,role为玩家段位,游戏难度由role决定
no改为玩家等级的提升通过题数,role的提升通过积分,两者相辅相成
role
0: Rookie
1: credit>getCreditLimit() && no>getNoLimit()
no
0: 0
1: queSum>getQueLimit(this.role.getValue)
1.0
no与枚举值绑定,游戏难度随着角色变化而变化
#游戏配置和参数请在config中的Setting中修改
#主要涉及知识: 字符串的处理,文件I/O操作,常用数据结构,java反射知识,java计时器,异常处理,枚举类
#本项目仅作学期java课程总结,且存在部分为了使用而使用的代码结构,代码不一定没有bug,欢迎反馈
#by:Cien
config文件夹下的Setting类
package day411.project.config;
/**
* @Author Cien
* @Date 2022/4/11 15:36
* @Version 2.0
* @Note 游戏配置类
*/
public class Setting {
//存档目录
private static final String catalogue = "F:\\存档.txt";
//中文开关
private static final boolean havachinese = false;
//趣味开关
private static final boolean Comment = false;
//段位对应时间规定
private static final Long[] TimeLimit = new Long[]{3l,5l,7l,10l,15l,20l,10l};
//段位对应字符串长度
private static final Integer[] StrLimit = new Integer[]{3,5,10,10,15,20,50};
//段位对应积分要求
private static final Integer[] CreditLimit = new Integer[]{10,40,90,130,210,310,460};
//段位对应加分
private static final Integer[] InCreditLimit = new Integer[]{1,3,5,7,9,10,15};
//段位对应等级要求
private static final Integer[] NoLimit = new Integer[]{0,1,2,3,4,5,6};
//等级对应题数要求
private static final Integer[] QueLimit = new Integer[]{3,5,7,9,10,13,15};
public static Integer getQueLimit(Integer roleNo){
return QueLimit[roleNo];
}
public static Integer getNoLimit(Integer roleNo){
return NoLimit[roleNo];
}
public static Long getTime(Integer roleNo){
return TimeLimit[roleNo];
}
public static Integer getStrLength(Integer roleNo){
return StrLimit[roleNo];
}
public static Integer getCreditLimit(Integer roleNo){
return CreditLimit[roleNo];
}
public static Integer getInCredit(Integer roleNo){
return InCreditLimit[roleNo];
}
public static Boolean gethavachinese(){
return havachinese;
}
public static Boolean getComment(){
return Comment;
}
public static String getCatalogue(){
return catalogue;
}
public static String successPoem(){
String str = "";
int a = (int) (Math.random() * 5);
switch (a){
case 1:
str="白衣走马执霜雪,不枉人间少年郎.";break;
case 2:
str="明年此日青云去,却笑人间举子忙";break;
case 3:
str="夫何瑰逸之令姿,独旷世以秀群";break;
case 4:
str="绿蚁新醅酒,红泥小火炉。晚来天欲雪,能饮一杯无?";break;
default:
//若教眼底无离恨,不信人间有白头
str="直道相思了无益,未妨惆怅是清狂";break;
}
return str;
}
public static String failurePoem(){
String str = "";
int a = (int) (Math.random() * 5);
switch (a){
case 1:
str="人生若只如初见,何事秋风悲画扇";break;
case 2:
str="欲买桂花同载酒,终不似,少年游。";break;
case 3:
str="惆怅东栏一株雪,人生看得几清明。";break;
case 4:
str="休言万事转头空,未转头时皆梦。";break;
default:
str="试问岭南应不好,却道:此心安处是吾乡。";break;
}
return str;
}
//后续增加泛型?
public <T> T fun(T t){
return t ;
}
}
config文件下的PlayerEnums类
package day411.project.config;
import day411.project.Player;
import static day411.project.config.Setting.getCreditLimit;
/**
* @Author Cien
* @Date 2022/4/11 16:09
* @Version 1.0
* @Note 枚举类
*/
public enum PlayerEnums {
Rookie(0,"菜鸟"),
Introduction(1,"入门"),
Primary(2,"初"),
Intermediate(3,"中"),
Advanced(4,"高"),
GodLike(5,"接近神明"),
Legendary(6,"超神");
private final int value ;
private final String description;
private PlayerEnums(int value, String description) {
this.value = value;
this.description = description;
}
public int getValue() {
return value;
}
public String getDescription() {
return description;
}
public static PlayerEnums getUserEnums(Integer value){
PlayerEnums[] values = PlayerEnums.values();
PlayerEnums p=Legendary;
for (PlayerEnums pe:values) {
if(value==pe.value){
p=pe;
}
}
return p;
}
}
utils文件夹下的FileUtils类
package day411.project.utils;
import day411.project.Player;
import day411.project.config.PlayerEnums;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @Author Cien
* @Date 2022/4/11 22:24
* @Version 1.0
* @Note 文件工具类
*/
public class FileUtils {
//实体类转map
public static Map<String, Object> entityToMap(Object object) {
Map<String, Object> map = new HashMap<>();
//获取声明字段并遍历放入map中
for (Field field : object.getClass().getDeclaredFields()) {
try {
//field.isAccessible()在jdk1.9后废弃,教室环境使用field.canAccess
//boolean flag = field.isAccessible();
//boolean flag = field.canAccess(o);
//设置访问权限
field.setAccessible(true);
Object o = field.get(object);
map.put(field.getName(), o);
field.setAccessible(true);
} catch (Exception e) {
System.err.println("反射获取值出现问题");
}
}
return map;
}
//String转map
public static Map<String, Object> stringToMap(String str){
Map<String, Object> map = new HashMap<>();
StringBuffer sbf = new StringBuffer();
char[] chars = str.toCharArray();
for (char c: chars) {
if(c!='{' && c!='}' && c!=','){
sbf.append(c);
}
}
String[] strings = sbf.toString().split("\\ ");
for (String s: strings) {
map.put(s.substring(0, s.indexOf("=")), s.substring(s.indexOf("=")+1, s.length()) );
}
return map;
}
//map转实体类
public static Player mapToEntry(Map<String,Object> map){
Player p = new Player();
try {
p.setNo(Integer.valueOf(map.get("no").toString()));
p.setCredit(Integer.valueOf(map.get("credit").toString()));
p.setQueSum(Integer.valueOf(map.get("queSum").toString()));
p.setRightQueSum(Integer.valueOf(map.get("rightQueSum").toString()));
p.setRole(PlayerEnums.valueOf(map.get("role").toString()));
System.out.println("读取数据成功,已为你继承上次数据");
} catch (NumberFormatException e) {
Scanner in= new Scanner(System.in);
System.err.println("存档数据存在问题,是否初始化数据(y/n):");
String i = in.nextLine();
if("y".equals(i)){
p.init();
System.out.println("初始化成功");
}else {
stop();
}
}
return p;
}
//中断
public static void stop(){
System.out.println("请更换存档或检查数据,see you again!");
System.exit(0);
}
}
utils文件夹下的StrUtuils类
package day411.project.utils;
import java.io.UnsupportedEncodingException;
import java.util.Random;
/**
* @Author Cien
* @Date 2022/4/12 17:54
* @Version 1.0
* @Note 字符工具类
*/
public class StrUtuils {
//生成单个小写字母
public static char getLowercaseChar(){
Random random = new Random();
int num = random.nextInt(26)+97;
char a = (char)num;
//System.out.println(a);
return a;
}
//生成单个大写字母
public static char getUppercaseChar(){
Random random = new Random();
int num = random.nextInt(26)+65;
char a = (char)num;
//System.out.println(a);
return a;
}
//生成数字字符
public static char getFiguresChar(){
Random random = new Random();
int num = random.nextInt(32)+33;
char a = (char)num;
//System.out.println(a);
return a;
}
//生成汉字
public static String getchineseStr() {
String str = null;
int hightPos, lowPos; // 定义高低位
Random random = new Random();
//这里采用GBK格式生成汉字,而gbk中汉字是双字节
//获取高位值
hightPos = (176 + Math.abs(random.nextInt(39)));
//获取低位值
lowPos = (161 + Math.abs(random.nextInt(93)));
byte[] b = new byte[2];
b[0] = (new Integer(hightPos).byteValue());
b[1] = (new Integer(lowPos).byteValue());
try {
// 转成中文
str = new String(b, "GBK");
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
return str;
}
}
FileWR类
package day411.project;
import java.io.*;
import static day411.project.config.Setting.getCatalogue;
import static day411.project.utils.FileUtils.*;
/**
* @Author Cien
* @Date 2022/4/11 17:48
* @Version 1.0
* @Note 存档读取类
*/
public class FileWR {
private final String catalogue = getCatalogue();
//判断存档是否存在
public boolean fileExist() {
File file = new File(catalogue);
boolean flag;
if(!file.exists()){
flag = false;
}else{
flag = true;
}
return flag;
}
//存档
public void fileWirte(Player p) {
try {
Writer fw = new FileWriter(catalogue);
String str = entityToMap(p).toString().trim();
fw.write(str);
System.out.println("存档成功");
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//读取存档
public Player fileRead() {
StringBuffer sbf=new StringBuffer();
try {
File file = new File(catalogue);
Reader fr = new FileReader(file);
char[] ch = new char[(int)file.length()];
int length=fr.read(ch);
while ((length!= -1)) {
sbf.append(ch);
length=fr.read();
}
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
Player p1 = mapToEntry(stringToMap(sbf.toString()));
System.out.println("当前用户等级为:"+p1.getNo()+",积分为:"+p1.getCredit());
return p1;
}
}
Play类
package day411.project;
import java.util.Scanner;
import static day411.project.config.Setting.getTime;
/**
* @Author Cien
* @Date 2022/4/11 17:12
* @Version 1.0
* @Note 游戏主类
*/
public class Play {
public void gameMain(Player p){
TimeClock tc = new TimeClock();
Scanner in = new Scanner(System.in);
RandomString randomString = new RandomString();
String str = randomString.getStr(p.getRole().getValue());
tc.startTime();
System.out.println("计时开始,你有"+getTime(p.getRole().getValue())+"秒时间进行填写");
System.out.println(str);
String userStr = in.nextLine();
Long time = tc.endTime();
System.out.println("用时"+time+"秒");
p.isSuccess(str,userStr,time);
p.rank();
}
public Player getPlayer(Player p){
FileWR fwr = new FileWR();
//读取数据
if(!fwr.fileExist()){
System.out.println("指定位置没有存档文件,或者无存档数据,已为你初始化数据");
p.init();
}else {
System.out.println("读取数据中...");
p = fwr.fileRead();
}
return p;
}
public static void main(String[] args) {
Play play = new Play();
Player p = new Player();
FileWR fwr = new FileWR();
Scanner in = new Scanner(System.in);
p = play.getPlayer(p);
p.rank();
while (true){
System.out.println("输入1开始游戏,2查看当前数据,3保存数据,4退出游戏");
String flag = in.next();
switch (flag){
case "1":play.gameMain(p);;break;
case "2":p.print();break;
case "3":fwr.fileWirte(p);break;
}
if("4".equals(flag)) {
System.out.println("see you again");
break;
}
}
}
}
Player类
package day411.project;
import day411.project.config.PlayerEnums;
import java.util.Scanner;
import static day411.project.config.PlayerEnums.*;
import static day411.project.config.Setting.*;
import static day411.project.utils.FileUtils.stop;
/**
* @Author Cien
* @Date 2022/4/11 15:26
* @Version 2.0
* @Note 玩家类
*/
public class Player {
/**
* 玩家等级
*/
private Integer no;
/**
* 玩家段位,且与游戏难度挂钩
*/
private PlayerEnums role;
/**
* 积分
*/
private Integer credit;
/**
* 已做题数
*/
private Integer queSum;
/**
* 正确题数
*/
private Integer rightQueSum;
/**
* 正确率
*/
//private Long accuracy;
public Player() {
}
public void init(){
this.no= 0 ;
this.credit = 0;
this.queSum = 0;
this.rightQueSum = 0;
this.role = PlayerEnums.Rookie;
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public Integer getCredit() {
return credit;
}
public void setCredit(Integer credit) {
this.credit = credit;
}
public Integer getQueSum() {
return queSum;
}
public void setQueSum(Integer queSum) {
this.queSum = queSum;
}
public Integer getRightQueSum() {
return rightQueSum;
}
public void setRightQueSum(Integer rightQueSum) {
this.rightQueSum = rightQueSum;
}
public PlayerEnums getRole() {
return role;
}
public void setRole(PlayerEnums role) {
this.role = role;
}
private void addCredit(){
Integer increase= getInCredit(this.role.getValue());
this.credit+=increase;
System.out.println("输入正确,积分增加"+increase+"分,当前正确率为"+getAccuracy()+"%");
}
//玩家等级和段位提升
public void rank(){
if(this.queSum>=getQueLimit(this.role.getValue()) && this.no!=6){
this.no+=1;
System.out.println("题数满足要求,等级+1,当前等级为:"+this.no);
}
if(this.role!=Legendary&&this.credit>getCreditLimit(this.role.getValue()) && this.no>getNoLimit(this.role.getValue())){
this.role = getUserEnums(this.role.getValue()+1);
System.out.println("积分和等级满足晋级条件,你已是"+this.role.getDescription()+"级强者");
}
}
private boolean isQuick(Long ltime){
boolean flag=false;
if(ltime<=getTime(this.no)){
flag=true;
}
return flag;
}
private String getAccuracy(){
String accuracy = null;
try {
if(this.queSum==0){
accuracy="0";
}else {
accuracy=String.format("%.2f", (rightQueSum*1.0/queSum)*100);
}
} catch (Exception e) {
System.err.println("读取到的题数存在空指针异常,请检查数据和代码");
Scanner in= new Scanner(System.in);
System.err.println("题数存在问题,是否初始化题数数据(y/n):");
String i = in.nextLine();
if("y".equals(i)){
this.queSum=0;
this.rightQueSum=0;
System.out.println("初始化成功");
}else {
stop();
}
}
return accuracy;
}
private void success(){
if(getComment()){
System.out.println(successPoem());
}
setQueSum(getQueSum()+1);
setRightQueSum(getRightQueSum()+1);
addCredit();
}
private void fail(){
if(getComment()){
System.out.println(failurePoem());
}
setQueSum(getQueSum()+1);
System.out.println("输入错误,当前正确率为"+getAccuracy()+"%");
}
public void isSuccess(String str, String userStr, Long time){
if(str.equals(userStr)||str.trim().equals(userStr.trim())){
if(!isQuick(time)){
System.out.println("超过规定时间,不予加分");
}else {
success();
}
}else{
fail();
}
}
public void print(){
System.out.println("玩家等级为:"+this.no+",游戏难度为:"+this.role.getDescription()+"级,积分为:"+this.credit+"分,已尝试:"+this.getQueSum()+"关,通过:"+this.getRightQueSum()+"关");
}
}
RandomString类
package day411.project;
import static day411.project.config.Setting.getStrLength;
import static day411.project.config.Setting.gethavachinese;
import static day411.project.utils.StrUtuils.*;
/**
* @Author Cien
* @Date 2022/4/11 11:34
* @Version 1.0
* @Note 字符生成类
*/
public class RandomString {
/*
* 纯恶搞
*/
private static String Legendary(){
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < 30; i++) {
if(gethavachinese()){
sbf.append(getchineseStr());
}else {
sbf.append(getLowercaseChar());
sbf.append(getUppercaseChar());
sbf.append(getFiguresChar());
}
}
return sbf.toString();
}
private static StringBuffer insertSpace(StringBuffer sbf, Integer roleNo){
if(gethavachinese() && ((int) (Math.random() * 2)) == 1){
int len = sbf.toString().replaceAll(" ", "").length();
if (len%5==0 && roleNo != 6) {
sbf.append((char)32);
}
sbf.append(getchineseStr());
}
return sbf;
}
/*
* 获取对应难度的字符串
*/
public String getStr(Integer roleNo){
StringBuffer sbf = new StringBuffer();
int len = 0;
for (int i = 0; i < getStrLength(roleNo); i++) {
switch (roleNo){
case 0:
case 1:
case 2:
sbf.append(getLowercaseChar());
sbf=insertSpace(sbf,roleNo);
break;
case 3:
case 4:
if ((int) (Math.random() * 2) == 1) {
sbf.append(getLowercaseChar());
} else {
sbf.append(getUppercaseChar());
}
sbf=insertSpace(sbf,roleNo);
break;
case 5:
case 6:
if ((int) (Math.random() * 3) == 1) {
sbf.append(getLowercaseChar());
} else if((int) (Math.random() * 3) == 2){
sbf.append(getUppercaseChar());
}else {
sbf.append(getFiguresChar());
}
sbf=insertSpace(sbf,roleNo);
break;
default:
sbf.append(Legendary());break;
}
len = sbf.toString().replaceAll(" ", "").length();
if (len%5==0 && roleNo != 6) {
sbf.append((char)32);
}
}
return sbf.toString();
}
}
TimeClock类
package day411.project;
/**
* @Author Cien
* @Date 2022/4/11 11:58
* @Version 1.0
* @Note 计时类
*/
public class TimeClock {
private long startTime = 0;
private long endTime = 0;
//开始计时
public void startTime(){
//获取当前系统时间
startTime = System.currentTimeMillis();
}
//结束计时并返回耗时
public Long endTime(){
//获取当前的系统时间,与初始时间相减就是程序运行的毫秒数,除以1000就是秒数
endTime = System.currentTimeMillis();
long usedTime = (endTime-startTime)/1000;
return usedTime;
}
}

浙公网安备 33010602011771号