From 594a7037af815020658ab127b6649b45bca0cbc1 Mon Sep 17 00:00:00 2001 From: Joffrey Bion Date: Wed, 24 Feb 2021 01:36:50 +0100 Subject: Improved state --- .../org/luxons/sevenwonders/model/PlayerState.kt | 46 ++++++++++++++++------ .../org/luxons/sevenwonders/model/TableState.kt | 4 +- .../sevenwonders/ui/components/game/GameScene.kt | 43 ++++++++++---------- .../luxons/sevenwonders/ui/components/game/Hand.kt | 22 ++++++----- .../org/luxons/sevenwonders/ui/redux/Reducers.kt | 36 +++++++---------- .../sevenwonders/ui/redux/sagas/RouteBasedSagas.kt | 2 +- 6 files changed, 83 insertions(+), 70 deletions(-) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/PlayerState.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/PlayerState.kt index 271b2a99..725b1654 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/PlayerState.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/PlayerState.kt @@ -1,37 +1,59 @@ package org.luxons.sevenwonders.model import kotlinx.serialization.Serializable +import org.luxons.sevenwonders.model.api.PlayerDTO import org.luxons.sevenwonders.model.boards.Board import org.luxons.sevenwonders.model.boards.RelativeBoardPosition +import org.luxons.sevenwonders.model.cards.CardBack +import org.luxons.sevenwonders.model.cards.HandCard +import org.luxons.sevenwonders.model.cards.HandRotationDirection import org.luxons.sevenwonders.model.wonders.WonderBuildability @Serializable -data class PlayerTurnInfo( +data class GameState( + val gameId: Long, val playerIndex: Int, - val table: TableState, + val currentAge: Age, + val players: List, + val boards: List, + val handRotationDirection: HandRotationDirection, val action: TurnAction, + val preparedCardsByUsername: Map = emptyMap(), + val currentPreparedMove: PlayerMove? = null, ) { - val currentAge: Int = table.currentAge - val message: String = action.message - val wonderBuildability: WonderBuildability = table.boards[playerIndex].wonder.buildability + val currentPreparedCard: HandCard? + get() { + val hand = (action as? TurnAction.PlayFromHand)?.hand + return hand?.firstOrNull { it.name == currentPreparedMove?.cardName } + } - val RelativeBoardPosition.index: Int - get() = getIndexFrom(playerIndex, table.boards.size) + val RelativeBoardPosition.absoluteIndex: Int + get() = getIndexFrom(playerIndex, boards.size) } -fun PlayerTurnInfo.getOwnBoard(): Board = table.boards[playerIndex] +fun GameState.getOwnBoard(): Board = boards[playerIndex] -fun PlayerTurnInfo.getBoard(position: RelativeBoardPosition): Board = table.boards[position.index] +fun GameState.getBoard(position: RelativeBoardPosition): Board = boards[position.absoluteIndex] -fun PlayerTurnInfo.getNonNeighbourBoards(): List { - val nPlayers = table.boards.size +fun GameState.getNonNeighbourBoards(): List { + val nPlayers = boards.size if (nPlayers <= 3) { return emptyList() } val first = (playerIndex + 2) % nPlayers val last = (playerIndex - 2 + nPlayers) % nPlayers val range = if (first <= last) first..last else ((first until nPlayers) + (0..last)) - return range.map { table.boards[it] } + return range.map { boards[it] } +} + +@Serializable +data class PlayerTurnInfo( + val playerIndex: Int, + val table: TableState, + val action: TurnAction, +) { + val currentAge: Int = table.currentAge + val wonderBuildability: WonderBuildability = table.boards[playerIndex].wonder.buildability } // TODO move to server code diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/TableState.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/TableState.kt index d27fccb5..e19ce272 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/TableState.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/TableState.kt @@ -12,6 +12,4 @@ data class TableState( val currentAge: Age, val handRotationDirection: HandRotationDirection, val lastPlayedMoves: List, -) { - val nbPlayers: Int = boards.size -} +) diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt index 74118d05..03ee881f 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt @@ -12,7 +12,6 @@ import org.luxons.sevenwonders.model.cards.HandCard import org.luxons.sevenwonders.model.resources.ResourceTransactionOptions import org.luxons.sevenwonders.ui.components.GlobalStyles import org.luxons.sevenwonders.ui.redux.* -import org.luxons.sevenwonders.ui.redux.GameState import react.* import styled.css import styled.getClassName @@ -21,7 +20,7 @@ import styled.styledDiv interface GameSceneStateProps : RProps { var currentPlayer: PlayerDTO? var players: List - var gameState: GameState? + var game: GameState? var preparedMove: PlayerMove? var preparedCard: HandCard? } @@ -57,17 +56,17 @@ private class GameScene(props: GameSceneProps) : RComponent = mapStateToProps = { state, _ -> currentPlayer = state.currentPlayer players = state.gameState?.players ?: emptyList() - gameState = state.gameState + game = state.gameState preparedMove = state.gameState?.currentPreparedMove preparedCard = state.gameState?.currentPreparedCard }, diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt index 08983228..2d5d8b8d 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt @@ -5,6 +5,7 @@ import kotlinx.css.* import kotlinx.css.properties.* import kotlinx.html.DIV import org.luxons.sevenwonders.model.* +import org.luxons.sevenwonders.model.boards.Board import org.luxons.sevenwonders.model.cards.CardPlayability import org.luxons.sevenwonders.model.cards.HandCard import org.luxons.sevenwonders.model.resources.ResourceTransactionOptions @@ -27,7 +28,8 @@ private enum class HandAction( } interface HandProps : RProps { - var turnInfo: PlayerTurnInfo + var action: TurnAction + var ownBoard: Board var preparedMove: PlayerMove? var prepareMove: (PlayerMove) -> Unit var startTransactionsSelection: (TransactionSelectorState) -> Unit @@ -36,7 +38,7 @@ interface HandProps : RProps { class HandComponent(props: HandProps) : RComponent(props) { override fun RBuilder.render() { - val hand = props.turnInfo.action.cardsToPlay() ?: return + val hand = props.action.cardsToPlay() ?: return styledDiv { css { handStyle() @@ -71,7 +73,7 @@ class HandComponent(props: HandProps) : RComponent(props) { block() cardImage(card) { css { - val isPlayable = card.playability.isPlayable || props.turnInfo.getOwnBoard().canPlayAnyCardForFree + val isPlayable = card.playability.isPlayable || props.ownBoard.canPlayAnyCardForFree handCardImgStyle(isPlayable) } } @@ -93,11 +95,11 @@ class HandComponent(props: HandProps) : RComponent(props) { } } bpButtonGroup { - val action = props.turnInfo.action + val action = props.action when (action) { is TurnAction.PlayFromHand -> { playCardButton(card, HandAction.PLAY) - if (props.turnInfo.getOwnBoard().canPlayAnyCardForFree) { + if (props.ownBoard.canPlayAnyCardForFree) { playCardButton(card.copy(playability = CardPlayability.SPECIAL_FREE), HandAction.PLAY_FREE) } } @@ -134,7 +136,7 @@ class HandComponent(props: HandProps) : RComponent(props) { } private fun RElementBuilder.upgradeWonderButton(card: HandCard) { - val wonderBuildability = props.turnInfo.wonderBuildability + val wonderBuildability = props.ownBoard.wonder.buildability bpButton( title = "UPGRADE WONDER (${wonderBuildabilityInfo(wonderBuildability)})", large = true, @@ -258,15 +260,15 @@ private fun CSSBuilder.handCardImgStyle(isPlayable: Boolean) { } fun RBuilder.handCards( - turnInfo: PlayerTurnInfo, - preparedMove: PlayerMove?, + game: GameState, prepareMove: (PlayerMove) -> Unit, startTransactionsSelection: (TransactionSelectorState) -> Unit, ) { child(HandComponent::class) { attrs { - this.turnInfo = turnInfo - this.preparedMove = preparedMove + this.action = game.action + this.ownBoard = game.getOwnBoard() + this.preparedMove = game.currentPreparedMove this.prepareMove = prepareMove this.startTransactionsSelection = startTransactionsSelection } diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt index bf6aaf2e..082387c6 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt @@ -1,14 +1,10 @@ package org.luxons.sevenwonders.ui.redux -import org.luxons.sevenwonders.model.PlayerMove -import org.luxons.sevenwonders.model.PlayerTurnInfo -import org.luxons.sevenwonders.model.TurnAction +import org.luxons.sevenwonders.model.GameState import org.luxons.sevenwonders.model.api.ConnectedPlayer import org.luxons.sevenwonders.model.api.GameListEvent import org.luxons.sevenwonders.model.api.LobbyDTO import org.luxons.sevenwonders.model.api.PlayerDTO -import org.luxons.sevenwonders.model.cards.CardBack -import org.luxons.sevenwonders.model.cards.HandCard import redux.RAction data class SwState( @@ -25,20 +21,6 @@ data class SwState( val games: List = gamesById.values.toList() } -data class GameState( - val id: Long, - val players: List, - val turnInfo: PlayerTurnInfo?, - val preparedCardsByUsername: Map = emptyMap(), - val currentPreparedMove: PlayerMove? = null, -) { - val currentPreparedCard: HandCard? - get() { - val hand = (turnInfo?.action as? TurnAction.PlayFromHand)?.hand - return hand?.firstOrNull { it.name == currentPreparedMove?.cardName } - } -} - fun rootReducer(state: SwState, action: RAction): SwState = state.copy( gamesById = gamesReducer(state.gamesById, action), connectedPlayer = currentPlayerReducer(state.connectedPlayer, action), @@ -73,9 +55,15 @@ private fun currentLobbyReducer(currentLobby: LobbyDTO?, action: RAction): Lobby private fun gameStateReducer(gameState: GameState?, action: RAction): GameState? = when (action) { is EnterGameAction -> GameState( - id = action.lobby.id, + gameId = action.lobby.id, players = action.lobby.players, - turnInfo = action.turnInfo, + playerIndex = action.turnInfo.playerIndex, + currentAge = action.turnInfo.table.currentAge, + boards = action.turnInfo.table.boards, + handRotationDirection = action.turnInfo.table.handRotationDirection, + action = action.turnInfo.action, + preparedCardsByUsername = emptyMap(), + currentPreparedMove = null, ) is PreparedMoveEvent -> gameState?.copy(currentPreparedMove = action.move) is RequestUnprepareMove -> gameState?.copy(currentPreparedMove = null) @@ -89,7 +77,11 @@ private fun gameStateReducer(gameState: GameState?, action: RAction): GameState? ) is TurnInfoEvent -> gameState?.copy( players = gameState.players.map { p -> p.copy(isReady = false) }, - turnInfo = action.turnInfo, + playerIndex = action.turnInfo.playerIndex, + currentAge = action.turnInfo.table.currentAge, + boards = action.turnInfo.table.boards, + handRotationDirection = action.turnInfo.table.handRotationDirection, + action = action.turnInfo.action, preparedCardsByUsername = emptyMap(), currentPreparedMove = null, ) diff --git a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/RouteBasedSagas.kt b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/RouteBasedSagas.kt index af2624ec..b2fad7e1 100644 --- a/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/RouteBasedSagas.kt +++ b/sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/RouteBasedSagas.kt @@ -50,7 +50,7 @@ suspend fun SwSagaContext.lobbySaga(session: SevenWondersSession) { suspend fun SwSagaContext.gameSaga(session: SevenWondersSession) { val game = reduxState.gameState ?: error("Game saga run without a current game") coroutineScope { - session.watchGameEvents(game.id).map { + session.watchGameEvents(game.gameId).map { when (it) { is GameEvent.NewTurnStarted -> TurnInfoEvent(it.turnInfo) is GameEvent.MovePrepared -> PreparedMoveEvent(it.move) -- cgit