From d146ae11f7f217eec18b34d10697a68d21efccb9 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Thu, 15 May 2025 17:39:24 +0200 Subject: [PATCH] Save each game for Debugging --- commonUI/build.gradle.kts | 2 +- .../kotlin/ch/dissem/yaep/ui/common/App.kt | 43 +++++++++++++++++-- domain/build.gradle.kts | 2 +- .../kotlin/ch/dissem/yaep/domain/Game.kt | 2 +- .../kotlin/ch/dissem/yaep/domain/clues.kt | 10 ++--- gradle/libs.versions.toml | 14 +++--- 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/commonUI/build.gradle.kts b/commonUI/build.gradle.kts index a6f7421..c676de0 100644 --- a/commonUI/build.gradle.kts +++ b/commonUI/build.gradle.kts @@ -31,7 +31,7 @@ kotlin { implementation(compose.components.uiToolingPreview) // implementation(libs.compose.ui.text.googlefonts) - implementation(libs.logging) + implementation(libs.bundles.logging) } } diff --git a/commonUI/src/commonMain/kotlin/ch/dissem/yaep/ui/common/App.kt b/commonUI/src/commonMain/kotlin/ch/dissem/yaep/ui/common/App.kt index 83033d9..d2358a7 100644 --- a/commonUI/src/commonMain/kotlin/ch/dissem/yaep/ui/common/App.kt +++ b/commonUI/src/commonMain/kotlin/ch/dissem/yaep/ui/common/App.kt @@ -40,10 +40,23 @@ import ch.dissem.yaep.domain.NeighbourClue import ch.dissem.yaep.domain.OrderClue import ch.dissem.yaep.domain.SameColumnClue import ch.dissem.yaep.domain.TripletClue +import io.github.oshai.kotlinlogging.KotlinLogging +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.painterResource import yaep.commonui.generated.resources.Res import yaep.commonui.generated.resources.neighbour import yaep.commonui.generated.resources.order +import kotlin.io.path.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.createFile +import kotlin.io.path.isDirectory +import kotlin.io.path.notExists +import kotlin.io.path.writeText +import kotlin.time.Clock +import kotlin.time.ExperimentalTime + +private val log = KotlinLogging.logger {} class DisplayClue(val clue: C) { var isActive: Boolean by mutableStateOf(true) @@ -59,13 +72,37 @@ class DisplayClue(val clue: C) { } @Composable -fun App(modifier: Modifier = Modifier, game: Game, onNewGame: () -> Unit, resetCluesBeacon: Any = Any()) { - val horizontalClues = remember(game, resetCluesBeacon) { game.horizontalClues.map { DisplayClue(it) } } - val verticalClues = remember(game, resetCluesBeacon) { game.verticalClues.map { DisplayClue(it) } } +@OptIn(ExperimentalTime::class) +fun App( + modifier: Modifier = Modifier, + game: Game, + onNewGame: () -> Unit, + resetCluesBeacon: Any = Any() +) { + val horizontalClues = + remember(game, resetCluesBeacon) { game.horizontalClues.map { DisplayClue(it) } } + val verticalClues = + remember(game, resetCluesBeacon) { game.verticalClues.map { DisplayClue(it) } } val timer = remember(game) { GameTimer() } val time by timer.elapsedTime.collectAsState("00:00") var isSolved by remember(game) { mutableStateOf(false) } LaunchedEffect(game) { + launch(Dispatchers.IO) { + val dirName = """${System.getProperty("user.home")}/.yaep""" + val dir = Path(dirName) + if (dir.notExists()) { + dir.createDirectories() + } else if (!dir.isDirectory()) { + log.error { "Yaep data directory already exists and is not a directory: $dir" } + log.debug { "Game: $game" } + } else { + val fileName = "$dirName/${Clock.System.now()}.yaep" + Path(fileName) + .createFile() + .writeText(game.toString()) + log.info { "Saved game to $fileName" } + } + } game.onStart { timer.start() } diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 01b63c9..ef4bf13 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -21,7 +21,7 @@ kotlin { sourceSets { commonMain { dependencies { - implementation(libs.logging) + implementation(libs.bundles.logging) } } diff --git a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/Game.kt b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/Game.kt index a7f4047..6806496 100644 --- a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/Game.kt +++ b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/Game.kt @@ -66,7 +66,7 @@ class Game( companion object { fun parse(description: String): Game { - val optionsRegex = Regex("[A-Z]+(_[A-Z]+)*") + val optionsRegex = Regex("[A-Z]+(?:_[A-Z]+)*") val options = optionsRegex.findAll(description) .map { it.value } .distinct() diff --git a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt index 571dab9..c732318 100644 --- a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt +++ b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt @@ -92,7 +92,7 @@ class NeighbourClue, B : ItemClass>(val a: Item, val b: I line: String, mapper: (ItemClass<*>) -> Item ): Clue? { - val regex = Regex("^(\\* )?(?[A-Z_]+) is next to (?[A-Z_]+)$") + val regex = Regex("^(?:\\* )?(?[A-Z_]+) is next to (?[A-Z_]+)$") val matchResult = regex.matchEntire(line) ?: return null val a = ItemClass.parse(matchResult.groups["a"]!!.value) @@ -154,7 +154,7 @@ class OrderClue, R : ItemClass>(val left: Item, val right line: String, mapper: (ItemClass<*>) -> Item ): Clue? { - val regex = Regex("^(\\* )?(?[A-Z_]+) is left of (?[A-Z_]+)$") + val regex = Regex("^(?:\\* )?(?[A-Z_]+) is left of (?[A-Z_]+)$") val matchResult = regex.matchEntire(line) ?: return null val left = ItemClass.parse(matchResult.groups["left"]!!.value) @@ -299,7 +299,7 @@ class TripletClue, B : ItemClass, C : ItemClass>( mapper: (ItemClass<*>) -> Item ): Clue? { val regex = - Regex("^(\\* )?(?[A-Z_]+) is between the neighbours (?[A-Z_]+) and (?[A-Z_]+) to both sides$") + Regex("^(?:\\* )?(?[A-Z_]+) is between the neighbours (?[A-Z_]+) and (?[A-Z_]+) to both sides$") val matchResult = regex.matchEntire(line) ?: return null val a = ItemClass.parse(matchResult.groups["a"]!!.value) @@ -364,7 +364,7 @@ class SameColumnClue, B : ItemClass>(val a: Item, val b: line: String, mapper: (ItemClass<*>) -> Item ): Clue? { - val regex = Regex("^(\\* )?(?[A-Z_]+) and (?[A-Z_]+) are in the same column$") + val regex = Regex("^(?:\\* )?(?[A-Z_]+) and (?[A-Z_]+) are in the same column$") val matchResult = regex.matchEntire(line) ?: return null val a = ItemClass.parse(matchResult.groups["a"]!!.value) @@ -408,7 +408,7 @@ class PositionClue>(val item: Item, val index: Int) : Clue() line: String, mapper: (ItemClass<*>) -> Item ): Clue? { - val regex = Regex("^(\\* )?(?[A-Z_]+) is at position (?\\d)$") + val regex = Regex("^(?:\\* )?(?[A-Z_]+) is at position (?\\d)$") val matchResult = regex.matchEntire(line) ?: return null val type = ItemClass.parse(matchResult.groups["type"]!!.value) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0b60412..8c6f7c6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,14 @@ [versions] -agp = "8.9.2" +agp = "8.10.0" jdk = "21" android-compileSdk = "35" android-minSdk = "24" android-targetSdk = "35" androidx-activityCompose = "1.10.1" -androidx-compose = "1.7.8" +androidx-compose = "1.8.1" compose-plugin = "1.7.0" -kotlin = "2.1.0" -coreKtx = "1.15.0" +kotlin = "2.1.21" +coreKtx = "1.16.0" atrium = "1.2.0" [libraries] @@ -19,7 +19,11 @@ kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotl atrium = { module = "ch.tutteli.atrium:atrium-fluent", version.ref = "atrium" } androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.10.1" } -logging = { module = "io.github.oshai:kotlin-logging", version = "7.0.0" } +logging-jvm = { module = "io.github.oshai:kotlin-logging-jvm", version = "7.0.7" } +logging-slf4j = { module = "org.slf4j:slf4j-simple", version = "2.0.13" } + +[bundles] +logging = [ "logging-jvm", "logging-slf4j" ] [plugins] versions = { id = "com.github.ben-manes.versions", version = "0.51.0" }