利用Java编写24点小游戏的实例代码

2021-01-12 0 601

话不多说直接给大家上代码

package com.company;

import java.util.*;

/**
 * 24点小游戏
 * 游戏规则:系统自动生成4个1-10的随机整数,玩家通过加减乘除操作,得到结果为24,每个数字只能使用一次
 */
public class Game24Player {

 final String[] patterns = {\"nnonnoo\", \"nnonono\", \"nnnoono\", \"nnnonoo\",
   \"nnnnooo\"};
 final String ops = \"+-*/^\";//存储运算符

 String solution;//解题答案
 List<Integer> digits;

 public static void main(String[] args) {
  new Game24Player().play();
 }

 void play() {
  digits = getSolvableDigits();

  Scanner in = new Scanner(System.in);
  while (true) {
   System.out.println(\"24点小游戏:\");
   System.out.print(\"使用以下数字得出24点: \");
   System.out.println(digits);
   System.out.println(\"tips:输入q退出游戏,输入s打印解法以及出下一道题\");
   System.out.print(\"> \");

   String line = in.nextLine();//获取控制台下一行输入的内容
   if (line.equalsIgnoreCase(\"q\")) {
    System.out.println(\"\\nThanks for playing\");
    return;
   }

   if (line.equalsIgnoreCase(\"s\")) {
    System.out.println(solution);
    digits = getSolvableDigits();
    continue;
   }

   char[] entry = line.replaceAll(\"[^*+-/)(\\\\d]\", \"\").toCharArray();

   try {
    validate(entry);

    if (evaluate(infixToPostfix(entry))) {
     System.out.println(\"\\n恭喜你,回答正确,请继续下一轮 \");
     digits = getSolvableDigits();
    } else {
     System.out.println(\"\\n答题错误,请重新答题\");
    }

   } catch (Exception e) {
    System.out.printf(\"%n%s 请重新输入.%n\", e.getMessage());
   }
  }
 }

 //判断玩家在控制台输入的内容是否正确
 void validate(char[] input) throws Exception {
  int total1 = 0, parens = 0, opsCount = 0;

  for (char c : input) {
   if (Character.isDigit(c))
    total1 += 1 << (c - \'0\') * 4;
   else if (c == \'(\')
    parens++;
   else if (c == \')\')
    parens--;
   else if (ops.indexOf(c) != -1)
    opsCount++;
   if (parens < 0)
    throw new Exception(\"括号不匹配.\");
  }

  if (parens != 0)
   throw new Exception(\"括号不匹配.\");

  if (opsCount != 3)
   throw new Exception(\"错误输入.\");

  int total2 = 0;
  for (int d : digits)
   total2 += 1 << d * 4;

  if (total1 != total2)
   throw new Exception(\"输入有误.\");
 }

 boolean evaluate(char[] line) throws Exception {
  Stack<Float> s = new Stack<>();
  try {
   for (char c : line) {
    if (\'0\' <= c && c <= \'9\')
     s.push((float) c - \'0\');
    else
     s.push(applyOperator(s.pop(), s.pop(), c));
   }
  } catch (EmptyStackException e) {
   throw new Exception(\"输入无效,请重新输入.\");
  }
  return (Math.abs(24 - s.peek()) < 0.001F);
 }

 float applyOperator(float a, float b, char c) {
  switch (c) {
   case \'+\':
    return a + b;
   case \'-\':
    return b - a;
   case \'*\':
    return a * b;
   case \'/\':
    return b / a;
   default:
    return Float.NaN;
  }
 }

 //获取一组随机数
 List<Integer> randomDigits() {
  Random r = new Random();
  List<Integer> result = new ArrayList<>(4);
  for (int i = 0; i < 4; i++)
   result.add(r.nextInt(9) + 1);//添加4个1-10的随机数
  return result;
 }

 List<Integer> getSolvableDigits() {
  List<Integer> result;
  do {
   result = randomDigits();
  } while (!isSolvable(result));
  return result;
 }

 boolean isSolvable(List<Integer> digits) {
  Set<List<Integer>> dPerms = new HashSet<>(4 * 3 * 2);
  permute(digits, dPerms, 0);

  int total = 4 * 4 * 4;
  List<List<Integer>> oPerms = new ArrayList<>(total);
  permuteOperators(oPerms, 4, total);

  StringBuilder sb = new StringBuilder(4 + 3);

  for (String pattern : patterns) {
   char[] patternChars = pattern.toCharArray();

   for (List<Integer> dig : dPerms) {
    for (List<Integer> opr : oPerms) {

     int i = 0, j = 0;
     for (char c : patternChars) {
      if (c == \'n\')
       sb.append(dig.get(i++));
      else
       sb.append(ops.charAt(opr.get(j++)));
     }

     String candidate = sb.toString();
     try {
      if (evaluate(candidate.toCharArray())) {
       solution = postfixToInfix(candidate);
       return true;
      }
     } catch (Exception ignored) {
     }
     sb.setLength(0);
    }
   }
  }
  return false;
 }

 String postfixToInfix(String postfix) {
  class Expression {
   String op, ex;
   int prec = 3;

   Expression(String e) {
    ex = e;
   }

   Expression(String e1, String e2, String o) {
    ex = String.format(\"%s %s %s\", e1, o, e2);
    op = o;
    prec = ops.indexOf(o) / 2;
   }
  }

  Stack<Expression> expr = new Stack<>();

  for (char c : postfix.toCharArray()) {
   int idx = ops.indexOf(c);
   if (idx != -1) {

    Expression r = expr.pop();
    Expression l = expr.pop();

    int opPrec = idx / 2;

    if (l.prec < opPrec)
     l.ex = \'(\' + l.ex + \')\';

    if (r.prec <= opPrec)
     r.ex = \'(\' + r.ex + \')\';

    expr.push(new Expression(l.ex, r.ex, \"\" + c));
   } else {
    expr.push(new Expression(\"\" + c));
   }
  }
  return expr.peek().ex;
 }

 char[] infixToPostfix(char[] infix) throws Exception {
  StringBuilder sb = new StringBuilder();
  Stack<Integer> s = new Stack<>();
  try {
   for (char c : infix) {
    int idx = ops.indexOf(c);
    if (idx != -1) {
     if (s.isEmpty())
      s.push(idx);
     else {
      while (!s.isEmpty()) {
       int prec2 = s.peek() / 2;
       int prec1 = idx / 2;
       if (prec2 >= prec1)
        sb.append(ops.charAt(s.pop()));
       else
        break;
      }
      s.push(idx);
     }
    } else if (c == \'(\') {
     s.push(-2);
    } else if (c == \')\') {
     while (s.peek() != -2)
      sb.append(ops.charAt(s.pop()));
     s.pop();
    } else {
     sb.append(c);
    }
   }
   while (!s.isEmpty())
    sb.append(ops.charAt(s.pop()));

  } catch (EmptyStackException e) {
   throw new Exception(\"Invalid entry.\");
  }
  return sb.toString().toCharArray();
 }

 void permute(List<Integer> lst, Set<List<Integer>> res, int k) {
  for (int i = k; i < lst.size(); i++) {
   Collections.swap(lst, i, k);
   permute(lst, res, k + 1);
   Collections.swap(lst, k, i);
  }
  if (k == lst.size())
   res.add(new ArrayList<>(lst));
 }

 void permuteOperators(List<List<Integer>> res, int n, int total) {
  for (int i = 0, npow = n * n; i < total; i++)
   res.add(Arrays.asList((i / npow), (i % npow) / n, i % n));
 }
}

运行结果截图

游戏题目

利用Java编写24点小游戏的实例代码

在控制台输入答案

利用Java编写24点小游戏的实例代码

输入s是查看结果并开始下一次游戏。

利用Java编写24点小游戏的实例代码

输入q是退出游戏。

利用Java编写24点小游戏的实例代码

总结

到此这篇关于利用Java编写24点小游戏的文章就介绍到这了,更多相关Java编写24点小游戏内容请搜索自学编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持自学编程网!

遇见资源网 JAVA 利用Java编写24点小游戏的实例代码 http://www.ox520.com/20345.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务