diff options
author | Joffrey Bion <joffrey.bion@gmail.com> | 2021-02-24 01:36:50 +0100 |
---|---|---|
committer | Joffrey Bion <joffrey.bion@gmail.com> | 2021-02-24 01:36:50 +0100 |
commit | 594a7037af815020658ab127b6649b45bca0cbc1 (patch) | |
tree | 5f1ffad6be5ddcb4107f0075888573493061591d | |
parent | Remove unnecessary flex style from selfBoardSummary (diff) | |
download | seven-wonders-594a7037af815020658ab127b6649b45bca0cbc1.tar.gz seven-wonders-594a7037af815020658ab127b6649b45bca0cbc1.tar.bz2 seven-wonders-594a7037af815020658ab127b6649b45bca0cbc1.zip |
Improved state
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<PlayerDTO>, + val boards: List<Board>, + val handRotationDirection: HandRotationDirection, val action: TurnAction, + val preparedCardsByUsername: Map<String, CardBack?> = 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<Board> { - val nPlayers = table.boards.size +fun GameState.getNonNeighbourBoards(): List<Board> { + 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<PlayedMove>, -) { - 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<PlayerDTO> - var gameState: GameState? + var game: GameState? var preparedMove: PlayerMove? var preparedCard: HandCard? } @@ -57,17 +56,17 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, Game +GlobalStyles.papyrusBackground +GlobalStyles.fullscreen } - val turnInfo = props.gameState?.turnInfo - if (turnInfo == null) { + val game = props.game + if (game == null) { bpNonIdealState(icon = "error", title = "Error: no game data") } else { - turnInfoScene(turnInfo) + boardScene(game) } } } - private fun RBuilder.turnInfoScene(turnInfo: PlayerTurnInfo) { - val board = turnInfo.getOwnBoard() + private fun RBuilder.boardScene(game: GameState) { + val board = game.getOwnBoard() styledDiv { css { height = 100.pct @@ -75,11 +74,11 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, Game +GameStyles.pulsatingRed } } - val action = turnInfo.action + val action = game.action if (action is TurnAction.WatchScore) { scoreTableOverlay(action.scoreBoard, props.players, props.leaveGame) } - actionInfo(turnInfo.message) + actionInfo(game.action.message) boardComponent(board = board) { css { padding(all = 7.rem) // to fit the action info message & board summaries @@ -90,24 +89,24 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, Game transactionsSelectorDialog( state = state.transactionSelector, neighbours = playerNeighbours(), - prepareMove = ::prepareMove, + prepareMove = ::prepareMoveAndCloseTransactions, cancelTransactionSelection = ::resetTransactionSelector, ) - boardSummaries(turnInfo) - handRotationIndicator(turnInfo.table.handRotationDirection) - handCards(turnInfo, props.preparedMove, props.prepareMove, ::startTransactionSelection) + boardSummaries(game) + handRotationIndicator(game.handRotationDirection) + handCards(game, props.prepareMove, ::startTransactionSelection) val card = props.preparedCard val move = props.preparedMove if (card != null && move != null) { preparedMove(card, move) } - if (turnInfo.action is TurnAction.SayReady) { + if (game.action is TurnAction.SayReady) { sayReadyButton() } } } - private fun prepareMove(move: PlayerMove) { + private fun prepareMoveAndCloseTransactions(move: PlayerMove) { props.prepareMove(move) setState { transactionSelector = null } } @@ -125,7 +124,7 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, Game if (onlyMeInTheGame || props.preparedMove != null) { return false } - val gameState = props.gameState ?: return false + val gameState = props.game ?: return false return gameState.preparedCardsByUsername.values.count { it != null } == props.players.size - 1 } @@ -156,11 +155,11 @@ private class GameScene(props: GameSceneProps) : RComponent<GameSceneProps, Game } } - private fun RBuilder.boardSummaries(turnInfo: PlayerTurnInfo) { - val leftBoard = turnInfo.getBoard(RelativeBoardPosition.LEFT) - val rightBoard = turnInfo.getBoard(RelativeBoardPosition.RIGHT) - val topBoards = turnInfo.getNonNeighbourBoards().reversed() - selfBoardSummary(turnInfo.getOwnBoard()) + private fun RBuilder.boardSummaries(game: GameState) { + val leftBoard = game.getBoard(RelativeBoardPosition.LEFT) + val rightBoard = game.getBoard(RelativeBoardPosition.RIGHT) + val topBoards = game.getNonNeighbourBoards().reversed() + selfBoardSummary(game.getOwnBoard()) leftPlayerBoardSummary(leftBoard) rightPlayerBoardSummary(rightBoard) if (topBoards.isNotEmpty()) { @@ -295,7 +294,7 @@ private val gameScene: RClass<GameSceneProps> = 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<HandProps, RState>(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<HandProps, RState>(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<HandProps, RState>(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<HandProps, RState>(props) { } private fun RElementBuilder<IButtonGroupProps>.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<LobbyDTO> = gamesById.values.toList() } -data class GameState( - val id: Long, - val players: List<PlayerDTO>, - val turnInfo: PlayerTurnInfo?, - val preparedCardsByUsername: Map<String, CardBack?> = 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) |