Add and improve domain (WIP)
This commit is contained in:
@@ -5,4 +5,5 @@ plugins {
|
||||
alias(libs.plugins.androidLibrary) apply false
|
||||
alias(libs.plugins.jetbrainsCompose) apply false
|
||||
alias(libs.plugins.kotlinMultiplatform) apply false
|
||||
alias(libs.plugins.jetbrainsKotlinJvm) apply false
|
||||
}
|
||||
@@ -19,6 +19,7 @@ kotlin {
|
||||
|
||||
sourceSets {
|
||||
val desktopMain by getting
|
||||
val desktopTest by getting
|
||||
|
||||
androidMain.dependencies {
|
||||
implementation(libs.compose.ui.tooling.preview)
|
||||
@@ -27,7 +28,7 @@ kotlin {
|
||||
commonMain.dependencies {
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
@@ -35,7 +36,19 @@ kotlin {
|
||||
desktopMain.dependencies {
|
||||
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 {
|
||||
|
||||
@@ -2,9 +2,9 @@ import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
21
composeApp/src/commonMain/kotlin/domain/Game.kt
Normal file
21
composeApp/src/commonMain/kotlin/domain/Game.kt
Normal 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 }
|
||||
}
|
||||
21
composeApp/src/commonMain/kotlin/domain/grid.kt
Normal file
21
composeApp/src/commonMain/kotlin/domain/grid.kt
Normal 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>
|
||||
)
|
||||
44
composeApp/src/commonMain/kotlin/domain/items.kt
Normal file
44
composeApp/src/commonMain/kotlin/domain/items.kt
Normal 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>
|
||||
69
composeApp/src/commonMain/kotlin/domain/rules.kt
Normal file
69
composeApp/src/commonMain/kotlin/domain/rules.kt
Normal 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
|
||||
}
|
||||
}
|
||||
14
composeApp/src/commonMain/kotlin/ui/selector.kt
Normal file
14
composeApp/src/commonMain/kotlin/ui/selector.kt
Normal 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) {
|
||||
|
||||
}
|
||||
}
|
||||
31
composeApp/src/commonTest/kotlin/domain/GameTest.kt
Normal file
31
composeApp/src/commonTest/kotlin/domain/GameTest.kt
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,15 @@
|
||||
[versions]
|
||||
agp = "8.3.2"
|
||||
agp = "8.4.2"
|
||||
android-compileSdk = "34"
|
||||
android-minSdk = "24"
|
||||
android-targetSdk = "34"
|
||||
androidx-activityCompose = "1.9.0"
|
||||
androidx-appcompat = "1.6.1"
|
||||
androidx-constraintlayout = "2.1.4"
|
||||
androidx-core-ktx = "1.13.0"
|
||||
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"
|
||||
compose = "1.6.7"
|
||||
compose-plugin = "1.6.11"
|
||||
kotlin = "1.9.24"
|
||||
|
||||
[libraries]
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
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" }
|
||||
#junit = { module = "junit:junit", version = "4.13.2"}
|
||||
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-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" }
|
||||
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
|
||||
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" }
|
||||
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
rootProject.name = "YAEP"
|
||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user