利用Java編寫24點(diǎn)小游戲的實(shí)例代碼
話不多說直接給大家上代碼
package com.company;
import java.util.*;
/**
* 24點(diǎn)小游戲
* 游戲規(guī)則:系統(tǒng)自動(dòng)生成4個(gè)1-10的隨機(jī)整數(shù),玩家通過加減乘除操作,得到結(jié)果為24,每個(gè)數(shù)字只能使用一次
*/
public class Game24Player {
final String[] patterns = {"nnonnoo", "nnonono", "nnnoono", "nnnonoo",
"nnnnooo"};
final String ops = "+-*/^";//存儲(chǔ)運(yùn)算符
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點(diǎn)小游戲:");
System.out.print("使用以下數(shù)字得出24點(diǎn): ");
System.out.println(digits);
System.out.println("tips:輸入q退出游戲,輸入s打印解法以及出下一道題");
System.out.print("> ");
String line = in.nextLine();//獲取控制臺(tái)下一行輸入的內(nèi)容
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恭喜你,回答正確,請繼續(xù)下一輪 ");
digits = getSolvableDigits();
} else {
System.out.println("\n答題錯(cuò)誤,請重新答題");
}
} catch (Exception e) {
System.out.printf("%n%s 請重新輸入.%n", e.getMessage());
}
}
}
//判斷玩家在控制臺(tái)輸入的內(nèi)容是否正確
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("括號(hào)不匹配.");
}
if (parens != 0)
throw new Exception("括號(hào)不匹配.");
if (opsCount != 3)
throw new Exception("錯(cuò)誤輸入.");
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;
}
}
//獲取一組隨機(jī)數(shù)
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個(gè)1-10的隨機(jī)數(shù)
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));
}
}
運(yùn)行結(jié)果截圖
游戲題目

在控制臺(tái)輸入答案

輸入s是查看結(jié)果并開始下一次游戲。

輸入q是退出游戲。

總結(jié)
到此這篇關(guān)于利用Java編寫24點(diǎn)小游戲的文章就介紹到這了,更多相關(guān)Java編寫24點(diǎn)小游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java實(shí)現(xiàn)24點(diǎn)紙牌游戲
- java實(shí)現(xiàn)24點(diǎn)游戲
- Java實(shí)現(xiàn)24點(diǎn)小游戲
- Java編寫的24點(diǎn)紙牌游戲
- Java Swing實(shí)現(xiàn)坦克大戰(zhàn)游戲
- Java實(shí)戰(zhàn)之飛翔的小鳥小游戲
- Java實(shí)現(xiàn)五子棋游戲
- Java實(shí)現(xiàn)的迷宮游戲
- Java實(shí)戰(zhàn)入門之雙色球彩票小游戲
- Java實(shí)戰(zhàn)之貪吃蛇小游戲(源碼+注釋)
- 用Java實(shí)現(xiàn)24點(diǎn)游戲
相關(guān)文章
java后端如何調(diào)用第三方接口(往header和body中的參數(shù)傳參)
這篇文章主要介紹了java后端如何調(diào)用第三方接口(往header和body中的參數(shù)傳參),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
基于java中的null類型---有關(guān)null的9件事
這篇文章主要介紹了java中的null類型---有關(guān)null的9件事,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Java中json使用方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式, json是個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu),在web開發(fā)中應(yīng)用十分廣泛。下面通過本文給大家講解Java中json使用方法,感興趣的朋友一起看看吧2017-07-07
Spring Boot集成Druid出現(xiàn)異常報(bào)錯(cuò)的原因及解決
Druid 可以很好的監(jiān)控 DB 池連接和 SQL 的執(zhí)行情況,天生就是針對監(jiān)控而生的 DB 連接池。本文講述了Spring Boot集成Druid項(xiàng)目中discard long time none received connection異常的解決方法,出現(xiàn)此問題的同學(xué)可以參考下2021-05-05
MyBatisPlus報(bào)錯(cuò):Failed to process,please exclud
這篇文章主要介紹了MyBatisPlus報(bào)錯(cuò):Failed to process,please exclude the tableName or statementId問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
詳解Spring Boot 使用Java代碼創(chuàng)建Bean并注冊到Spring中
本篇介紹了Spring Boot 使用Java代碼創(chuàng)建Bean并注冊到Spring中,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02

