diff options
author | olim <bobq4582@gmail.com> | 2024-04-24 17:14:09 +0100 |
---|---|---|
committer | olim <bobq4582@gmail.com> | 2024-05-09 22:42:35 +0100 |
commit | 6ae6896b147cd9e012f52e15a2d5ac0beb898c44 (patch) | |
tree | 3e2a2c14dd6acbc6d72fc97ff53a758a7e38e77a /src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java | |
parent | aa97d9a5bb3e9274ac04b47c5d711c20e7b30087 (diff) | |
download | Skyblocker-6ae6896b147cd9e012f52e15a2d5ac0beb898c44.tar.gz Skyblocker-6ae6896b147cd9e012f52e15a2d5ac0beb898c44.tar.bz2 Skyblocker-6ae6896b147cd9e012f52e15a2d5ac0beb898c44.zip |
move the calculator to a util function
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java')
-rw-r--r-- | src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java | 207 |
1 files changed, 3 insertions, 204 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index e71442a5..cf621ca7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock; import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Switch; +import de.hysky.skyblocker.utils.Calculator; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; @@ -16,25 +17,6 @@ public class SignCalculator { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - public enum TokenType { - NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS - } - public static class Token { - public TokenType type; - String value; - int tokenLength; - } - private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); - private static final HashMap<String, Integer> magnitudeValues = Util.make(new HashMap<>(), map -> { - map.put("s", 64); - map.put("k", 1000); - map.put("m", 1000000); - map.put("b", 1000000000); - }); - - - - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); private static String lastInput; @@ -48,13 +30,12 @@ public class SignCalculator { //only update output if new input if (!input.equals(lastInput)) { // try { - output = evaluate(shunt(lex(input))); + output = Calculator.calculate(input); } catch (Exception e){ output = null; //todo log } } - render(context); lastInput = input; @@ -72,192 +53,10 @@ public class SignCalculator { return Long.toString(Math.round(output)); } - private static List<Token> lex(String input) { - List<Token> tokens = new ArrayList<>(); - input = input.replace(" ", "").toLowerCase().replace("x","*"); - int i = 0; - while (i < input.length()) { - Token token = new Token(); - switch (input.charAt(i)) { - case '+','-','*','/' -> { - token.type = TokenType.OPERATOR; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - } - - case '(' -> { - token.type = TokenType.L_PARENTHESIS; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - //add implicit multiplication when there is a number before brackets - if (!tokens.isEmpty() ) { - TokenType lastType = tokens.get(tokens.size()-1).type; - if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { - Token mutliplyToken = new Token(); - mutliplyToken.type = TokenType.OPERATOR; - mutliplyToken.value = "*"; - tokens.add(mutliplyToken); - } - } - } - - case ')' -> { - token.type = TokenType.R_PARENTHESIS; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - } - - default -> { - token.type = TokenType.NUMBER; - Matcher numberMatcher = NUMBER_PATTERN.matcher(input.substring(i)); - if (!numberMatcher.find()) {//invalid value to lex - throw new UnsupportedOperationException(); - } - int end = numberMatcher.end(); - token.value = input.substring(i,i + end); - token.tokenLength = end; - } - } - tokens.add(token); - - i += token.tokenLength; - } - - return tokens; - } - - private static List<Token> shunt(List<Token> tokens) { - // This is an implementation of the shunting yard algorithm - // Converts equation to use reverse polish notation - - Deque<Token> operatorStack = new ArrayDeque<>(); - List<Token> outputQueue = new ArrayList<>(); - - for (Token shuntingToken : tokens) - switch (shuntingToken.type) { - case NUMBER -> { - outputQueue.add(shuntingToken); - } - case OPERATOR -> { - int precedence = getPrecedence(shuntingToken.value); - while (!operatorStack.isEmpty()) { - Token leftToken = operatorStack.peek(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - break; - } - assert (leftToken.type == TokenType.OPERATOR); //todo why is this here - int leftPrecedence = getPrecedence(leftToken.value); - if (leftPrecedence >= precedence) { - outputQueue.add(operatorStack.pop()); - continue; - } - break; - } - operatorStack.push(shuntingToken); - } - case L_PARENTHESIS -> { - operatorStack.push(shuntingToken); - } - case R_PARENTHESIS -> { - while (true) { - if (operatorStack.isEmpty()) { - throw new UnsupportedOperationException("Unbalanced left parenthesis"); - } - Token leftToken = operatorStack.pop(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - break; - } - outputQueue.add(leftToken); - } - } - } - //empty the operator stack - while (!operatorStack.isEmpty()) { - Token leftToken = operatorStack.pop(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - throw new UnsupportedOperationException("Unbalanced left parenthesis"); - } - outputQueue.add(leftToken); - } - - return outputQueue.stream().toList(); - } - private static int getPrecedence(String operator) { - switch (operator) { - case "+","-" -> { - return 0; - } - case "*","/" -> { - return 1; - } - default -> { - throw new UnsupportedOperationException(); - } - } - } - - /** - * - * @param tokens list of Tokens in reverse polish notation - * @return answer to equation - */ - private static double evaluate(List<Token> tokens) { - Deque<Double> values = new ArrayDeque<>(); - for (Token token : tokens) { - switch (token.type) { - case NUMBER -> { - values.push(calculateValue(token.value)); - } - case OPERATOR -> { - double right = values.pop(); - double left = values.pop(); - switch (token.value) { - case "+" -> { - values.push(left + right); - } - case "-" -> { - values.push(left - right); - } - case "/" -> { - values.push(left / right); - } - case "*" -> { - values.push(left * right); - } - } - } - case L_PARENTHESIS, R_PARENTHESIS -> { - throw new UnsupportedOperationException("equation is not in RPN"); - } - } - } - return values.pop(); - } - - private static double calculateValue(String value) { - Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); - if (!numberMatcher.matches()) { - throw new UnsupportedOperationException(); - } - double number = Double.parseDouble(numberMatcher.group(1)); - String magnitude = numberMatcher.group(2); - - if (!magnitude.isEmpty()) { - if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter - throw new UnsupportedOperationException(); - } - number *= magnitudeValues.get(magnitude); - } - - return number; - } - - - private static void render(DrawContext context) { Text text; if (output == null) { - text = Text.literal("test").formatted(Formatting.RED); + text = Text.literal("Invalid Equation").formatted(Formatting.RED); } else { text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); |