Add and improve domain (WIP)
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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]
|
[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" }
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
rootProject.name = "YAEP"
|
rootProject.name = "YAEP"
|
||||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user