From 6de584caa0eda2f8306e808ea70e36357b95dda4 Mon Sep 17 00:00:00 2001 From: PenguinDevs <34122116+PenguinDevs@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:47:48 +1100 Subject: [PATCH 1/3] Implement calculator --- build.gradle.kts | 1 + src/main/kotlin/eu/tricht/gamesense/Main.kt | 65 ++- .../kotlin/eu/tricht/gamesense/SystemTray.kt | 5 + .../gamesense/com/steelseries/model/Frame.kt | 4 +- .../tricht/gamesense/events/EventProducer.kt | 25 + .../eu/tricht/gamesense/model/Calculator.kt | 426 ++++++++++++++++++ 6 files changed, 515 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt diff --git a/build.gradle.kts b/build.gradle.kts index 2667690..50addef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { implementation("net.java.dev.jna:jna:5.15.0") implementation("net.java.dev.jna:jna-platform:5.15.0") implementation("com.hynnet:jacob:1.18") + implementation("com.github.kwhat:jnativehook:2.2.2") } tasks { diff --git a/src/main/kotlin/eu/tricht/gamesense/Main.kt b/src/main/kotlin/eu/tricht/gamesense/Main.kt index 2154715..25d70ca 100644 --- a/src/main/kotlin/eu/tricht/gamesense/Main.kt +++ b/src/main/kotlin/eu/tricht/gamesense/Main.kt @@ -8,12 +8,17 @@ import eu.tricht.gamesense.events.EventProducer import java.util.* import java.util.prefs.Preferences import kotlin.system.exitProcess +import com.github.kwhat.jnativehook.GlobalScreen +import com.github.kwhat.jnativehook.NativeHookException +import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent +import com.github.kwhat.jnativehook.keyboard.NativeKeyListener val mapper = jacksonObjectMapper() const val GAME_NAME = "GAMESENSE_ESSENTIALS" const val CLOCK_EVENT = "CLOCK" const val VOLUME_EVENT = "VOLUME" const val SONG_EVENT = "SONG" +const val CALCULATOR_EVENT = "CALCULATOR" var timer = Timer() var client: ApiClient? = null var preferences: Preferences = Preferences.userNodeForPackage(Main::class.java) @@ -27,6 +32,8 @@ fun main() { class Main { companion object { + var eventProducer: EventProducer? = null + fun registerHandlers(client: ApiClient) { registerClockHandler(client) val volumeHandler = EventRegistration( @@ -60,6 +67,7 @@ class Main { exitProcess(1) } registerSongHandler(client) + registerCalculatorHandler(client) } fun registerClockHandler(client: ApiClient) { @@ -94,10 +102,10 @@ class Main { MultiLine( listOf( HandlerData( - contextFrameKey = "artist" + contextFrameKey = "text2" ), HandlerData( - contextFrameKey = "song" + contextFrameKey = "text1" ) ), if (preferences.get("songIcon", "true")!!.toBoolean()) 23 else 0 @@ -107,11 +115,11 @@ class Main { ), listOf( DataField( - "song", + "text1", "Song" ), DataField( - "artist", + "text2", "Artist" ) ) @@ -131,10 +139,10 @@ class Main { MultiLine( listOf( HandlerData( - contextFrameKey = "song" + contextFrameKey = "text1" ), HandlerData( - contextFrameKey = "artist" + contextFrameKey = "text2" ) ), if (preferences.get("songIcon", "true")!!.toBoolean()) 23 else 0 @@ -144,11 +152,11 @@ class Main { ), listOf( DataField( - "song", + "text1", "Song" ), DataField( - "artist", + "text2", "Artist" ) ) @@ -161,8 +169,47 @@ class Main { } } + fun registerCalculatorHandler(client: ApiClient) { + val calculatorHandler = EventRegistration( + GAME_NAME, + CALCULATOR_EVENT, + listOf( + Handler( + listOf( + MultiLine( + listOf( + HandlerData( + contextFrameKey = "text1" + ), + HandlerData( + contextFrameKey = "text2" + ) + ) + ) + ) + ) + ), + listOf( + DataField( + "text1", + "Input" + ), + DataField( + "text2", + "Answer" + ) + ) + ) + val response = client.addEvent(calculatorHandler).execute() + if (!response.isSuccessful) { + println("Failed to add calculator handler, error: " + response.errorBody()?.string()) + exitProcess(1) + } + } + fun startTimer() { - timer.schedule(EventProducer(), 0, Tick.tickRateInMs()) + eventProducer = EventProducer() + timer.schedule(eventProducer, 0, Tick.tickRateInMs()) } } } diff --git a/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt b/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt index 230bfa2..1c24b1f 100644 --- a/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt +++ b/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt @@ -35,6 +35,8 @@ class SystemTray { createSettingMenuItem("Enable song icon", "songIcon"), createSettingMenuItem("Flip song title and artist", "songInfoFlip", false), createSettingMenuItem("Display song scrolling separator", "songSeparator", false), + createSettingMenuItem("Enable calculator (Need numpad)", "calculator"), + createSettingMenuItem("Use algebraic calculator", "calculatorIsAlgebraic", false), tickRate, exit ).forEach(menu::add) @@ -66,6 +68,9 @@ class SystemTray { timer = Timer() Main.startTimer() } + if (setting == "calculatorIsAlgebraic") { + Main.eventProducer!!.calculator.reset() + } } settingMenuItem.state = preferences.get(setting, default.toString()).toBoolean() return settingMenuItem diff --git a/src/main/kotlin/eu/tricht/gamesense/com/steelseries/model/Frame.kt b/src/main/kotlin/eu/tricht/gamesense/com/steelseries/model/Frame.kt index 509d2ad..ceeacd5 100644 --- a/src/main/kotlin/eu/tricht/gamesense/com/steelseries/model/Frame.kt +++ b/src/main/kotlin/eu/tricht/gamesense/com/steelseries/model/Frame.kt @@ -1,6 +1,6 @@ package eu.tricht.gamesense.com.steelseries.model data class Frame( - val song: String, - val artist: String + val text1: String, + val text2: String ) \ No newline at end of file diff --git a/src/main/kotlin/eu/tricht/gamesense/events/EventProducer.kt b/src/main/kotlin/eu/tricht/gamesense/events/EventProducer.kt index aad05e7..06b2ddd 100644 --- a/src/main/kotlin/eu/tricht/gamesense/events/EventProducer.kt +++ b/src/main/kotlin/eu/tricht/gamesense/events/EventProducer.kt @@ -6,6 +6,7 @@ import eu.tricht.gamesense.com.steelseries.model.Data import eu.tricht.gamesense.com.steelseries.model.Event import eu.tricht.gamesense.com.steelseries.model.Frame import eu.tricht.gamesense.model.SongInformation +import eu.tricht.gamesense.model.Calculator import java.net.ConnectException import java.text.DateFormat import java.util.* @@ -20,6 +21,8 @@ class EventProducer : TimerTask() { private var displayClockPeriodically = 0 private var currentSong: SongInformation? = null private var masterVolumeTimeout = 0 + public var calculator = Calculator() + private var toggleInsertionPoint = false override fun run() { try { @@ -49,6 +52,10 @@ class EventProducer : TimerTask() { waitTicks = Tick.msToTicks(2000) return } + if (preferences.get("calculator", "true").toBoolean() && (if (!preferences.get("calculatorNumpadFlip", "false").toBoolean()) calculator.numpadOn else !calculator.numpadOn)) { + sendCalculatorEvent() + return + } val potentialSong = dataFetcher.getCurrentSong() if (preferences.get("songInfo", "true").toBoolean() && potentialSong != null && potentialSong != "") { if (currentSong == null || potentialSong != currentSong!!.fullSongName) { @@ -118,4 +125,22 @@ class EventProducer : TimerTask() { ) ).execute() } + + private fun sendCalculatorEvent() { + toggleInsertionPoint = !toggleInsertionPoint + waitTicks = Tick.msToTicks(200) + client.sendEvent( + Event( + GAME_NAME, + CALCULATOR_EVENT, + Data( + "${if (toggleInsertionPoint) {calculator.inputDisplay.replace("|", "")} else {calculator.inputDisplay.replace("|", "|")}}:${if (toggleInsertionPoint) {calculator.answerDisplay.replace("|", "")} else {calculator.answerDisplay.replace("|", "|")}}", + Frame( + if (toggleInsertionPoint) {calculator.inputDisplay.replace("|", "")} else {calculator.inputDisplay.replace("|", "|")}, + if (toggleInsertionPoint) {calculator.answerDisplay.replace("|", "")} else {calculator.answerDisplay.replace("|", "|")} + ) + ) + ) + ).execute() + } } \ No newline at end of file diff --git a/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt new file mode 100644 index 0000000..adf905f --- /dev/null +++ b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt @@ -0,0 +1,426 @@ +package eu.tricht.gamesense.model + +import eu.tricht.gamesense.preferences + +import com.github.kwhat.jnativehook.GlobalScreen +import com.github.kwhat.jnativehook.NativeHookException +import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent +import com.github.kwhat.jnativehook.keyboard.NativeKeyListener +import com.sun.jna.platform.win32.User32 +import kotlin.math.pow + +class Calculator { + private val digits = ('0'..'9').toList() + private val operators = listOf('+', '-', '*', '/', '^') + private val textMaxLength = 15 + + // Used in non-algebraic (basic) mode + private var carryOnValue = 0.0 + private var carryOnOperator: Char? = null + + private var input = "" + var inputDisplay = "|" + private var answer = "" + var answerDisplay = "" + + var numpadOn = isNumLockOn() + private var lShiftOn = false + private var rShiftOn = false + + init { + try { + // Initialize the GlobalScreen to start capturing global input events + GlobalScreen.registerNativeHook() + + GlobalScreen.addNativeKeyListener(object : NativeKeyListener { + override fun nativeKeyPressed(nativeEvent: NativeKeyEvent) { + if (nativeEvent.keyCode == 42) { // LShift + lShiftOn = true + } else if (nativeEvent.keyCode == 3638) { // RShift + rShiftOn = true + } else if (isNumpadKey(nativeEvent.keyCode)) { + if (!numpadOn) { + return + } + + val shiftOn = lShiftOn || rShiftOn + + when (nativeEvent.keyCode) { + 14 -> { // Backspace + if (!preferences.get("calculatorIsAlgebraic", "false").toBoolean()) { + if (input.isNotEmpty() && input.last() in operators.toString()) { + return + } + } + if (input.isNotEmpty()) { + input = input.dropLast(1) + updateDisplay() + } + return + } + 28 -> { // Enter + evaluate() + return + } + } + + var text = NativeKeyEvent.getKeyText(nativeEvent.keyCode).toCharArray()[0] + when (nativeEvent.keyCode) { + 53 -> { text = '/' } + 3639 -> { text = '*' } + 3658 -> { text = '-' } + 3662 -> { text = '+' } + 83 -> { text = '.' } + 7 -> if (shiftOn) { text = '^' } + 10 -> if (shiftOn) { text = '(' } + 11 -> if (shiftOn) { text = ')' } + } + + if (input.isNotEmpty() && input.last() in operators && text in operators) { + input = input.dropLast(1) + } + input += text + + if (!preferences.get("calculatorIsAlgebraic", "false").toBoolean()) { + if (text == ')' || text == '(') { + input = input.dropLast(1) + return + } + + if (when (nativeEvent.keyCode) { + 53 -> true // / + 3639 -> true // * + 3658 -> true // - + 3662 -> true // + + 7 -> shiftOn // ^ + else -> false + }) { + if (input.length <= 1) { + input = "" + return + } + evaluate(shouldCarryOnValue = true) + return + } + } + + updateDisplay() + } + } + + override fun nativeKeyReleased(nativeEvent: NativeKeyEvent) { + when (nativeEvent.keyCode) { + 42 -> { // LShift + lShiftOn = false + } + 3638 -> { // RShift + rShiftOn = false + } + 69 -> { // Numpad + numpadOn = !numpadOn + reset() + } + } + } + + }) + } catch (e: NativeHookException) { + println("There was an error registering the native hook: ${e.message}") + } + } + + private fun isNumLockOn(): Boolean { + val keyboardState = ByteArray(256) // Array to store the state of all keys + + // TODO: Add mac support... + val result = User32.INSTANCE.GetKeyboardState(keyboardState) + + if (!result) { + println("Failed to get keyboard state") + return false + } + + // Check the state of the Num Lock key (key code 0x90) + val numLockState = keyboardState[0x90].toInt() + + return numLockState and 0x01 != 0 + } + + private fun isNumpadKey(keyCode: Int): Boolean { + return when (keyCode) { + in 2..11 -> true // 0-9 + 53 -> true // / + 3639 -> true // * + 3658 -> true // - + 3662 -> true // + + 83 -> true // . + 3667 -> true // . + 14 -> true // Backspace + 28 -> true // Enter + else -> false + } + } + + fun reset(shouldUpdateDisplay: Boolean = true) { + carryOnValue = 0.0 + carryOnOperator = null + input = "" + answer = "" + if (shouldUpdateDisplay) { updateDisplay() } + } + + private fun updateDisplay(hasError: Boolean = false) { + if (hasError) { + inputDisplay = truncateDisplayText(input) + answerDisplay = "Syntax error" + return + } + + if (!preferences.get("calculatorIsAlgebraic", "false").toBoolean()) { + // Find the last occurrence of any operator + val lastOperatorIndex = input.indexOfLast { it in operators } + + if (lastOperatorIndex == -1) { + inputDisplay = "${truncateDisplayText(input)}|" + answerDisplay = truncateDisplayText(answer) + } else { + // Get the terms before and after the operator +// val beforeOperator = input.substring(0, lastOperatorIndex + 1).trim() + val afterOperator = input.substring(lastOperatorIndex + 1).trim() + + inputDisplay = truncateDisplayText("${parseValue(carryOnValue)}${carryOnOperator}") + answerDisplay = truncateDisplayText("${afterOperator}|") + } + } else { + inputDisplay = "${truncateDisplayText(input)}|" + answerDisplay = truncateDisplayText(answer) + } + } + + private fun truncateDisplayText(text: String): String { + return if (text.length <= textMaxLength) { + text + } else { + text.takeLast(textMaxLength) + } + } + + private fun precedence(op: String): Int { + return when (op) { + "+", "-" -> 1 + "*", "/" -> 2 + "^" -> 3 + else -> 0 + } + } + + private fun infixToPostfix(expression: List): List { + val result = mutableListOf() + val stack = mutableListOf() + + for (token in expression) { + when (token) { + // If the token is a number, add it to the result + !in (operators + listOf('(', ')')).toString() -> result.add(token) + "(" -> stack.add(token) + // If the token is a closing parenthesis, pop from the stack until an opening parenthesis is encountered + ")" -> { + while (stack.isNotEmpty() && stack.last() != "(") { + result.add(stack.removeAt(stack.size - 1)) + } + stack.removeAt(stack.size - 1) // Remove '(' + } + in operators.toString() -> { + // Any higher precedence operators is added first before adding lower precedence token operator + while (stack.isNotEmpty() && precedence(stack.last()) >= precedence(token)) { + result.add(stack.removeAt(stack.size - 1)) + } + stack.add(token) + } + } + } + + // Pop all the operators remaining in the stack + while (stack.isNotEmpty()) { + result.add(stack.removeAt(stack.size - 1)) + } + + return result + } + + private fun evalPostfix(postfix: List): Double { + val stack = mutableListOf() + + for (token in postfix) { + when (token) { + // If the token is a number, push it onto the stack + !in (operators + listOf('(', ')')).toString() -> stack.add(token.toDouble()) + // If the token is an operator, pop two operands and apply the operation + in listOf("+", "-", "*", "/", "^") -> { + val b = stack.removeAt(stack.size - 1) // Second operand + val a = stack.removeAt(stack.size - 1) // First operand + val result = when (token) { + "+" -> a + b + "-" -> a - b + "*" -> a * b + "/" -> a / b + "^" -> a.pow(b) + else -> throw IllegalArgumentException("Unknown operator: $token") + } + stack.add(result) // Push the result back onto the stack + } + } + } + + // The result is the last remaining item on the stack + return stack.lastOrNull() ?: throw IllegalArgumentException("Invalid expression") + } + + private fun evaluateInfix(expression: List): Double { + println(expression) + val postfix = infixToPostfix(expression) + println(postfix) + return evalPostfix(postfix) + } + + private fun stringExpressionToList(expression: String): Pair> { + val tokens = mutableListOf() + var hasTerms = false + var openingBracketCount = 0 + var constructingTerm = "" + var constructingHasDecimal = false + + fun addTerm(term: String) { + if (term.isEmpty()) { + return + } + + hasTerms = true + tokens.add(term) + constructingHasDecimal = false + } + + for (char in expression) { + if (char == '(') { + if (constructingTerm.isNotEmpty()) { + // There are digits in front of the bracket separated by any operator + addTerm(constructingTerm) + constructingTerm = "" + addTerm("*") + } else if (constructingTerm.isEmpty() && tokens.isNotEmpty() && tokens.last() == ")") { + // There is a ( directly after a ) + constructingTerm = "" + addTerm("*") + } + addTerm("(") + openingBracketCount++ + } else if (char == ')') { + openingBracketCount-- + + addTerm(constructingTerm) + constructingTerm = "" + + if (tokens.last() == "(" || tokens.last() in operators.toString()) { + // A ) cannot come after an operator or a ( + return Pair(false, emptyList()) + } + + addTerm(")") + + if (openingBracketCount < 0) { + return Pair(false, emptyList()) + } + } else if (char in operators && !hasTerms && constructingTerm.isEmpty()) { + // Cannot have an operator as first char + if (char == '-') { + // Unless it is a negative number as the first term + constructingTerm += char + } else { + println("Cannot have an operator as first char") + return Pair(false, emptyList()) + } + } else if (char in operators && (hasTerms || constructingTerm.isNotEmpty())) { + // There were digits preceding the operator + // Now register this term to items + addTerm(constructingTerm) + constructingTerm = "" + + if (tokens.last() == "(") { + // An operator cannot come immediately after a ( + return Pair(false, emptyList()) + } + + addTerm(char.toString()) + } else if (char in digits) { + constructingTerm += char + } else if (char == '.') { + if (constructingHasDecimal) { + println("There cannot be more than one decimal in a single term") + return Pair(false, emptyList()) + } + constructingTerm += '.' + constructingHasDecimal = true + } + } + + if (openingBracketCount != 0) { + // Unclosed brackets or excess closing brackets + return Pair(false, emptyList()) + } + + if (constructingTerm.isNotEmpty()) { + // There was no operator after this term to register it + addTerm(constructingTerm) + constructingTerm = "" + } + + if (tokens.isEmpty()) { + println("Expression cannot be empty") + return Pair(false, emptyList()) + } + + if (tokens.last() in operators.toString()) { + println("The last char should not be an operator") + return Pair(false, emptyList()) + } + + return Pair(true, tokens) + } + + fun evaluate(shouldCarryOnValue: Boolean = false) { + if (input.isEmpty()) { + return + } else if (shouldCarryOnValue) { + val (success, tokens) = stringExpressionToList(if (input.last() in operators) {input.dropLast(1)} else {input}) + if (success) { + val operator = input.last() + carryOnValue = evaluateInfix(tokens) + carryOnOperator = operator + input = "(${input.dropLast(1)})${operator}" + updateDisplay() + } else { + updateDisplay(hasError = true) + } + } else { + val (success, tokens) = stringExpressionToList(if (input.last() in operators) {input.dropLast(1)} else {input}) + if (success) { + inputDisplay = "" + answerDisplay = parseValue(evaluateInfix(tokens)) + reset(shouldUpdateDisplay = false) + } else { + updateDisplay(hasError = true) + } + } + } + + private fun parseValue(value: Double): String { + val string = value.toString() + + return if (string == "NaN" || string == "Infinity") { + // Likely due to a div by 0 + "Div by 0" + } else { + String.format("%.15f", value).trimEnd('0').trimEnd('.') + } + } +} \ No newline at end of file From 141b3f39c04153cf7b9cf14b9db1d6b0c62acf56 Mon Sep 17 00:00:00 2001 From: PenguinDevs <34122116+PenguinDevs@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:48:28 +1100 Subject: [PATCH 2/3] Numpad flip --- .../kotlin/eu/tricht/gamesense/SystemTray.kt | 1 + .../eu/tricht/gamesense/model/Calculator.kt | 36 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt b/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt index 1c24b1f..c2aa4a4 100644 --- a/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt +++ b/src/main/kotlin/eu/tricht/gamesense/SystemTray.kt @@ -37,6 +37,7 @@ class SystemTray { createSettingMenuItem("Display song scrolling separator", "songSeparator", false), createSettingMenuItem("Enable calculator (Need numpad)", "calculator"), createSettingMenuItem("Use algebraic calculator", "calculatorIsAlgebraic", false), + createSettingMenuItem("Flip calculator numpad", "calculatorNumpadFlip", false), tickRate, exit ).forEach(menu::add) diff --git a/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt index adf905f..0de6ca1 100644 --- a/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt +++ b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt @@ -39,7 +39,7 @@ class Calculator { } else if (nativeEvent.keyCode == 3638) { // RShift rShiftOn = true } else if (isNumpadKey(nativeEvent.keyCode)) { - if (!numpadOn) { + if (if (!preferences.get("calculatorNumpadFlip", "false").toBoolean()) !numpadOn else numpadOn) { return } @@ -65,12 +65,27 @@ class Calculator { } var text = NativeKeyEvent.getKeyText(nativeEvent.keyCode).toCharArray()[0] + if (preferences.get("calculatorNumpadFlip", "false").toBoolean()) { + when (nativeEvent.keyCode) { + 3666 -> text = '0' + 3663 -> text = '1' + 57424 -> text = '2' + 3665 -> text = '3' + 57419 -> text = '4' + 57420 -> text = '5' + 57421 -> text = '6' + 3655 -> text = '7' + 57416 -> text = '8' + 3657 -> text = '9' + } + } when (nativeEvent.keyCode) { 53 -> { text = '/' } 3639 -> { text = '*' } 3658 -> { text = '-' } 3662 -> { text = '+' } 83 -> { text = '.' } + 3667 -> { text = '.' } 7 -> if (shiftOn) { text = '^' } 10 -> if (shiftOn) { text = '(' } 11 -> if (shiftOn) { text = ')' } @@ -147,8 +162,25 @@ class Calculator { } private fun isNumpadKey(keyCode: Int): Boolean { + val numpadNumbers = if (!preferences.get("calculatorNumpadFlip", "false").toBoolean()) { + 2..11 // Numpad number keys + } else { + listOf( + 3666, // 0 + 3663, // 1 + 57424, // 2 + 3665, // 3 + 57419, // 4 + 57420, // 5 + 57421, // 6 + 3655, // 7 + 57416, // 8 + 3657, // 9 + ) // Alternative keys + } + return when (keyCode) { - in 2..11 -> true // 0-9 + in numpadNumbers -> true // 0-9 53 -> true // / 3639 -> true // * 3658 -> true // - From 40ccbf22b3e77cfe2ef16bb37089a9b547544fa8 Mon Sep 17 00:00:00 2001 From: PenguinDevs <34122116+PenguinDevs@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:27:56 +1100 Subject: [PATCH 3/3] Removed debug statements --- src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt index 0de6ca1..7c9a215 100644 --- a/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt +++ b/src/main/kotlin/eu/tricht/gamesense/model/Calculator.kt @@ -309,9 +309,7 @@ class Calculator { } private fun evaluateInfix(expression: List): Double { - println(expression) val postfix = infixToPostfix(expression) - println(postfix) return evalPostfix(postfix) }