Add and improve domain (WIP)
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user