Add and improve domain (WIP)

This commit is contained in:
2024-06-11 11:04:02 +02:00
parent 1b9c8633c9
commit f891dea885
11 changed files with 232 additions and 29 deletions

View File

@@ -5,4 +5,5 @@ plugins {
alias(libs.plugins.androidLibrary) apply false alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.jetbrainsCompose) apply false alias(libs.plugins.jetbrainsCompose) apply false
alias(libs.plugins.kotlinMultiplatform) apply false alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.jetbrainsKotlinJvm) apply false
} }

View File

@@ -19,6 +19,7 @@ kotlin {
sourceSets { sourceSets {
val desktopMain by getting val desktopMain by getting
val desktopTest by getting
androidMain.dependencies { androidMain.dependencies {
implementation(libs.compose.ui.tooling.preview) implementation(libs.compose.ui.tooling.preview)
@@ -27,7 +28,7 @@ kotlin {
commonMain.dependencies { commonMain.dependencies {
implementation(compose.runtime) implementation(compose.runtime)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material) implementation(compose.material3)
implementation(compose.ui) implementation(compose.ui)
implementation(compose.components.resources) implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview) implementation(compose.components.uiToolingPreview)
@@ -35,7 +36,19 @@ kotlin {
desktopMain.dependencies { desktopMain.dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
} }
commonTest.dependencies {
// implementation(libs.junit)
implementation(kotlin("test"))
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
implementation(compose.uiTest)
} }
desktopTest.dependencies {
implementation(compose.desktop.uiTestJUnit4)
implementation(compose.desktop.currentOs)
}
}
} }
android { android {

View File

@@ -2,9 +2,9 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Button import androidx.compose.material3.Button
import androidx.compose.material.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier

View File

@@ -0,0 +1,21 @@
package domain
class Game(
val categories: List<ItemCategory>,
val grid: Grid,
val horizontalRules: List<HorizontalRule>,
val verticalRules: List<VerticalRule>
) {
fun areCategoriesValid(): Boolean = categories.mapIndexed { index, category ->
category.any { item ->
categories.filterIndexed { i, _ -> i > index }.any { it.contains(item) }
}
}.none { it }
fun areRulesViolated(): Boolean = horizontalRules
.map { it.isRuleViolated(grid) }
.reduce { a, b -> a || b }
|| verticalRules
.map { it.isRuleViolated(grid) }
.reduce { a, b -> a || b }
}

View File

@@ -0,0 +1,21 @@
package domain
class GameRow(
val category: ItemCategory,
val cells: List<GameCell>
) : List<GameCell> by cells
class Grid(
val rows: List<GameRow>
) : List<GameRow> by rows {
fun indexOf(element: Item): Int {
val row = rows.first { it.category == element.category }
return row.indexOfFirst { it.selection == element }
}
}
class GameCell(
var selection: Item?,
val solution: Item,
val options: List<Item>
)

View File

@@ -0,0 +1,44 @@
@file:OptIn(ExperimentalResourceApi::class)
package domain
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.ExperimentalResourceApi
fun category(block: CategoryContext.() -> Unit): ItemCategory {
class CategoryImpl(val items: MutableList<ItemImpl>) :
ItemCategory, List<Item> by items {
inner class ItemImpl(
override val image: DrawableResource
) : Item {
override val category: CategoryImpl = this@CategoryImpl
init {
items.add(this)
}
}
}
val ctx = object : CategoryContext {
val category = CategoryImpl(mutableListOf())
override fun item(image: DrawableResource) {
category.ItemImpl(image)
}
}
ctx.block()
return ctx.category
}
interface CategoryContext {
fun item(image: DrawableResource)
}
interface Item {
val category: ItemCategory
@OptIn(ExperimentalResourceApi::class)
val image: DrawableResource
}
interface ItemCategory : List<Item>

View File

@@ -0,0 +1,69 @@
package domain
import kotlin.math.abs
sealed class GameRule {
abstract fun isRuleViolated(grid: Grid): Boolean
}
sealed class HorizontalRule : GameRule()
class NeighbourRule(val a: Item, val b: Item) : HorizontalRule() {
override fun isRuleViolated(grid: Grid): Boolean {
val ia = grid.indexOf(a)
val ib = grid.indexOf(b)
if (ia == -1 || ib == -1) return false
return abs(ia - ib) != 1
}
}
class OrderRule(val left: Item, val right: Item) : HorizontalRule() {
override fun isRuleViolated(grid: Grid): Boolean {
val il = grid.indexOf(left)
val ir = grid.indexOf(right)
if (il == -1 || ir == -1) return false
return ir <= il
}
}
class TripletRule(val a: Item, val b: Item, val c: Item) : HorizontalRule() {
private fun isNeighbourRuleViolated(ix: Int, iy: Int): Boolean {
if (ix == -1 || iy == -1) return false
return abs(ix - iy) != 1
}
override fun isRuleViolated(grid: Grid): Boolean {
val ia = grid.indexOf(a)
val ib = grid.indexOf(b)
val ic = grid.indexOf(c)
if (ia == -1 && ic == -1) {
return false
}
if (ia == ib) {
return true
}
if (isNeighbourRuleViolated(ia, ib) || isNeighbourRuleViolated(ib, ic)) {
return true
}
return false
}
}
class VerticalRule(val a: Item, val b: Item) : GameRule() {
override fun isRuleViolated(grid: Grid): Boolean {
val ia = grid.indexOf(a)
val ib = grid.indexOf(b)
if (ia == -1 || ib == -1) return false
return ia != ib
}
}

View File

@@ -0,0 +1,14 @@
package ui
import androidx.compose.material3.OutlinedCard
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import domain.Item
import domain.ItemCategory
@Composable
fun Selector(modifier: Modifier = Modifier, category: ItemCategory, selectedItem: Item, onSelectItem: (Item) -> Unit) {
OutlinedCard(modifier = modifier) {
}
}

View File

@@ -0,0 +1,31 @@
@file:OptIn(ExperimentalResourceApi::class)
package domain
import org.jetbrains.compose.resources.ExperimentalResourceApi
//import org.junit.Test
import yaep.composeapp.generated.resources.Res
import yaep.composeapp.generated.resources.compose_multiplatform
import kotlin.test.Test
import kotlin.test.fail
class GameTest {
@Test
fun areCategoriesValid() {
// Game(
// categories = listOf(
// category {
// item(Res.drawable.compose_multiplatform)
// }
// ),
// Grid(
//
// )
// )
}
@Test
fun areRulesViolated() {
TODO()
}
}

View File

@@ -1,30 +1,15 @@
[versions] [versions]
agp = "8.3.2" agp = "8.4.2"
android-compileSdk = "34" android-compileSdk = "34"
android-minSdk = "24" android-minSdk = "24"
android-targetSdk = "34" android-targetSdk = "34"
androidx-activityCompose = "1.9.0" androidx-activityCompose = "1.9.0"
androidx-appcompat = "1.6.1" compose = "1.6.7"
androidx-constraintlayout = "2.1.4" compose-plugin = "1.6.11"
androidx-core-ktx = "1.13.0" kotlin = "1.9.24"
androidx-espresso-core = "3.5.1"
androidx-material = "1.11.0"
androidx-test-junit = "1.1.5"
compose = "1.6.6"
compose-plugin = "1.6.2"
junit = "4.13.2"
kotlin = "1.9.23"
[libraries] [libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } #junit = { module = "junit:junit", version = "4.13.2"}
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core-ktx" }
androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-junit" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-espresso-core" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" }
androidx-material = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
@@ -34,3 +19,5 @@ androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" }
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
jetbrainsKotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

View File

@@ -1,3 +1,5 @@
@file:Suppress("UnstableApiUsage")
rootProject.name = "YAEP" rootProject.name = "YAEP"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")