人机交互打字游戏
要求
做一个人机交互的打字游戏。
提取类:
Game类
genStr:可以随机输出字符串。
printResult: Player类
levelNo:玩家的级别号
currentScore:得分
startTime:开始时间
elapedTime:已用时间。
使用知识点
1.面向对象编程(OOP)基本原则
封装:所有的数据(如玩家得分、字符串长度、关卡参数等)和行为(如生成字符串、计算得分等)都被封装在相应的类中。
继承:使用了类的继承机制。例如,NumGenImpl, AbcGenImpl, MixGenImpl 这几个类都继承了 IGenStrategy 接口,重写了 genString 方法,展现了多态的特性。
多态:通过接口 IGenStrategy 和其具体实现类(如 NumGenImpl),Game 类可以通过传入不同的策略类(如数字生成、字母生成或混合生成)来改变字符串生成的方式,展示了多态。
抽象:通过接口 IGenStrategy,在 Game 类中我们不关心具体的字符串生成逻辑,只需要知道有一个 genString 方法,这就隐藏了具体实现的细节。
2. 接口和实现
接口(Interface):IGenStrategy 是一个接口,定义了生成字符串的方法 genString,而具体的生成逻辑由 NumGenImpl, AbcGenImpl, MixGenImpl 等类来实现。接口是实现多态的基础。
实现类:NumGenImpl, AbcGenImpl, MixGenImpl 是具体的实现类,它们实现了 IGenStrategy 接口,并根据不同的逻辑生成字符串。
3. 构造函数(Constructor)
每个类(如 Player, Level, Game)都通过构造函数初始化实例变量(如玩家等级、字符串生成策略等)。构造函数用于初始化对象时为对象分配初始值。
4. 随机数生成(Random)
使用 Random 类来生成随机数字或字符,这为字符串生成策略提供了基础。Random.nextInt() 方法被用来生成随机的数字和字符。
5. 字符串处理
StringBuilder:在 NumGenImpl, AbcGenImpl, MixGenImpl 类中,使用了 StringBuilder 来动态生成字符串,这是因为 StringBuilder 更适合处理字符串的拼接操作,相比于 String 类,它效率更高。
charAt():charAt() 方法用于获取字符串中指定位置的字符,这在字母生成策略中用于从字母表中随机挑选字符。
6. 控制台输入输出
使用 Scanner 类从控制台获取用户输入(例如,玩家输入的字符串),并通过 System.out.println() 向玩家显示提示信息或结果。
输出格式:通过 System.out.printf() 输出用时,使用了 %.2f 格式化输出时间,确保精确到小数点后两位。
7. 时间处理
使用 System.currentTimeMillis() 获取当前时间的毫秒数,来计算游戏的开始时间和已用时间。
8. 数组和集合
数组:在 LevelParams 类中,使用了一个数组 levels[] 来存储多个关卡的设置。这样可以方便地扩展和管理多个关卡。
增强的 for 循环:在 Game 类中的 start() 方法中,使用了增强的 for 循环遍历所有关卡,并为每个关卡生成相应的字符串。
9. 条件判断与循环
使用 if 条件语句判断玩家输入的字符串是否正确,若正确则增加分数。
for 循环:用 for 循环遍历多个关卡,或者在每个关卡内遍历字符串的生成次数。
10. 方法参数和返回值
方法参数:方法如 genString(int length) 采用了方法参数来动态传入生成字符串所需的长度,显示了方法如何接受输入并根据不同的输入生成不同的输出。
方法返回值:方法如 genString() 返回了一个生成的字符串,用于游戏逻辑中的比较和计分。
实际代码
import java.util.Random;
import java.util.Scanner;// 1. IGenStrategy接口
interface IGenStrategy {String genString(int length);
}// 2. 数字字符串生成策略
class NumGenImpl implements IGenStrategy {@Overridepublic String genString(int length) {StringBuilder sb = new StringBuilder();Random rand = new Random();for (int i = 0; i < length; i++) {sb.append(rand.nextInt(10)); // 生成数字 0-9}return sb.toString();}
}// 3. 字母字符串生成策略
class AbcGenImpl implements IGenStrategy {@Overridepublic String genString(int length) {StringBuilder sb = new StringBuilder();Random rand = new Random();String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";for (int i = 0; i < length; i++) {sb.append(characters.charAt(rand.nextInt(characters.length())));}return sb.toString();}
}// 4. 混合字符串生成策略(字母+数字)
class MixGenImpl implements IGenStrategy {@Overridepublic String genString(int length) {StringBuilder sb = new StringBuilder();Random rand = new Random();String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";for (int i = 0; i < length; i++) {sb.append(characters.charAt(rand.nextInt(characters.length())));}return sb.toString();}
}// 5. Player类
class Player {int levelNo; // 玩家等级int score; // 当前得分long startTime; // 游戏开始时间long elapsedTime; // 游戏已用时间public Player(int levelNo) {this.levelNo = levelNo;this.score = 0;}public void startGame() {startTime = System.currentTimeMillis();}public void endGame() {elapsedTime = System.currentTimeMillis() - startTime;}public void addScore(int score) {this.score += score;}
}// 6. Level类(关卡类)
class Level {int levelNo; // 关卡编号int strLength; // 字符串长度int strTimes; // 每关字符串出现次数long limitedTime; // 限时int perScore; // 每个正确的得分public Level(int levelNo, int strLength, int strTimes, long limitedTime, int perScore) {this.levelNo = levelNo;this.strLength = strLength;this.strTimes = strTimes;this.limitedTime = limitedTime;this.perScore = perScore;}
}// 7. LevelParams类(关卡参数类)
class LevelParams {Level[] levels; // 关卡集合public LevelParams(Level[] levels) {this.levels = levels;}
}// 8. Game类(游戏类)
class Game {private Player player; // 玩家private IGenStrategy iGenStrategy; // 字符串生成策略private LevelParams levelParams; // 关卡参数public Game(Player player, IGenStrategy iGenStrategy, LevelParams levelParams) {this.player = player;this.iGenStrategy = iGenStrategy;this.levelParams = levelParams;}public String genStr(int levelNo) {Level level = levelParams.levels[levelNo - 1];return iGenStrategy.genString(level.strLength); // 根据当前策略生成字符串}public void printResult() {System.out.println("游戏结束!");System.out.println("得分: " + player.score);System.out.printf("用时: %.2f 秒\n", player.elapsedTime / 1000.0);}public void start() {Scanner scanner = new Scanner(System.in);player.startGame();// 遍历每一个关卡for (Level level : levelParams.levels) {String target = genStr(level.levelNo); // 生成当前关卡的字符串System.out.println("Level " + level.levelNo + " - 请输如下字符串(长度: " + level.strLength + "):");System.out.println(target);// 按关卡要求进行字符串输入与检查for (int i = 0; i < level.strTimes; i++) {String input = scanner.nextLine();if (input.equals(target)) {System.out.println("正确!");player.addScore(level.perScore); // 得分} else {System.out.println("错误!应为:" + target);}}}player.endGame();printResult(); // 打印最终成绩和用时}public static void main(String[] args) {// 创建不同的关卡Level level1 = new Level(1, 10, 3, 60000, 10); // Level 1Level level2 = new Level(2, 15, 3, 60000, 20); // Level 2LevelParams levelParams = new LevelParams(new Level[]{level1, level2});// 创建玩家和游戏策略(可以更改为其他策略)Player player = new Player(1);IGenStrategy strategy = new NumGenImpl(); // 可以切换为 AbcGenImpl 或 MixGenImpl// 创建游戏对象并开始游戏Game game = new Game(player, strategy, levelParams);game.start();}
}