Save each game for Debugging

This commit is contained in:
Christian Basler
2025-05-15 17:39:24 +02:00
parent b05f971ec1
commit d146ae11f7
6 changed files with 57 additions and 16 deletions

View File

@@ -31,7 +31,7 @@ kotlin {
implementation(compose.components.uiToolingPreview)
// implementation(libs.compose.ui.text.googlefonts)
implementation(libs.logging)
implementation(libs.bundles.logging)
}
}

View File

@@ -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<C : Clue>(val clue: C) {
var isActive: Boolean by mutableStateOf(true)
@@ -59,13 +72,37 @@ class DisplayClue<C : Clue>(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()
}

View File

@@ -21,7 +21,7 @@ kotlin {
sourceSets {
commonMain {
dependencies {
implementation(libs.logging)
implementation(libs.bundles.logging)
}
}

View File

@@ -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()

View File

@@ -92,7 +92,7 @@ class NeighbourClue<A : ItemClass<A>, B : ItemClass<B>>(val a: Item<A>, val b: I
line: String,
mapper: (ItemClass<*>) -> Item<T>
): Clue? {
val regex = Regex("^(\\* )?(?<a>[A-Z_]+) is next to (?<b>[A-Z_]+)$")
val regex = Regex("^(?:\\* )?(?<a>[A-Z_]+) is next to (?<b>[A-Z_]+)$")
val matchResult = regex.matchEntire(line) ?: return null
val a = ItemClass.parse(matchResult.groups["a"]!!.value)
@@ -154,7 +154,7 @@ class OrderClue<L : ItemClass<L>, R : ItemClass<R>>(val left: Item<L>, val right
line: String,
mapper: (ItemClass<*>) -> Item<T>
): Clue? {
val regex = Regex("^(\\* )?(?<left>[A-Z_]+) is left of (?<right>[A-Z_]+)$")
val regex = Regex("^(?:\\* )?(?<left>[A-Z_]+) is left of (?<right>[A-Z_]+)$")
val matchResult = regex.matchEntire(line) ?: return null
val left = ItemClass.parse(matchResult.groups["left"]!!.value)
@@ -299,7 +299,7 @@ class TripletClue<A : ItemClass<A>, B : ItemClass<B>, C : ItemClass<C>>(
mapper: (ItemClass<*>) -> Item<T>
): Clue? {
val regex =
Regex("^(\\* )?(?<b>[A-Z_]+) is between the neighbours (?<a>[A-Z_]+) and (?<c>[A-Z_]+) to both sides$")
Regex("^(?:\\* )?(?<b>[A-Z_]+) is between the neighbours (?<a>[A-Z_]+) and (?<c>[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<A : ItemClass<A>, B : ItemClass<B>>(val a: Item<A>, val b:
line: String,
mapper: (ItemClass<*>) -> Item<T>
): Clue? {
val regex = Regex("^(\\* )?(?<a>[A-Z_]+) and (?<b>[A-Z_]+) are in the same column$")
val regex = Regex("^(?:\\* )?(?<a>[A-Z_]+) and (?<b>[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<C : ItemClass<C>>(val item: Item<C>, val index: Int) : Clue()
line: String,
mapper: (ItemClass<*>) -> Item<T>
): Clue? {
val regex = Regex("^(\\* )?(?<type>[A-Z_]+) is at position (?<pos>\\d)$")
val regex = Regex("^(?:\\* )?(?<type>[A-Z_]+) is at position (?<pos>\\d)$")
val matchResult = regex.matchEntire(line) ?: return null
val type = ItemClass.parse(matchResult.groups["type"]!!.value)

View File

@@ -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" }