Save each game for Debugging
This commit is contained in:
@@ -31,7 +31,7 @@ kotlin {
|
|||||||
implementation(compose.components.uiToolingPreview)
|
implementation(compose.components.uiToolingPreview)
|
||||||
// implementation(libs.compose.ui.text.googlefonts)
|
// implementation(libs.compose.ui.text.googlefonts)
|
||||||
|
|
||||||
implementation(libs.logging)
|
implementation(libs.bundles.logging)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,23 @@ import ch.dissem.yaep.domain.NeighbourClue
|
|||||||
import ch.dissem.yaep.domain.OrderClue
|
import ch.dissem.yaep.domain.OrderClue
|
||||||
import ch.dissem.yaep.domain.SameColumnClue
|
import ch.dissem.yaep.domain.SameColumnClue
|
||||||
import ch.dissem.yaep.domain.TripletClue
|
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 org.jetbrains.compose.resources.painterResource
|
||||||
import yaep.commonui.generated.resources.Res
|
import yaep.commonui.generated.resources.Res
|
||||||
import yaep.commonui.generated.resources.neighbour
|
import yaep.commonui.generated.resources.neighbour
|
||||||
import yaep.commonui.generated.resources.order
|
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) {
|
class DisplayClue<C : Clue>(val clue: C) {
|
||||||
var isActive: Boolean by mutableStateOf(true)
|
var isActive: Boolean by mutableStateOf(true)
|
||||||
@@ -59,13 +72,37 @@ class DisplayClue<C : Clue>(val clue: C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun App(modifier: Modifier = Modifier, game: Game, onNewGame: () -> Unit, resetCluesBeacon: Any = Any()) {
|
@OptIn(ExperimentalTime::class)
|
||||||
val horizontalClues = remember(game, resetCluesBeacon) { game.horizontalClues.map { DisplayClue(it) } }
|
fun App(
|
||||||
val verticalClues = remember(game, resetCluesBeacon) { game.verticalClues.map { DisplayClue(it) } }
|
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 timer = remember(game) { GameTimer() }
|
||||||
val time by timer.elapsedTime.collectAsState("00:00")
|
val time by timer.elapsedTime.collectAsState("00:00")
|
||||||
var isSolved by remember(game) { mutableStateOf(false) }
|
var isSolved by remember(game) { mutableStateOf(false) }
|
||||||
LaunchedEffect(game) {
|
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 {
|
game.onStart {
|
||||||
timer.start()
|
timer.start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.logging)
|
implementation(libs.bundles.logging)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class Game(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun parse(description: String): Game {
|
fun parse(description: String): Game {
|
||||||
val optionsRegex = Regex("[A-Z]+(_[A-Z]+)*")
|
val optionsRegex = Regex("[A-Z]+(?:_[A-Z]+)*")
|
||||||
val options = optionsRegex.findAll(description)
|
val options = optionsRegex.findAll(description)
|
||||||
.map { it.value }
|
.map { it.value }
|
||||||
.distinct()
|
.distinct()
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class NeighbourClue<A : ItemClass<A>, B : ItemClass<B>>(val a: Item<A>, val b: I
|
|||||||
line: String,
|
line: String,
|
||||||
mapper: (ItemClass<*>) -> Item<T>
|
mapper: (ItemClass<*>) -> Item<T>
|
||||||
): Clue? {
|
): 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 matchResult = regex.matchEntire(line) ?: return null
|
||||||
|
|
||||||
val a = ItemClass.parse(matchResult.groups["a"]!!.value)
|
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,
|
line: String,
|
||||||
mapper: (ItemClass<*>) -> Item<T>
|
mapper: (ItemClass<*>) -> Item<T>
|
||||||
): Clue? {
|
): 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 matchResult = regex.matchEntire(line) ?: return null
|
||||||
|
|
||||||
val left = ItemClass.parse(matchResult.groups["left"]!!.value)
|
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>
|
mapper: (ItemClass<*>) -> Item<T>
|
||||||
): Clue? {
|
): Clue? {
|
||||||
val regex =
|
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 matchResult = regex.matchEntire(line) ?: return null
|
||||||
|
|
||||||
val a = ItemClass.parse(matchResult.groups["a"]!!.value)
|
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,
|
line: String,
|
||||||
mapper: (ItemClass<*>) -> Item<T>
|
mapper: (ItemClass<*>) -> Item<T>
|
||||||
): Clue? {
|
): 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 matchResult = regex.matchEntire(line) ?: return null
|
||||||
|
|
||||||
val a = ItemClass.parse(matchResult.groups["a"]!!.value)
|
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,
|
line: String,
|
||||||
mapper: (ItemClass<*>) -> Item<T>
|
mapper: (ItemClass<*>) -> Item<T>
|
||||||
): Clue? {
|
): 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 matchResult = regex.matchEntire(line) ?: return null
|
||||||
|
|
||||||
val type = ItemClass.parse(matchResult.groups["type"]!!.value)
|
val type = ItemClass.parse(matchResult.groups["type"]!!.value)
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.9.2"
|
agp = "8.10.0"
|
||||||
jdk = "21"
|
jdk = "21"
|
||||||
android-compileSdk = "35"
|
android-compileSdk = "35"
|
||||||
android-minSdk = "24"
|
android-minSdk = "24"
|
||||||
android-targetSdk = "35"
|
android-targetSdk = "35"
|
||||||
androidx-activityCompose = "1.10.1"
|
androidx-activityCompose = "1.10.1"
|
||||||
androidx-compose = "1.7.8"
|
androidx-compose = "1.8.1"
|
||||||
compose-plugin = "1.7.0"
|
compose-plugin = "1.7.0"
|
||||||
kotlin = "2.1.0"
|
kotlin = "2.1.21"
|
||||||
coreKtx = "1.15.0"
|
coreKtx = "1.16.0"
|
||||||
atrium = "1.2.0"
|
atrium = "1.2.0"
|
||||||
|
|
||||||
[libraries]
|
[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" }
|
atrium = { module = "ch.tutteli.atrium:atrium-fluent", version.ref = "atrium" }
|
||||||
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
|
||||||
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.10.1" }
|
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]
|
[plugins]
|
||||||
versions = { id = "com.github.ben-manes.versions", version = "0.51.0" }
|
versions = { id = "com.github.ben-manes.versions", version = "0.51.0" }
|
||||||
|
|||||||
Reference in New Issue
Block a user