Move to 1.20.4

Refactored the calculator code for clarity.

Added Jacoco line to prvent issues with the bigger Material class.
This commit is contained in:
tastybento 2023-12-10 10:06:33 -08:00
parent cfb35909f0
commit cec620162b
3 changed files with 585 additions and 527 deletions

View File

@ -58,7 +58,7 @@
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
<!-- Warps addon version -->
<warps.version>1.12.0</warps.version>
@ -410,6 +410,8 @@
<!-- This is required to prevent Jacoco from adding
synthetic fields to a JavaBean class (causes errors in testing) -->
<exclude>**/*Names*</exclude>
<!-- Prevents the Material is too large to mock error -->
<exclude>org/bukkit/Material*</exclude>
</excludes>
</configuration>
<executions>

View File

@ -0,0 +1,121 @@
package world.bentobox.level.calculators;
import java.text.ParseException;
/**
* @author tastybento
*/
public class EquationEvaluator {
private static class Parser {
private final String input;
private int pos = -1;
private int currentChar;
public Parser(String input) {
this.input = input;
moveToNextChar();
}
private void moveToNextChar() {
currentChar = (++pos < input.length()) ? input.charAt(pos) : -1;
}
private boolean tryToEat(int charToEat) {
while (currentChar == ' ')
moveToNextChar();
if (currentChar == charToEat) {
moveToNextChar();
return true;
}
return false;
}
public double evaluate() throws ParseException {
double result = parseExpression();
if (pos < input.length()) {
throw new ParseException("Unexpected character: " + (char) currentChar, pos);
}
return result;
}
private double parseExpression() throws ParseException {
double result = parseTerm();
while (true) {
if (tryToEat('+'))
result += parseTerm();
else if (tryToEat('-'))
result -= parseTerm();
else
return result;
}
}
private double parseFactor() throws ParseException {
if (tryToEat('+'))
return parseFactor(); // unary plus
if (tryToEat('-'))
return -parseFactor(); // unary minus
double x;
int startPos = this.pos;
if (tryToEat('(')) { // parentheses
x = parseExpression();
tryToEat(')');
} else if ((currentChar >= '0' && currentChar <= '9') || currentChar == '.') { // numbers
while ((currentChar >= '0' && currentChar <= '9') || currentChar == '.')
moveToNextChar();
x = Double.parseDouble(input.substring(startPos, this.pos));
} else if (currentChar >= 'a' && currentChar <= 'z') { // functions
while (currentChar >= 'a' && currentChar <= 'z')
moveToNextChar();
String func = input.substring(startPos, this.pos);
x = parseFactor();
switch (func) {
case "sqrt":
x = Math.sqrt(x);
break;
case "sin":
x = Math.sin(Math.toRadians(x));
break;
case "cos":
x = Math.cos(Math.toRadians(x));
break;
case "tan":
x = Math.tan(Math.toRadians(x));
break;
case "log":
x = Math.log(x);
break;
default:
throw new ParseException("Unknown function: " + func, startPos);
}
} else {
throw new ParseException("Unexpected: " + (char) currentChar, startPos);
}
if (tryToEat('^'))
x = Math.pow(x, parseFactor()); // exponentiation
return x;
}
private double parseTerm() throws ParseException {
double x = parseFactor();
for (;;) {
if (tryToEat('*'))
x *= parseFactor(); // multiplication
else if (tryToEat('/'))
x /= parseFactor(); // division
else
return x;
}
}
}
public static double eval(final String equation) throws ParseException {
return new Parser(equation).evaluate();
}
}