10.2.4 核心处理逻辑
开发“猜数字”游戏最关键的部分在于如何通过编码实现10.1.3节中的核心处理流程,笔者将游戏相关的处理逻辑统一封装在GameService类中,该类的代码如下:
- 1 package org.liufeng.course.service;
- 2
- 3 import java.util.HashMap;
- 4 import java.util.List;
- 5 import javax.servlet.http.HttpServletRequest;
- 6 import org.liufeng.course.pojo.Game;
- 7 import org.liufeng.course.pojo.GameRound;
- 8 import org.liufeng.course.util.GameUtil;
- 9 import org.liufeng.course.util.MySQLUtil;
- 10
- 11 /**
- 12 * "猜数字"游戏业务类
- 13 *
- 14 * @author liufeng
- 15 * @date 2013-11-21
- 16 */
- 17 public class GameService {
- 18 /**
- 19 * "猜数字"游戏处理逻辑
- 20 *
- 21 * @param request 请求对象
- 22 * @param openId 用户的OpenID
- 23 * @param content 消息内容
- 24 * @return
- 25 */
- 26 public static String process(HttpServletRequest request, String openId,
- String content)
- 27 {
- 28 // 获取用户最近一次创建的游戏
- 29 Game game = MySQLUtil.getLastGame(request, openId);
- 30 // 本局游戏的正确答案
- 31 String gameAnswer = null;
- 32 // 本回合的猜测结果
- 33 String guessResult = null;
- 34 // 本局游戏的id
- 35 int gameId = -1;
- 36 // 是不是新的一局(默认为false)
- 37 boolean newGameFlag = (null == game || 0 != game.getGameStatus());
- 38 // 新的一局
- 39 if (newGameFlag) {
- 40 // 生成不重复的4位随机数作为答案
- 41 gameAnswer = GameUtil.generateRandNumber();
- 42 // 计算本回合"猜数字"的结果(xAyB)
- 43 guessResult = GameUtil.guessResult(gameAnswer, content);
- 44 // 创建game
- 45 game = new Game();
- 46 game.setOpenId(openId);
- 47 game.setGameAnswer(gameAnswer);
- 48 game.setCreateTime(GameUtil.getStdDateTime());
- 49 game.setGameStatus(0);
- 50 // 保存game并获取id
- 51 gameId = MySQLUtil.saveGame(request, game);
- 52 }
- 53 // 不是新的一局
- 54 else {
- 55 gameAnswer = game.getGameAnswer();
- 56 guessResult = GameUtil.guessResult(game.getGameAnswer(), content);
- 57 gameId = game.getGameId();
- 58 }
- 59 // 保存当前游戏回合
- 60 GameRound gameRound = new GameRound();
- 61 gameRound.setGameId(gameId);
- 62 gameRound.setOpenId(openId);
- 63 gameRound.setGuessNumber(content);
- 64 gameRound.setGuessTime(GameUtil.getStdDateTime());
- 65 gameRound.setGuessResult(guessResult);
- 66 MySQLUtil.saveGameRound(request, gameRound);
- 67 // 查询本局游戏的所有回合
- 68 List<GameRound> roundList = MySQLUtil.findAllRoundByGameId(request, gameId);
- 69 // 遍历游戏回合,组装给用户回复的消息
- 70 StringBuffer buffer = new StringBuffer();
- 71 buffer.append("查看玩法请回复:help").append("\n");
- 72 buffer.append("查看战绩请回复:score").append("\n");
- 73 for (int i = 0; i < roundList.size(); i++) {
- 74 gameRound = roundList.get(i);
- 75 buffer.append(String.format("第%d回合: %s %s", i + 1,
- 76 gameRound.getGuessNumber(), gameRound.getGuessResult())).append("\n");
- 77 }
- 78 // 胜利
- 79 if ("4A0B".equals(guessResult)) {
- 80 buffer.append("正确答案:").append(gameAnswer) .append("\n");
- 81 buffer.append("恭喜您猜对了![强]").append("\n");
- 82 buffer.append("重新输入4个不重复的数字开始新的一局。");
- 83 MySQLUtil.updateGame(request,gameId,1,GameUtil.getStdDateTime());
- 84 }
- 85 // 失败(10回合仍没猜对)
- 86 else if (roundList.size() >= 10) {
- 87 buffer.append("正确答案:").append(gameAnswer).append("\n");
- 88 buffer.append("唉,10回合都没猜出来,本局结束![流泪]").append("\n");
- 89 buffer.append("重新输入4个不重复的数字开始新的一局。");
- 90 MySQLUtil.updateGame(request, gameId, 2, GameUtil.getStdDateTime());
- 91 }
- 92 // 本回合没猜对
- 93 else {
- 94 buffer.append("请再接再厉!");
- 95 }
- 96 return buffer.toString();
- 97 }
- 98
- 99 /**
- 100 * "猜数字"游戏玩法
- 101 *
- 102 * @return String
- 103 */
- 104 public static String getGameRule() {
- 105 StringBuffer buffer = new StringBuffer();
- 106 buffer.append("《"猜数字"游戏玩法》").append("\n");
- 107 buffer.append("系统设定一个没有重复数字的4位数,由玩家来猜,每局10次机会。")
- .append("\n");
- 108 buffer.append("每猜一次,系统会给出猜测结果xAyB,x表示数字与位置
- 109 均正确的数的个数,y表示数字正确但位置不对的数的个数。").append("\n");
- 110 buffer.append("玩家根据猜测结果xAyB一直猜,直到猜中(4A0B)为止。")
- .append("\n");
- 111 buffer.append("如果10次都没猜中,系统会公布答案,游戏结束。")
- .append("\n");
- 112 buffer.append("玩家任意输入一个没有重复数字的4位数即开始游戏,例如:7890");
- 113 return buffer.toString();
- 114 }
- 115
- 116 /**
- 117 * "猜数字"游戏战绩
- 118 *
- 119 * @param request 请求对象
- 120 * @param openId 用户的OpenID
- 121 * @return
- 122 */
- 123 public static String getUserScore(HttpServletRequest request, String openId) {
- 124 StringBuffer buffer = new StringBuffer();
- 125 HashMap<Integer, Integer> scoreMap = MySQLUtil.getScoreByOpenId(request,
- openId);
- 126 if (null == scoreMap || 0 == scoreMap.size()) {
- 127 buffer.append("您还没有玩过"猜数字"游戏!").append("\n");
- 128 buffer.append("请输入4个不重复的数字开始新的一局,例如:0269");
- 129 } else {
- 130 buffer.append("您的游戏战绩如下:").append("\n");
- 131 for (Integer status : scoreMap.keySet()) {
- 132 if (0L == status) {
- 133 buffer.append("游戏中:").append(scoreMap.get(status))
- .append("\n");
- 134 } else if (1L == status) {
- 135 buffer.append("胜利局数:").append(scoreMap.get(status))
- .append("\n");
- 136 } else if (2L == status) {
- 137 buffer.append("失败局数:").append(scoreMap.get(status))
- .append("\n");
- 138 }
- 139 }
- 140 buffer.append("请输入4个不重复的数字开始新的一局,例如:0269");
- 141 }
- 142 return buffer.toString();
- 143 }
- 144 }
上述代码中的process()方法是核心处理流程的编码实现,用于处理用户每回合猜测的数字,主要说明如下。
第29行和第37行:获取用户最近一次创建的游戏,然后判断是创建新的一局游戏还是继续之前的游戏,如果数据库中没有用户的游戏记录,或者用户最近一次创建的游戏已结束(游戏状态为胜利或失败),则表示创建新的一局游戏。
第39~58行:是不是新的一局游戏关系到正确答案、猜测结果和游戏ID的获取方式。如果是新的一局游戏,正确答案和游戏ID要重新生成;如果是继续之前的游戏,正确答案和游戏ID是从数据库中获得。
第60~66行:保存当前游戏回合的数据。
第68~77行:查询出本局游戏的所有回合数据,并将每一回合的猜测数字、猜测答案追加到buffer中,方便用户推理。
第79~96行:根据猜测结果往buffer中追加不同的提示信息,如果本局游戏结束(胜利或失败),还要更新本局游戏的状态。
GameService类还有两个方法getGameRule()和getUserScore(),分别用于获取游戏玩法和用户的游戏战绩。