diff --git a/game/src/ludo/LudoGameMode.cpp b/game/src/ludo/LudoGameMode.cpp index 86b69a8..c1d2cec 100644 --- a/game/src/ludo/LudoGameMode.cpp +++ b/game/src/ludo/LudoGameMode.cpp @@ -20,41 +20,17 @@ std::vector ludo::LudoGameMode::pollEvents() { return events; } -std::optional ludo::LudoGameMode::findLowestHomeSlotPiece(PlayerColor color) const { - for (int i = 0; i < static_cast(m_gameState.m_pieces.size()); ++i) { - const auto& piece = m_gameState.m_pieces[i]; - if (piece.color == color && piece.state == PieceState::AtHome) { - return i; // erste Übereinstimmung = kleinster Home-Slot, dank Erzeugungsreihenfolge - } - } - return std::nullopt; -} +ludo::LudoRules::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIndex, int diceValue) { + auto result = LudoRules::computeMoveResult(m_gameState, pieceIndex, diceValue); -ludo::LudoGameMode::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIndex, int diceValue) { Piece& piece = m_gameState.m_pieces[pieceIndex]; - int fromPosition = piece.position; + piece.state = result.targetState; + piece.position = result.toPosition; - Destination destination = LudoRules::computeDestination(m_gameState, piece, diceValue).value(); - - PieceState startState = piece.state; - PieceState targetState = destination.state; - piece.state = destination.state; - piece.position = destination.position; - MoveResult result{fromPosition, piece.position, false, -1, targetState, startState}; - - - if (piece.state == PieceState::OnTrack) { - for (int i = 0; i < static_cast(m_gameState.m_pieces.size()); ++i) { - if (i == pieceIndex) continue; - Piece& other = m_gameState.m_pieces[i]; - if (other.color != piece.color && other.state == PieceState::OnTrack && other.position == piece.position) { - other.state = PieceState::AtHome; - other.position = -1; - result.captured = true; - result.capturedPieceIndex = i; - break; // dank Blockade-Regel kann max. eine gegnerische Figur auf einem Feld stehen - } - } + if (result.captured) { + Piece& capturedPiece = m_gameState.m_pieces[result.capturedPieceIndex]; + capturedPiece.state = PieceState::AtHome; + capturedPiece.position = -1; } return result; @@ -78,8 +54,8 @@ void ludo::LudoGameMode::handle(const RollDiceCommand &command) { publishEvent(DiceRolledEvent(command.player, m_gameState.m_diceValue)); if (m_gameState.m_diceValue == 6) { - if (auto homeIndex = findLowestHomeSlotPiece(getColorOf(command.player))) { - if (!LudoRules::isBlockedByOwnPiece(m_gameState, getColorOf(command.player), PieceState::OnTrack, getEntryOffset(getColorOf(command.player)))) { + if (auto homeIndex = LudoRules::findLowestHomeSlotPiece(m_gameState, getColorOf(command.player))) { + if (!LudoRules::isBlockedByOwnPiece(m_gameState, getColorOf(command.player), PieceState::OnTrack, LudoRules::getEntryOffset(getColorOf(command.player)))) { autoReleasePiece(*homeIndex); finishTurn(); return; @@ -154,10 +130,6 @@ int ludo::LudoGameMode::rollDice() { return m_diceSource->roll(); } -int ludo::LudoGameMode::getEntryOffset(PlayerColor color) { - return static_cast(color) * 10; -} - void ludo::LudoGameMode::publishEvent(LudoEvent event) { m_pendingEvents.push_back(event); m_eventBus.publish(event); diff --git a/game/src/ludo/LudoGameMode.h b/game/src/ludo/LudoGameMode.h index 048caf4..9368742 100644 --- a/game/src/ludo/LudoGameMode.h +++ b/game/src/ludo/LudoGameMode.h @@ -13,6 +13,7 @@ #include "LudoTypes.h" #include "core/events/EventBus.h" #include "game/TurnBasedGameMode.h" +#include "gameMode/LudoRules.h" namespace ludo { @@ -26,24 +27,12 @@ namespace ludo { [[nodiscard]] const LudoGameState& getState() const override { return m_gameState; } [[nodiscard]] PlayerColor getColorOf(engine::PlayerID playerID) const; - - [[nodiscard]] static int getEntryOffset(PlayerColor color); - - void setDiceSource(std::unique_ptr diceSource) { m_diceSource = std::move(diceSource); } private: engine::EventBus& m_eventBus; - struct MoveResult { - int fromPosition = 0; - int toPosition = 0; - bool captured = false; - int capturedPieceIndex = -1; - PieceState targetState = PieceState::OnTrack; - PieceState startState = PieceState::OnTrack; - }; - [[nodiscard]] std::optional findLowestHomeSlotPiece(PlayerColor color) const; - MoveResult movePieceInternal(int pieceIndex, int diceValue); + + LudoRules::MoveResult movePieceInternal(int pieceIndex, int diceValue); void autoReleasePiece(int pieceIndex); void handle(const RollDiceCommand &command); diff --git a/game/src/ludo/gameMode/LudoRules.cpp b/game/src/ludo/gameMode/LudoRules.cpp index 0189018..2c5edbb 100644 --- a/game/src/ludo/gameMode/LudoRules.cpp +++ b/game/src/ludo/gameMode/LudoRules.cpp @@ -82,3 +82,39 @@ std::vector ludo::LudoRules::getMoveablePieceIndices(const LudoGameState &s } return moveablePieceIndices; } + +std::optional ludo::LudoRules::findLowestHomeSlotPiece(const LudoGameState &state, PlayerColor color) { + for (int i = 0; i < static_cast(state.getPieces().size()); ++i) { + const auto& piece = state.getPieces()[i]; + if (piece.color == color && piece.state == PieceState::AtHome) { + return i; // erste Übereinstimmung = kleinster Home-Slot, dank Erzeugungsreihenfolge + } + } + return std::nullopt; +} + +ludo::LudoRules::MoveResult ludo::LudoRules::computeMoveResult(const LudoGameState &state, int pieceIndex, int diceValue) { + const Piece& piece = state.getPieces()[pieceIndex]; + int fromPosition = piece.position; + + Destination destination = computeDestination(state, piece, diceValue).value(); + + PieceState startState = piece.state; + PieceState targetState = destination.state; + + MoveResult result{fromPosition, destination.position, false, -1, targetState, startState}; + + if (targetState == PieceState::OnTrack) { + for (int i = 0; i < static_cast(state.getPieces().size()); ++i) { + if (i == pieceIndex) continue; + const Piece& other = state.getPieces()[i]; + if (other.color != piece.color && other.state == PieceState::OnTrack && other.position == destination.position) { + result.captured = true; + result.capturedPieceIndex = i; + break; // dank Blockade-Regel max. eine gegnerische Figur pro Feld + } + } + } + + return result; +} diff --git a/game/src/ludo/gameMode/LudoRules.h b/game/src/ludo/gameMode/LudoRules.h index 3071fe6..4392756 100644 --- a/game/src/ludo/gameMode/LudoRules.h +++ b/game/src/ludo/gameMode/LudoRules.h @@ -33,6 +33,19 @@ namespace ludo { static std::vector getMoveablePieceIndices(const LudoGameState& state, PlayerColor color, int diceValue); + static std::optional findLowestHomeSlotPiece(const LudoGameState& state, PlayerColor color); + + struct MoveResult { + int fromPosition = 0; + int toPosition = 0; + bool captured = false; + int capturedPieceIndex = -1; + PieceState targetState = PieceState::OnTrack; + PieceState startState = PieceState::OnTrack; + }; + static MoveResult computeMoveResult(const LudoGameState& state, int pieceIndex, int diceValue); + + };