diff --git a/core/src/com/unciv/logic/IdHelper.kt b/core/src/com/unciv/logic/IdHelper.kt index 67ac95bab3..6419ad4090 100644 --- a/core/src/com/unciv/logic/IdHelper.kt +++ b/core/src/com/unciv/logic/IdHelper.kt @@ -1,6 +1,7 @@ package com.unciv.logic import java.util.* +import kotlin.math.abs /** * This class checks whether a Game- or Player-ID matches the old or new format. @@ -34,13 +35,13 @@ object IdChecker { val trimmedPlayerId = id.trim() if (trimmedPlayerId.length == 40) { // length of a UUID (36) with pre- and postfix if (!trimmedPlayerId.startsWith(prefix, true)) { - throw IllegalArgumentException("Not a valid ID. Does not start with prefix " + prefix) + throw IllegalArgumentException("Not a valid ID. Does not start with prefix $prefix") } val checkDigit = trimmedPlayerId.substring(trimmedPlayerId.lastIndex, trimmedPlayerId.lastIndex +1) // remember, the format is: P-9e37e983-a676-4ecc-800e-ef8ec721a9b9-5 val shortenedPlayerId = trimmedPlayerId.substring(2, 38) val calculatedCheckDigit = getCheckDigit(shortenedPlayerId).toString() - if (!calculatedCheckDigit.equals(checkDigit)) { + if (calculatedCheckDigit != checkDigit) { throw IllegalArgumentException("Not a valid ID. Checkdigit invalid.") } return shortenedPlayerId @@ -56,10 +57,11 @@ object IdChecker { */ fun getCheckDigit(uuid: String): Int { // allowable characters within identifier + @Suppress("SpellCheckingInspection") val validChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVYWXZ-" var idWithoutCheckdigit = uuid // remove leading or trailing whitespace, convert to uppercase - idWithoutCheckdigit = idWithoutCheckdigit.trim().toUpperCase(Locale.ENGLISH) + idWithoutCheckdigit = idWithoutCheckdigit.trim().uppercase(Locale.ENGLISH) // this will be a running total var sum = 0 @@ -68,15 +70,14 @@ object IdChecker { for (i in idWithoutCheckdigit.indices) { //set ch to "current" character to be processed - val ch = idWithoutCheckdigit.get(idWithoutCheckdigit.length - i - 1) + val ch = idWithoutCheckdigit[idWithoutCheckdigit.length - i - 1] // throw exception for invalid characters if (validChars.indexOf(ch) == -1) - throw IllegalArgumentException( - ch + " is an invalid character") + throw IllegalArgumentException("$ch is an invalid character") // our "digit" is calculated using ASCII value - 48 - val digit = ch.toInt() - 48 + val digit = ch.code - 48 // weight will be the current digit's contribution to // the running total @@ -104,7 +105,7 @@ object IdChecker { } // avoid sum less than 10 (if characters below "0" allowed, // this could happen) - sum = Math.abs(sum) + 10 + sum = abs(sum) + 10 // check digit is amount needed to reach next number // divisible by ten diff --git a/core/src/com/unciv/models/simulation/Simulation.kt b/core/src/com/unciv/models/simulation/Simulation.kt index af27a1874b..71d97854d9 100644 --- a/core/src/com/unciv/models/simulation/Simulation.kt +++ b/core/src/com/unciv/models/simulation/Simulation.kt @@ -4,33 +4,36 @@ import com.unciv.logic.GameInfo import com.unciv.logic.GameStarter import com.unciv.models.ruleset.VictoryType import com.unciv.models.metadata.GameSetupInfo -import java.lang.Integer.max -import java.time.Duration +import kotlin.time.Duration import kotlin.concurrent.thread +import kotlin.math.max +import kotlin.time.ExperimentalTime -class Simulation(val newGameInfo: GameInfo, - val simulationsPerThread: Int = 5, - val threadsNumber: Int = 1, - val maxTurns: Int = 1000 +@ExperimentalTime +class Simulation( + private val newGameInfo: GameInfo, + val simulationsPerThread: Int = 5, + private val threadsNumber: Int = 1, + private val maxTurns: Int = 1000 ) { - val maxSimulations = threadsNumber * simulationsPerThread + private val maxSimulations = threadsNumber * simulationsPerThread val civilizations = newGameInfo.civilizations.filter { it.civName != "Spectator" }.map { it.civName } private var startTime: Long = 0 private var endTime: Long = 0 var steps = ArrayList() var winRate = mutableMapOf() - var winRateByVictory = HashMap>() - var avgSpeed = 0f - var avgDuration: Duration = Duration.ZERO + private var winRateByVictory = HashMap>() + private var avgSpeed = 0f + private var avgDuration: Duration = Duration.ZERO private var totalTurns = 0 private var totalDuration: Duration = Duration.ZERO - var stepCounter: Int = 0 + private var stepCounter: Int = 0 init{ for (civ in civilizations) { this.winRate[civ] = MutableInt(0) - winRateByVictory[civ] = mutableMapOf() + winRateByVictory[civ] = mutableMapOf() for (victory in VictoryType.values()) winRateByVictory[civ]!![victory] = MutableInt(0) } @@ -48,7 +51,7 @@ class Simulation(val newGameInfo: GameInfo, gameInfo.simulateUntilWin = true gameInfo.nextTurn() - var step = SimulationStep(gameInfo) + val step = SimulationStep(gameInfo) if (step.victoryType != null) { step.winner = step.currentPlayer @@ -67,11 +70,13 @@ class Simulation(val newGameInfo: GameInfo, endTime = System.currentTimeMillis() } + @Suppress("UNUSED_PARAMETER") // used when activating debug output @Synchronized fun add(step: SimulationStep, threadId: Int = 1) { // println("Thread $threadId: End simulation ($stepCounter/$maxSimulations)") steps.add(step) } + @Suppress("UNUSED_PARAMETER") // used when activating debug output @Synchronized fun updateCounter(threadId: Int = 1) { stepCounter++ // println("Thread $threadId: Start simulation ($stepCounter/$maxSimulations)") @@ -100,10 +105,10 @@ class Simulation(val newGameInfo: GameInfo, winRateByVictory[it.winner!!]!![it.victoryType]!!.inc() } } - totalTurns = steps.sumBy { it.turns } - totalDuration = Duration.ofMillis(endTime - startTime) - avgSpeed = totalTurns.toFloat() / totalDuration.seconds - avgDuration = totalDuration.dividedBy(steps.size.toLong()) + totalTurns = steps.sumOf { it.turns } + totalDuration = Duration.milliseconds(endTime - startTime) + avgSpeed = totalTurns.toFloat() / totalDuration.inWholeSeconds + avgDuration = totalDuration / steps.size } override fun toString(): String { @@ -119,8 +124,8 @@ class Simulation(val newGameInfo: GameInfo, outString += "\n" } outString += "\nAverage speed: %.1f turns/s \n".format(avgSpeed) - outString += "Average game duration: " + formatDuration(avgDuration) + "\n" - outString += "Total time: " + formatDuration(totalDuration) + "\n" + outString += "Average game duration: $avgDuration\n" + outString += "Total time: $totalDuration\n" return outString } diff --git a/core/src/com/unciv/models/simulation/Utils.kt b/core/src/com/unciv/models/simulation/Utils.kt index 82f7174323..f0009de378 100644 --- a/core/src/com/unciv/models/simulation/Utils.kt +++ b/core/src/com/unciv/models/simulation/Utils.kt @@ -1,7 +1,5 @@ package com.unciv.models.simulation -import java.time.Duration - class MutableInt(var value: Int = 0) { fun inc() { ++value } fun get(): Int { return value } @@ -11,20 +9,3 @@ class MutableInt(var value: Int = 0) { return value.toString() } } - -fun formatDuration(d: Duration): String { - var newDuration = d - val days = newDuration.toDays() - newDuration = newDuration.minusDays(days) - val hours = newDuration.toHours() - newDuration = newDuration.minusHours(hours) - val minutes = newDuration.toMinutes() - newDuration = newDuration.minusMinutes(minutes) - val seconds = newDuration.seconds - newDuration = newDuration.minusSeconds(seconds) - val millis = newDuration.toMillis() - return (if (days == 0L) "" else "$days"+"d ") + - (if (hours == 0L) "" else "$hours"+"h ") + - (if (minutes == 0L) "" else "$minutes"+"m ") + - (if (seconds == 0L) "$millis"+"ms" else "$seconds"+"."+"$millis".take(2)+"s") -} \ No newline at end of file diff --git a/core/src/com/unciv/models/translations/TranslationFileWriter.kt b/core/src/com/unciv/models/translations/TranslationFileWriter.kt index 5e2bc8806c..fc077f3e14 100644 --- a/core/src/com/unciv/models/translations/TranslationFileWriter.kt +++ b/core/src/com/unciv/models/translations/TranslationFileWriter.kt @@ -176,7 +176,7 @@ object TranslationFileWriter { // used for unit test only fun getGeneratedStringsSize(): Int { - return generateStringsFromJSONs(Gdx.files.local("jsons/Civ V - Vanilla")).values.sumBy { // exclude empty lines + return generateStringsFromJSONs(Gdx.files.local("jsons/Civ V - Vanilla")).values.sumOf { // exclude empty lines it.count { line: String -> !line.startsWith(specialNewLineCode) } } } diff --git a/core/src/com/unciv/ui/utils/Fonts.kt b/core/src/com/unciv/ui/utils/Fonts.kt index f340bfe47a..4ec6e9800e 100644 --- a/core/src/com/unciv/ui/utils/Fonts.kt +++ b/core/src/com/unciv/ui/utils/Fonts.kt @@ -20,7 +20,9 @@ interface NativeFontImplementation { } // This class is loosely based on libgdx's FreeTypeBitmapFontData -class NativeBitmapFontData(val fontImplementation: NativeFontImplementation) : BitmapFontData(), Disposable { +class NativeBitmapFontData( + private val fontImplementation: NativeFontImplementation +) : BitmapFontData(), Disposable { val regions: Array @@ -59,7 +61,7 @@ class NativeBitmapFontData(val fontImplementation: NativeFontImplementation) : B val charPixmap = getPixmapFromChar(ch) glyph = Glyph() - glyph.id = ch.toInt() + glyph.id = ch.code glyph.width = charPixmap.width glyph.height = charPixmap.height glyph.xadvance = glyph.width @@ -75,7 +77,7 @@ class NativeBitmapFontData(val fontImplementation: NativeFontImplementation) : B packer.updateTextureRegions(regions, filter, filter, false) setGlyphRegion(glyph, regions.get(glyph.page)) - setGlyph(ch.toInt(), glyph) + setGlyph(ch.code, glyph) dirty = true } return glyph diff --git a/core/src/com/unciv/ui/utils/KeyPressDispatcher.kt b/core/src/com/unciv/ui/utils/KeyPressDispatcher.kt index 2334a2032a..fab3b1ae08 100644 --- a/core/src/com/unciv/ui/utils/KeyPressDispatcher.kt +++ b/core/src/com/unciv/ui/utils/KeyPressDispatcher.kt @@ -32,8 +32,6 @@ data class KeyCharAndCode(val char: Char, val code: Int) { /** express keys that only have a keyCode like F1 */ constructor(code: Int): this(Char.MIN_VALUE, code) - // From Kotlin 1.5? on the Ctrl- line will need Char(char.code+64) - // see https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/char-int-conversions.md override fun toString(): String { // debug helper, but also used for tooltips fun fixedKeysToString(code: Int) = when (code) { @@ -44,7 +42,7 @@ data class KeyCharAndCode(val char: Char, val code: Int) { return when { char == Char.MIN_VALUE -> fixedKeysToString(code) this == ESC -> "ESC" - char < ' ' -> "Ctrl-" + (char.toInt()+64).toChar() + char < ' ' -> "Ctrl-" + Char(char.code+64) else -> "\"$char\"" } } @@ -66,14 +64,14 @@ data class KeyCharAndCode(val char: Char, val code: Int) { val UNKNOWN = KeyCharAndCode(Input.Keys.UNKNOWN) /** mini-factory for control codes - case insensitive */ - fun ctrl(letter: Char) = KeyCharAndCode((letter.toInt() and 31).toChar(), 0) + fun ctrl(letter: Char) = KeyCharAndCode(Char(letter.code and 31), 0) /** mini-factory for KeyCharAndCode values to be compared by character, not by code */ - fun ascii(char: Char) = KeyCharAndCode(char.toLowerCase(), 0) + fun ascii(char: Char) = KeyCharAndCode(char.lowercaseChar(), 0) /** factory maps a Char to a keyCode if possible, returns a Char-based instance otherwise */ fun mapChar(char: Char): KeyCharAndCode { - val code = Input.Keys.valueOf(char.toUpperCase().toString()) + val code = Input.Keys.valueOf(char.uppercaseChar().toString()) return if (code == -1) KeyCharAndCode(char,0) else KeyCharAndCode(Char.MIN_VALUE, code) } } diff --git a/core/src/com/unciv/ui/utils/UncivTooltip.kt b/core/src/com/unciv/ui/utils/UncivTooltip.kt index aedd2e5071..d154110f29 100644 --- a/core/src/com/unciv/ui/utils/UncivTooltip.kt +++ b/core/src/com/unciv/ui/utils/UncivTooltip.kt @@ -196,7 +196,7 @@ class UncivTooltip ( * @param always override requirement: presence of physical keyboard */ fun Group.addTooltip(char: Char, size: Float = 26f, always: Boolean = false) { - addTooltip((if (char in "Ii") 'i' else char.toUpperCase()).toString(), size, always) + addTooltip((if (char in "Ii") 'i' else char.uppercaseChar()).toString(), size, always) } /** diff --git a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt index 051e51829c..8b483763af 100644 --- a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt @@ -15,8 +15,10 @@ import com.unciv.models.ruleset.RulesetCache import com.unciv.models.simulation.Simulation import com.unciv.models.tilesets.TileSetCache import com.unciv.models.metadata.GameSetupInfo +import kotlin.time.ExperimentalTime internal object ConsoleLauncher { + @ExperimentalTime @JvmStatic fun main(arg: Array) {