From b6908cc712779344b35fc0f2da913e52f9e1cc9f Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Wed, 5 Mar 2025 02:08:05 +0100 Subject: [PATCH] create ICantPlayCommand + move canBePlayThisCard --- src/main/kotlin/eventDemo/app/GameState.kt | 71 +++++++++++++++++++ .../app/command/GameCommandHandler.kt | 2 + .../app/command/command/ICantPlayCommand.kt | 45 ++++++++++++ .../command/command/IWantToPlayCardCommand.kt | 70 ++---------------- 4 files changed, 124 insertions(+), 64 deletions(-) create mode 100644 src/main/kotlin/eventDemo/app/command/command/ICantPlayCommand.kt diff --git a/src/main/kotlin/eventDemo/app/GameState.kt b/src/main/kotlin/eventDemo/app/GameState.kt index 9eac142..82b71d9 100644 --- a/src/main/kotlin/eventDemo/app/GameState.kt +++ b/src/main/kotlin/eventDemo/app/GameState.kt @@ -76,4 +76,75 @@ data class GameState( if (lastCard == null) error("No card") return this.playerDiffIndex(lastCard.player) == 1 } + + fun playableCards(player: Player): List = + deck + .playersHands[player] + ?.filter { canBePlayThisCard(player, it) } + ?: emptyList() + + fun canBePlayThisCard( + player: Player, + card: Card, + ): Boolean { + val cardOnBoard = lastCard?.card ?: return false + return when (cardOnBoard) { + is Card.NumericCard -> { + when (card) { + is Card.AllColorCard -> true + is Card.NumericCard -> card.number == cardOnBoard.number || card.color == cardOnBoard.color + is Card.ColorCard -> card.color == cardOnBoard.color + } + } + + is Card.ReverseCard -> { + when (card) { + is Card.ReverseCard -> true + is Card.AllColorCard -> true + is Card.ColorCard -> card.color == cardOnBoard.color + } + } + + is Card.PassCard -> { + if (player.cardOnBoardIsForYou) { + false + } else { + when (card) { + is Card.AllColorCard -> true + is Card.ColorCard -> card.color == cardOnBoard.color + } + } + } + + is Card.ChangeColorCard -> { + when (card) { + is Card.AllColorCard -> true + is Card.ColorCard -> card.color == lastColor + } + } + + is Card.Plus2Card -> { + if (player.cardOnBoardIsForYou && card is Card.Plus2Card) { + true + } else { + when (card) { + is Card.AllColorCard -> true + is Card.Plus2Card -> true + is Card.ColorCard -> card.color == cardOnBoard.color + } + } + } + + is Card.Plus4Card -> { + if (player.cardOnBoardIsForYou && card is Card.Plus4Card) { + true + } else { + when (card) { + is Card.AllColorCard -> true + is Card.ColorCard -> card.color == lastColor + } + } + } + } + } } diff --git a/src/main/kotlin/eventDemo/app/command/GameCommandHandler.kt b/src/main/kotlin/eventDemo/app/command/GameCommandHandler.kt index c32ceed..e7064a8 100644 --- a/src/main/kotlin/eventDemo/app/command/GameCommandHandler.kt +++ b/src/main/kotlin/eventDemo/app/command/GameCommandHandler.kt @@ -2,6 +2,7 @@ package eventDemo.app.command import eventDemo.app.GameState import eventDemo.app.command.command.GameCommand +import eventDemo.app.command.command.ICantPlayCommand import eventDemo.app.command.command.IWantToJoinTheGameCommand import eventDemo.app.command.command.IWantToPlayCardCommand import eventDemo.app.command.command.IamReadyToPlayCommand @@ -46,6 +47,7 @@ class GameCommandHandler( is IWantToPlayCardCommand -> command.run(gameState, playerNotifier, eventStream) is IamReadyToPlayCommand -> command.run(gameState, playerNotifier, eventStream) is IWantToJoinTheGameCommand -> command.run(gameState, playerNotifier, eventStream) + is ICantPlayCommand -> command.run(gameState, playerNotifier, eventStream) } } } diff --git a/src/main/kotlin/eventDemo/app/command/command/ICantPlayCommand.kt b/src/main/kotlin/eventDemo/app/command/command/ICantPlayCommand.kt new file mode 100644 index 0000000..7f115cd --- /dev/null +++ b/src/main/kotlin/eventDemo/app/command/command/ICantPlayCommand.kt @@ -0,0 +1,45 @@ +package eventDemo.app.command.command + +import eventDemo.app.GameState +import eventDemo.app.entity.GameId +import eventDemo.app.entity.Player +import eventDemo.app.event.GameEventStream +import eventDemo.app.event.event.PlayerHavePassEvent +import eventDemo.libs.command.CommandId +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * A command to perform an action to play a new card + */ +@Serializable +@SerialName("Pass") +data class ICantPlayCommand( + override val payload: Payload, +) : GameCommand { + override val id: CommandId = CommandId() + + @Serializable + data class Payload( + override val gameId: GameId, + override val player: Player, + ) : GameCommand.Payload + + fun run( + state: GameState, + playerNotifier: (String) -> Unit, + eventStream: GameEventStream, + ) { + val playableCards = state.playableCards(payload.player) + if (playableCards.isEmpty()) { + eventStream.publish( + PlayerHavePassEvent( + payload.gameId, + payload.player, + ), + ) + } else { + playerNotifier("You can and must play one card, like ${playableCards.first()::class.simpleName}") + } + } +} diff --git a/src/main/kotlin/eventDemo/app/command/command/IWantToPlayCardCommand.kt b/src/main/kotlin/eventDemo/app/command/command/IWantToPlayCardCommand.kt index d5bfdb8..13264d8 100644 --- a/src/main/kotlin/eventDemo/app/command/command/IWantToPlayCardCommand.kt +++ b/src/main/kotlin/eventDemo/app/command/command/IWantToPlayCardCommand.kt @@ -32,7 +32,12 @@ data class IWantToPlayCardCommand( playerNotifier: (String) -> Unit, eventStream: GameEventStream, ) { - if (state.canBePlayThisCard()) { + if (!state.isReady) { + playerNotifier("The game is Not started") + return + } + + if (state.canBePlayThisCard(payload.player, payload.card)) { eventStream.publish( CardIsPlayedEvent( payload.gameId, @@ -44,67 +49,4 @@ data class IWantToPlayCardCommand( playerNotifier("You cannot play this card") } } - - fun GameState.canBePlayThisCard(): Boolean { - if (!isReady) return false - val cardOnBoard = lastCard?.card ?: return false - return when (cardOnBoard) { - is Card.NumericCard -> { - when (payload.card) { - is Card.AllColorCard -> true - is Card.NumericCard -> payload.card.number == cardOnBoard.number || payload.card.color == cardOnBoard.color - is Card.ColorCard -> payload.card.color == cardOnBoard.color - } - } - - is Card.ReverseCard -> { - when (payload.card) { - is Card.ReverseCard -> true - is Card.AllColorCard -> true - is Card.ColorCard -> payload.card.color == cardOnBoard.color - } - } - - is Card.PassCard -> { - if (payload.player.cardOnBoardIsForYou) { - false - } else { - when (payload.card) { - is Card.AllColorCard -> true - is Card.ColorCard -> payload.card.color == cardOnBoard.color - } - } - } - - is Card.ChangeColorCard -> { - when (payload.card) { - is Card.AllColorCard -> true - is Card.ColorCard -> payload.card.color == lastColor - } - } - - is Card.Plus2Card -> { - if (payload.player.cardOnBoardIsForYou && payload.card is Card.Plus2Card) { - true - } else { - when (payload.card) { - is Card.AllColorCard -> true - is Card.Plus2Card -> true - is Card.ColorCard -> payload.card.color == cardOnBoard.color - } - } - } - - is Card.Plus4Card -> { - if (payload.player.cardOnBoardIsForYou && payload.card is Card.Plus4Card) { - true - } else { - when (payload.card) { - is Card.AllColorCard -> true - is Card.ColorCard -> payload.card.color == lastColor - } - } - } - } - } }