PlayersHands class

This commit is contained in:
2025-03-05 18:46:06 +01:00
parent fd78bfa4d0
commit c50127ba1b
5 changed files with 63 additions and 52 deletions

View File

@@ -15,7 +15,7 @@ data class GameState(
val lastColor: Card.Color? = null, val lastColor: Card.Color? = null,
val direction: Direction = Direction.CLOCKWISE, val direction: Direction = Direction.CLOCKWISE,
val readyPlayers: List<Player> = emptyList(), val readyPlayers: List<Player> = emptyList(),
val deck: Deck = Deck(players.toList()), val deck: Deck = Deck(players),
val isStarted: Boolean = false, val isStarted: Boolean = false,
) { ) {
@Serializable @Serializable

View File

@@ -6,9 +6,10 @@ import kotlinx.serialization.Serializable
data class Deck( data class Deck(
val stack: Stack = Stack(), val stack: Stack = Stack(),
val discard: Discard = Discard(), val discard: Discard = Discard(),
val playersHands: PlayerHands = emptyMap(), val playersHands: PlayersHands = PlayersHands(),
) { ) {
constructor(players: List<Player>) : this(playersHands = players.associateWith { emptyList<Card>() }) constructor(players: Set<Player>) :
this(playersHands = PlayersHands(players))
fun placeFirstCardOnDiscard(): Deck { fun placeFirstCardOnDiscard(): Deck {
val takenCard = stack.first() val takenCard = stack.first()
@@ -21,13 +22,14 @@ data class Deck(
fun takeOneCardFromStackTo(player: Player): Deck = fun takeOneCardFromStackTo(player: Player): Deck =
takeOne().let { (deck, newPlayerCard) -> takeOne().let { (deck, newPlayerCard) ->
val newHands = val newHands =
deck.playersHands.mapValues { (p, cards) -> deck.playersHands
.mapValues { (p, cards) ->
if (p == player) { if (p == player) {
cards + newPlayerCard cards + newPlayerCard
} else { } else {
cards cards
} }
} }.toPlayersHands()
deck.copy(playersHands = newHands) deck.copy(playersHands = newHands)
} }
@@ -79,7 +81,7 @@ fun Deck.initHands(
handSize: Int = 7, handSize: Int = 7,
): Deck { ): Deck {
// Copy cards from stack to the player hands // 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 -> return players.fold(deckWithEmptyHands) { acc: Deck, player: Player ->
val hand = acc.stack.take(handSize) val hand = acc.stack.take(handSize)
val newStack = acc.stack.filterNot { card: Card -> hand.contains(card) }.toStack() val newStack = acc.stack.filterNot { card: Card -> hand.contains(card) }.toStack()
@@ -93,11 +95,11 @@ fun Deck.initHands(
@JvmInline @JvmInline
@Serializable @Serializable
value class Stack( value class Stack(
val elems: Set<Card> = emptySet(), private val cards: Set<Card> = emptySet(),
) : Set<Card> by elems { ) : Set<Card> by cards {
operator fun plus(card: Card): Stack = elems.plus(card).toStack() 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<Card>.toStack(): Stack = Stack(this.toSet()) fun List<Card>.toStack(): Stack = Stack(this.toSet())
@@ -107,11 +109,11 @@ fun Set<Card>.toStack(): Stack = Stack(this)
@JvmInline @JvmInline
@Serializable @Serializable
value class Discard( value class Discard(
val elems: Set<Card> = emptySet(), private val cards: Set<Card> = emptySet(),
) : Set<Card> by elems { ) : Set<Card> by cards {
operator fun plus(card: Card): Discard = elems.plus(card).toDiscard() 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<Card>.toDiscard(): Discard = Discard(this.toSet()) fun List<Card>.toDiscard(): Discard = Discard(this.toSet())

View File

@@ -1,27 +0,0 @@
package eventDemo.app.entity
typealias PlayerHands = Map<Player, List<Card>>
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<Card>,
): PlayerHands =
mapValues { (p, cards) ->
if (p == player) {
cards + newCards
} else {
cards
}
}

View File

@@ -0,0 +1,37 @@
package eventDemo.app.entity
import kotlinx.serialization.Serializable
@Serializable
@JvmInline
value class PlayersHands(
private val map: Map<Player, List<Card>> = emptyMap(),
) : Map<Player, List<Card>> by map {
constructor(players: Set<Player>) : this(players.associateWith { emptyList<Card>() }.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<Card>,
): PlayersHands =
mapValues { (p, cards) ->
if (p == player) {
cards + newCards
} else {
cards
}
}.toPlayersHands()
}
fun Map<Player, List<Card>>.toPlayersHands(): PlayersHands = PlayersHands(this)

View File

@@ -11,11 +11,11 @@ class PlayerHandKtTest :
val playerNumbers = 4 val playerNumbers = 4
val players = (1..playerNumbers).map { Player(name = "name $it") }.toSet() val players = (1..playerNumbers).map { Player(name = "name $it") }.toSet()
val firstPlayer = players.first() val firstPlayer = players.first()
val playersHands: PlayerHands = players.associateWith { emptyList() } val playersHands = PlayersHands(players)
val card = Card.NumericCard(0, Card.Color.Red) val card = Card.NumericCard(0, Card.Color.Red)
// When // 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[firstPlayer]).size shouldBeExactly 1
assertNotNull(newHands[players.last()]).size shouldBeExactly 0 assertNotNull(newHands[players.last()]).size shouldBeExactly 0
@@ -28,13 +28,12 @@ class PlayerHandKtTest :
val firstPlayer = players.first() val firstPlayer = players.first()
val card1 = Card.NumericCard(1, Card.Color.Red) val card1 = Card.NumericCard(1, Card.Color.Red)
val card2 = Card.NumericCard(2, Card.Color.Red) val card2 = Card.NumericCard(2, Card.Color.Red)
val playersHands: PlayerHands = val playersHands: PlayersHands =
players PlayersHands(players)
.associateWith<Player, List<Card>> { emptyList() }
.addCards(firstPlayer, listOf(card1, card2)) .addCards(firstPlayer, listOf(card1, card2))
// When // When
val newHands: PlayerHands = playersHands.removeCard(firstPlayer, card1) val newHands: PlayersHands = playersHands.removeCard(firstPlayer, card1)
assertNotNull(newHands[firstPlayer]).size shouldBeExactly 1 assertNotNull(newHands[firstPlayer]).size shouldBeExactly 1
assertNotNull(newHands[players.last()]).size shouldBeExactly 0 assertNotNull(newHands[players.last()]).size shouldBeExactly 0