diff --git a/src/main/kotlin/eventDemo/app/GameState.kt b/src/main/kotlin/eventDemo/app/GameState.kt index 82b71d9..414cb85 100644 --- a/src/main/kotlin/eventDemo/app/GameState.kt +++ b/src/main/kotlin/eventDemo/app/GameState.kt @@ -15,7 +15,7 @@ data class GameState( val lastColor: Card.Color? = null, val direction: Direction = Direction.CLOCKWISE, val readyPlayers: List = emptyList(), - val deck: Deck = Deck(players.toList()), + val deck: Deck = Deck(players), val isStarted: Boolean = false, ) { @Serializable diff --git a/src/main/kotlin/eventDemo/app/entity/Deck.kt b/src/main/kotlin/eventDemo/app/entity/Deck.kt index b3db169..c50fcda 100644 --- a/src/main/kotlin/eventDemo/app/entity/Deck.kt +++ b/src/main/kotlin/eventDemo/app/entity/Deck.kt @@ -6,9 +6,10 @@ import kotlinx.serialization.Serializable data class Deck( val stack: Stack = Stack(), val discard: Discard = Discard(), - val playersHands: PlayerHands = emptyMap(), + val playersHands: PlayersHands = PlayersHands(), ) { - constructor(players: List) : this(playersHands = players.associateWith { emptyList() }) + constructor(players: Set) : + this(playersHands = PlayersHands(players)) fun placeFirstCardOnDiscard(): Deck { val takenCard = stack.first() @@ -21,13 +22,14 @@ data class Deck( fun takeOneCardFromStackTo(player: Player): Deck = takeOne().let { (deck, newPlayerCard) -> val newHands = - deck.playersHands.mapValues { (p, cards) -> - if (p == player) { - cards + newPlayerCard - } else { - cards - } - } + deck.playersHands + .mapValues { (p, cards) -> + if (p == player) { + cards + newPlayerCard + } else { + cards + } + }.toPlayersHands() deck.copy(playersHands = newHands) } @@ -79,7 +81,7 @@ fun Deck.initHands( handSize: Int = 7, ): Deck { // Copy cards from stack to the player hands - val deckWithEmptyHands = copy(playersHands = players.associateWith { listOf() }) + val deckWithEmptyHands = copy(playersHands = PlayersHands(players)) return players.fold(deckWithEmptyHands) { acc: Deck, player: Player -> val hand = acc.stack.take(handSize) val newStack = acc.stack.filterNot { card: Card -> hand.contains(card) }.toStack() @@ -93,11 +95,11 @@ fun Deck.initHands( @JvmInline @Serializable value class Stack( - val elems: Set = emptySet(), -) : Set by elems { - operator fun plus(card: Card): Stack = elems.plus(card).toStack() + private val cards: Set = emptySet(), +) : Set by cards { + operator fun plus(card: Card): Stack = cards.plus(card).toStack() - operator fun minus(card: Card): Stack = elems.minus(card).toStack() + operator fun minus(card: Card): Stack = cards.minus(card).toStack() } fun List.toStack(): Stack = Stack(this.toSet()) @@ -107,11 +109,11 @@ fun Set.toStack(): Stack = Stack(this) @JvmInline @Serializable value class Discard( - val elems: Set = emptySet(), -) : Set by elems { - operator fun plus(card: Card): Discard = elems.plus(card).toDiscard() + private val cards: Set = emptySet(), +) : Set by cards { + operator fun plus(card: Card): Discard = cards.plus(card).toDiscard() - operator fun minus(card: Card): Discard = elems.minus(card).toDiscard() + operator fun minus(card: Card): Discard = cards.minus(card).toDiscard() } fun List.toDiscard(): Discard = Discard(this.toSet()) diff --git a/src/main/kotlin/eventDemo/app/entity/PlayerHand.kt b/src/main/kotlin/eventDemo/app/entity/PlayerHand.kt deleted file mode 100644 index 74b1b10..0000000 --- a/src/main/kotlin/eventDemo/app/entity/PlayerHand.kt +++ /dev/null @@ -1,27 +0,0 @@ -package eventDemo.app.entity - -typealias PlayerHands = Map> - -fun PlayerHands.removeCard( - player: Player, - card: Card, -): PlayerHands = - mapValues { (p, cards) -> - if (p == player) { - cards - card - } else { - cards - } - } - -fun PlayerHands.addCards( - player: Player, - newCards: List, -): PlayerHands = - mapValues { (p, cards) -> - if (p == player) { - cards + newCards - } else { - cards - } - } diff --git a/src/main/kotlin/eventDemo/app/entity/PlayersHands.kt b/src/main/kotlin/eventDemo/app/entity/PlayersHands.kt new file mode 100644 index 0000000..e3a6f73 --- /dev/null +++ b/src/main/kotlin/eventDemo/app/entity/PlayersHands.kt @@ -0,0 +1,37 @@ +package eventDemo.app.entity + +import kotlinx.serialization.Serializable + +@Serializable +@JvmInline +value class PlayersHands( + private val map: Map> = emptyMap(), +) : Map> by map { + constructor(players: Set) : this(players.associateWith { emptyList() }.toPlayersHands()) + + fun removeCard( + player: Player, + card: Card, + ): PlayersHands = + mapValues { (p, cards) -> + if (p == player) { + cards - card + } else { + cards + } + }.toPlayersHands() + + fun addCards( + player: Player, + newCards: List, + ): PlayersHands = + mapValues { (p, cards) -> + if (p == player) { + cards + newCards + } else { + cards + } + }.toPlayersHands() +} + +fun Map>.toPlayersHands(): PlayersHands = PlayersHands(this) diff --git a/src/test/kotlin/eventDemo/app/entity/PlayerHandKtTest.kt b/src/test/kotlin/eventDemo/app/entity/PlayerHandKtTest.kt index 9dbca47..199cf75 100644 --- a/src/test/kotlin/eventDemo/app/entity/PlayerHandKtTest.kt +++ b/src/test/kotlin/eventDemo/app/entity/PlayerHandKtTest.kt @@ -11,11 +11,11 @@ class PlayerHandKtTest : val playerNumbers = 4 val players = (1..playerNumbers).map { Player(name = "name $it") }.toSet() val firstPlayer = players.first() - val playersHands: PlayerHands = players.associateWith { emptyList() } + val playersHands = PlayersHands(players) val card = Card.NumericCard(0, Card.Color.Red) // When - val newHands: PlayerHands = playersHands.addCards(firstPlayer, listOf(card)) + val newHands: PlayersHands = playersHands.addCards(firstPlayer, listOf(card)) assertNotNull(newHands[firstPlayer]).size shouldBeExactly 1 assertNotNull(newHands[players.last()]).size shouldBeExactly 0 @@ -28,13 +28,12 @@ class PlayerHandKtTest : val firstPlayer = players.first() val card1 = Card.NumericCard(1, Card.Color.Red) val card2 = Card.NumericCard(2, Card.Color.Red) - val playersHands: PlayerHands = - players - .associateWith> { emptyList() } + val playersHands: PlayersHands = + PlayersHands(players) .addCards(firstPlayer, listOf(card1, card2)) // When - val newHands: PlayerHands = playersHands.removeCard(firstPlayer, card1) + val newHands: PlayersHands = playersHands.removeCard(firstPlayer, card1) assertNotNull(newHands[firstPlayer]).size shouldBeExactly 1 assertNotNull(newHands[players.last()]).size shouldBeExactly 0