players hands and deck is modify on PlayerHavePassEvent & CardIsPlayedEvent events

This commit is contained in:
2025-03-05 01:48:19 +01:00
parent 4b6eaaf58c
commit 32472018d4
3 changed files with 52 additions and 13 deletions

View File

@@ -6,9 +6,9 @@ import kotlinx.serialization.Serializable
data class Deck( data class Deck(
val stack: Set<Card> = emptySet(), val stack: Set<Card> = emptySet(),
val discard: Set<Card> = emptySet(), val discard: Set<Card> = emptySet(),
val playersHands: List<PlayerHand> = emptyList(), val playersHands: PlayerHands = emptyMap(),
) { ) {
constructor(players: List<Player>) : this(playersHands = players.map { PlayerHand(it) }) constructor(players: List<Player>) : this(playersHands = players.associateWith { emptyList<Card>() })
fun putOneCardOnDiscard(): Deck { fun putOneCardOnDiscard(): Deck {
val takenCard = stack.first() val takenCard = stack.first()
@@ -16,20 +16,54 @@ data class Deck(
return copy(stack = newStack) return copy(stack = newStack)
} }
fun take(n: Int): Pair<Deck, List<Card>> { private fun take(n: Int): Pair<Deck, List<Card>> {
val takenCards = stack.take(n) val takenCards = stack.take(n)
val newStack = stack.filterNot { takenCards.contains(it) }.toSet() val newStack = stack.filterNot { takenCards.contains(it) }.toSet()
return Pair(copy(stack = newStack), takenCards) return Pair(copy(stack = newStack), takenCards)
} }
private fun takeOne(): Pair<Deck, Card> = take(1).let { (deck, cards) -> Pair(deck, cards.first()) }
fun takeOneCardTo(player: Player): Deck =
takeOne().let { (deck, newPlayerCard) ->
val newHands =
deck.playersHands.mapValues { (p, cards) ->
if (p == player) {
cards + newPlayerCard
} else {
cards
}
}
deck.copy(playersHands = newHands)
}
fun putOneCardFromHand(
player: Player,
card: Card,
): Deck =
run {
// Validate parameters
val playerHand =
playersHands[player]
?: error("No player on this game")
if (playerHand.none { it == card }) {
error("No card exist on the player hand")
}
}.let {
copy(
discard = discard + card,
playersHands = playersHands.addCard(player, card),
)
}
companion object { companion object {
fun initHands( fun initHands(
players: Set<Player>, players: Set<Player>,
handSize: Int = 7, handSize: Int = 7,
): Deck { ): Deck {
val deck = new() val deck = new()
val playersHands = players.map { PlayerHand(it, deck.stack.take(handSize)) } val playersHands = players.associateWith { deck.stack.take(handSize) }
val allTakenCards = playersHands.flatMap { it.cards } val allTakenCards = playersHands.flatMap { it.value }
val newStack = deck.stack.filterNot { allTakenCards.contains(it) }.toSet() val newStack = deck.stack.filterNot { allTakenCards.contains(it) }.toSet()
return deck.copy( return deck.copy(
stack = newStack, stack = newStack,

View File

@@ -1,11 +1,14 @@
package eventDemo.app.entity package eventDemo.app.entity
import kotlinx.serialization.Serializable typealias PlayerHands = Map<Player, List<Card>>
@Serializable fun PlayerHands.addCard(
data class PlayerHand( player: Player,
val player: Player, card: Card,
val cards: List<Card> = emptyList(), ) = mapValues { (p, cards) ->
) { if (p == player) {
val count = lazy { cards.count() } cards - card
} else {
cards
}
} }

View File

@@ -37,6 +37,7 @@ private fun GameId.buildStateFromEvents(events: List<GameEvent>): GameState =
lastPlayer = event.player, lastPlayer = event.player,
direction = direction, direction = direction,
lastColor = color, lastColor = color,
deck = state.deck.putOneCardFromHand(event.player, event.card),
) )
} }
@@ -57,6 +58,7 @@ private fun GameId.buildStateFromEvents(events: List<GameEvent>): GameState =
is PlayerHavePassEvent -> { is PlayerHavePassEvent -> {
state.copy( state.copy(
lastPlayer = event.player, lastPlayer = event.player,
deck = state.deck.takeOneCardTo(event.player),
) )
} }
@@ -69,7 +71,7 @@ private fun GameId.buildStateFromEvents(events: List<GameEvent>): GameState =
is GameStartedEvent -> { is GameStartedEvent -> {
state.copy( state.copy(
lastColor = (event.deck.discard.first() as? Card.ColorCard)?.color, lastColor = (event.deck.discard.first() as? Card.ColorCard)?.color,
lastCard = eventDemo.app.GameState.LastCard(event.deck.discard.first(), event.firstPlayer), lastCard = GameState.LastCard(event.deck.discard.first(), event.firstPlayer),
lastPlayer = event.firstPlayer, lastPlayer = event.firstPlayer,
deck = event.deck, deck = event.deck,
isStarted = true, isStarted = true,