refactoring

This commit is contained in:
2025-03-04 23:21:06 +01:00
parent f3ca94c97e
commit 06443d7efa
31 changed files with 140 additions and 185 deletions

View File

@@ -0,0 +1,109 @@
package eventDemo.app.entity
import eventDemo.configuration.UUIDSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.UUID
/**
* A Play card
*/
@Serializable
sealed interface Card {
val id: UUID
/**
* The color of a card
*/
@Serializable
enum class Color {
Blue,
Red,
Yellow,
Green,
}
sealed interface ColorCard : Card {
val color: Color
}
/**
* A play card with color and number
*/
@Serializable
@SerialName("Simple")
data class NumericCard(
val number: Int,
override val color: Color,
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Card,
ColorCard
sealed interface Special : Card
/**
* A revert card to revert the order of the turn.
*/
@Serializable
@SerialName("Reverse")
data class ReverseCard(
override val color: Color,
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Special,
ColorCard
sealed interface PassTurnCard : Card
/**
* A pass card to pass the turn of the next player.
*/
@Serializable
@SerialName("Pass")
data class PassCard(
override val color: Color,
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Special,
ColorCard,
PassTurnCard
/**
* A play card to force the next player to take 2 card and pass the turn.
*/
@Serializable
@SerialName("Plus2")
data class Plus2Card(
override val color: Color,
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Special,
ColorCard,
PassTurnCard
sealed interface AllColorCard : Card
/**
* A play card to force the next player to take 4 card and pass the turn.
*/
@Serializable
@SerialName("Plus4")
class Plus4Card(
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Special,
AllColorCard,
PassTurnCard
/**
* A play card to change the color.
*/
@Serializable
@SerialName("ChangeColor")
class ChangeColorCard(
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : Special,
AllColorCard
}

View File

@@ -0,0 +1,53 @@
package eventDemo.app.entity
import kotlinx.serialization.Serializable
@Serializable
data class Deck(
val stack: Set<Card> = emptySet(),
val discard: Set<Card> = emptySet(),
val playersHands: List<PlayerHand> = emptyList(),
) {
constructor(players: List<Player>) : this(playersHands = players.map { PlayerHand(it) })
fun putOneCardOnDiscard(): Deck {
val takenCard = stack.first()
val newStack = stack.filterNot { it != takenCard }.toSet()
return copy(stack = newStack)
}
fun take(n: Int): Pair<Deck, List<Card>> {
val takenCards = stack.take(n)
val newStack = stack.filterNot { takenCards.contains(it) }.toSet()
return Pair(copy(stack = newStack), takenCards)
}
companion object {
fun initHands(
players: Set<Player>,
handSize: Int = 7,
): Deck {
val deck = new()
val playersHands = players.map { PlayerHand(it, deck.stack.take(handSize)) }
val allTakenCards = playersHands.flatMap { it.cards }
val newStack = deck.stack.filterNot { allTakenCards.contains(it) }.toSet()
return deck.copy(
stack = newStack,
playersHands = playersHands,
)
}
private fun new(): Deck =
listOf(Card.Color.Red, Card.Color.Blue, Card.Color.Yellow, Card.Color.Green)
.flatMap { color ->
((0..9) + (1..9)).map { Card.NumericCard(it, color) } +
(1..2).map { Card.Plus2Card(color) } +
(1..2).map { Card.ReverseCard(color) } +
(1..2).map { Card.PassCard(color) }
}.let {
(1..4).map { Card.Plus4Card() }
}.shuffled()
.toSet()
.let { Deck(it) }
}
}

View File

@@ -0,0 +1,36 @@
package eventDemo.app.entity
import eventDemo.configuration.PlayerIdSerializer
import eventDemo.configuration.UUIDSerializer
import eventDemo.libs.event.AggregateId
import io.ktor.server.auth.Principal
import kotlinx.serialization.Serializable
import java.util.UUID
@Serializable
data class Player(
val name: String,
@Serializable(with = PlayerIdSerializer::class)
val id: PlayerId = PlayerId(UUID.randomUUID()),
) : Principal {
constructor(id: String, name: String) : this(
name,
PlayerId(UUID.fromString(id)),
)
@JvmInline
value class PlayerId(
@Serializable(with = UUIDSerializer::class)
override val id: UUID = UUID.randomUUID(),
) : AggregateId {
override fun toString(): String = id.toString()
}
}
@Serializable
data class PlayerHand(
val player: Player,
val cards: List<Card> = emptyList(),
) {
val count = lazy { cards.count() }
}