summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/PlayerState.kt46
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/TableState.kt4
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/GameScene.kt43
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/components/game/Hand.kt22
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/Reducers.kt36
-rw-r--r--sw-ui/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/RouteBasedSagas.kt2
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)
bgstack15