10.2.2 游戏算法封装

从猜数字游戏的处理流程来看,主要涉及的算法包括:验证不重复的4位数字、生成不重复的4位随机数和计算猜测结果(xAyB)。笔者将这些算法的实现统一封装到工具类GameUtil中,该类的完整代码如下:

  1. package org.liufeng.course.util;
  2.  
  3. import java.text.DateFormat;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.Random;
  7. import java.util.regex.Matcher;
  8. import java.util.regex.Pattern;
  9.  
  10. /**
  11. * 猜数字游戏的工具类
  12. *
  13. * @author liufeng
  14. * @date 2013-11-21
  15. */
  16. public class GameUtil {
  17. /**
  18. * 验证是不是4位纯数字
  19. *
  20. * @param number
  21. * @return
  22. */
  23. public static boolean verifyNumber(String number) {
  24. boolean result = false;
  25. // 正则表达式规则:0~9内的数字连续出现4次
  26. Pattern pattern = Pattern.compile("[0-9]{4}");
  27. Matcher matcher = pattern.matcher(number);
  28. // 匹配成功就表明是纯数字
  29. if (matcher.matches())
  30. result = true;
  31.  
  32. return result;
  33. }
  34.  
  35. /**
  36. * 验证是否有重复字符
  37. *
  38. * @param number
  39. * @return
  40. */
  41. public static boolean verifyRepeat(String number) {
  42. boolean result = false;
  43. // 从第2位数开始,每位都与其前面的所有数比较一遍
  44. for (int i = 1; i < number.length(); i++) {
  45. for (int j = 0; j < i; j++) {
  46. if (number.charAt(i) == number.charAt(j)) {
  47. result = true;
  48. break;
  49. }
  50. }
  51. }
  52. return result;
  53. }
  54.  
  55. /**
  56. * 生成不重复的4位随机数
  57. *
  58. * @return String
  59. */
  60. public static String generateRandNumber() {
  61. StringBuffer randBuffer = new StringBuffer();
  62. String scopeStr = "0123456789";
  63. Random random = new Random();
  64. for (int i = 0; i < 4; i++) {
  65. int num = random.nextInt(scopeStr.length());
  66. randBuffer.append(scopeStr.charAt(num));
  67. // 将每次获取到的随机数从scopeStr中移除
  68. scopeStr = scopeStr.replace(String.valueOf(scopeStr.charAt(num)), "");
  69. }
  70. return randBuffer.toString();
  71. }
  72.  
  73. /**
  74. * 计算猜测结果
  75. *
  76. * @param answer 正确答案
  77. * @param number 猜测的数字
  78. * @return xAyB
  79. */
  80. public static String guessResult(String answer, String number) {
  81. // 位置与数字均相同
  82. int rightA = 0;
  83. // 数字存在但位置不对
  84. int rightB = 0;
  85.  
  86. // 计算"A"的个数
  87. for (int i = 0; i < 4; i++) {
  88. // 位置与数字均相同
  89. if (number.charAt(i) == answer.charAt(i)) {
  90. rightA++;
  91. }
  92. }
  93.  
  94. // 计算"B"的个数
  95. for (int i = 0; i < 4; i++) {
  96. for (int j = 0; j < 4; j++) {
  97. // 位置不相同
  98. if (i != j) {
  99. if (number.charAt(i) == answer.charAt(j)) {
  100. rightB++;
  101. }
  102. }
  103. }
  104. }
  105. return String.format("%sA%sB", rightA, rightB);
  106. }
  107.  
  108. /**
  109. * 获取标准格式的时间
  110. *
  111. * @return yyyy-MM-dd hh:mm:ss
  112. */
  113. public static String getStdDateTime() {
  114. DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  115. return df.format(new Date());
  116. }
  117. }

verifyNumber()方法用于验证是不是4位纯数字,verifyRepeat()用于验证字符串中是否有重复字符,将这两个方法结合起来,就能够验证某字符串是否由不重复的4位数字组成,用法示例如下:

  1. String number = "5269";
  2. // 验证是否由不重复的4位数字组成
  3. boolean result = verifyNumber(number) && !verifyRepeat(number);
  4. // 输出结果:true
  5. System.out.println(result);

GameUtil类中的guessResult()是猜数字游戏最核心的算法,用于计算猜测结果。算法的实现并不复杂,读者结合代码中的注释很容易理解。