diff --git a/CMakeLists.txt b/CMakeLists.txt index 39b711f..d081d7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -287,8 +287,8 @@ add_library(GameLib STATIC game/src/gameLayer/GameInput.cpp game/src/gameLayer/GameInput.h game/src/gameLayer/gameController/LudoGameControllerContext.h - game/src/ludo/LudoRules.cpp - game/src/ludo/LudoRules.h + game/src/ludo/gameMode/LudoRules.cpp + game/src/ludo/gameMode/LudoRules.h game/src/ludo/gameMode/PiecePathBuilder.cpp game/src/ludo/gameMode/PiecePathBuilder.h game/src/ludo/gameMode/PathNode.h diff --git a/game/src/ludo/LudoGameMode.cpp b/game/src/ludo/LudoGameMode.cpp index 32baaea..a8f15ba 100644 --- a/game/src/ludo/LudoGameMode.cpp +++ b/game/src/ludo/LudoGameMode.cpp @@ -7,6 +7,7 @@ #include #include +#include "gameMode/LudoRules.h" #include "spdlog/spdlog.h" void ludo::LudoGameMode::sendCommand(const std::variant &command) { @@ -19,34 +20,6 @@ std::vector ludo::LudoGameMode::pollEvents() { return events; } -[[nodiscard]] std::optional ludo::LudoGameMode::computeDestination(const Piece &piece, int diceValue) const { - switch (piece.state) { - case PieceState::AtHome: - return Destination{PieceState::OnTrack, getEntryOffset(piece.color)}; - - case PieceState::OnTrack: { - int distanceTraveled = (piece.position - getEntryOffset(piece.color) + kTrackLength) % kTrackLength; - int newDistance = distanceTraveled + diceValue; - if (newDistance <= kTrackLength - 1) { - return Destination{PieceState::OnTrack, (piece.position + diceValue) % kTrackLength}; - } - int homeIndex = newDistance - kTrackLength; - if (homeIndex > kHomeStretchLength - 1) return std::nullopt; // überzählig - return Destination{homeIndex == kHomeStretchLength - 1 ? PieceState::Finished : PieceState::InHomeStretch, homeIndex}; - } - - case PieceState::InHomeStretch: { - int newIndex = piece.position + diceValue; - if (newIndex > kHomeStretchLength - 1) return std::nullopt; // überzählig - return Destination{newIndex == kHomeStretchLength - 1 ? PieceState::Finished : PieceState::InHomeStretch, newIndex}; - } - - case PieceState::Finished: - return std::nullopt; // nie bewegbar - } - return std::nullopt; -} - 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]; @@ -61,7 +34,7 @@ ludo::LudoGameMode::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIn Piece& piece = m_gameState.m_pieces[pieceIndex]; int fromPosition = piece.position; - Destination destination = computeDestination(piece, diceValue).value(); + Destination destination = LudoRules::computeDestination(m_gameState, piece, diceValue).value(); PieceState startState = piece.state; PieceState targetState = destination.state; @@ -182,7 +155,7 @@ std::vector ludo::LudoGameMode::getMoveablePieceIndices(PlayerColor color, const Piece& piece = m_gameState.getPieces()[i]; if (piece.color != color) continue; - Destination dest = computeDestination(piece, diceValue).value(); + Destination dest = LudoRules::computeDestination(m_gameState, piece, diceValue).value(); // Überschuss in der Zielgeraden abfangen: computeDestination liefert bei Überschuss // aktuell denselben Zustand zurück, wie unten in computeDestination definiert @@ -201,7 +174,7 @@ std::vector ludo::LudoGameMode::getMoveablePieceIndices(PlayerColor color, std::optional ludo::LudoGameMode::wouldCapture(int pieceIndex, int diceValue) const { const auto& piece = m_gameState.m_pieces[pieceIndex]; - auto dest = computeDestination(piece, diceValue); + auto dest = LudoRules::computeDestination(m_gameState, piece, diceValue); if (dest.value().state != PieceState::OnTrack) return std::nullopt; for (int i = 0; i < static_cast(m_gameState.m_pieces.size()); ++i) { diff --git a/game/src/ludo/LudoGameMode.h b/game/src/ludo/LudoGameMode.h index 184fdaf..16261fd 100644 --- a/game/src/ludo/LudoGameMode.h +++ b/game/src/ludo/LudoGameMode.h @@ -15,19 +15,6 @@ #include "game/TurnBasedGameMode.h" namespace ludo { - struct PathNode { - PieceState state; - int position; - - friend bool operator==(const PathNode& lhs, const PathNode& rhs) { - return lhs.state == rhs.state && lhs.position == rhs.position; - } - - static inline void PrintTo(const PathNode& node, std::ostream* os) { - *os << "PathNode{state=" << static_cast(node.state) - << ", position=" << node.position << "}"; - } - }; class LudoGameMode: public engine::TurnBasedGameMode { public: @@ -56,13 +43,6 @@ namespace ludo { PieceState targetState = PieceState::OnTrack; PieceState startState = PieceState::OnTrack; }; - - struct Destination { - PieceState state; - int position; - }; - - std::optional computeDestination(const Piece &piece, int diceValue) const; [[nodiscard]] std::optional findLowestHomeSlotPiece(PlayerColor color) const; MoveResult movePieceInternal(int pieceIndex, int diceValue); diff --git a/game/src/ludo/LudoRules.cpp b/game/src/ludo/LudoRules.cpp deleted file mode 100644 index 8e2bae8..0000000 --- a/game/src/ludo/LudoRules.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// Created by sebastian on 05.08.26. -// - -#include "LudoRules.h" - -int ludo::LudoRules::getEntryOffset(PlayerColor color) { - return static_cast(color) * 10; -} diff --git a/game/src/ludo/PiecePresenter.cpp b/game/src/ludo/PiecePresenter.cpp index 209a843..245e8fe 100644 --- a/game/src/ludo/PiecePresenter.cpp +++ b/game/src/ludo/PiecePresenter.cpp @@ -42,7 +42,7 @@ void ludo::PiecePresenter::onPieceMoved(const ludo::PieceMovedEvent &event, cons auto entity = m_pieceEntities[event.pieceIndex]; engine::animation::TransformAnimationComponent animationComponent; - std::vector path = PiecePathBuilder::computePath(piece.color, event.startState, event.fromPosition, event.targetState, event.toPosition); + std::vector path = PiecePathBuilder::computePath(piece.color, event.startState, event.fromPosition, event.targetState, event.toPosition); std::vector pathPositions; for (const auto& node : path) { pathPositions.push_back(m_layout.getWorldPosition(piece.color, node.state, node.position)); diff --git a/game/src/ludo/gameMode/LudoRules.cpp b/game/src/ludo/gameMode/LudoRules.cpp new file mode 100644 index 0000000..55537fb --- /dev/null +++ b/game/src/ludo/gameMode/LudoRules.cpp @@ -0,0 +1,37 @@ +// +// Created by sebastian on 05.08.26. +// + +#include "LudoRules.h" + +int ludo::LudoRules::getEntryOffset(PlayerColor color) { + return static_cast(color) * 10; +} + +std::optional ludo::LudoRules::computeDestination(const LudoGameState &state, const Piece &piece, int diceValue) { + switch (piece.state) { + case PieceState::AtHome: + return Destination{PieceState::OnTrack, getEntryOffset(piece.color)}; + + case PieceState::OnTrack: { + int distanceTraveled = (piece.position - getEntryOffset(piece.color) + kTrackLength) % kTrackLength; + int newDistance = distanceTraveled + diceValue; + if (newDistance <= kTrackLength - 1) { + return Destination{PieceState::OnTrack, (piece.position + diceValue) % kTrackLength}; + } + int homeIndex = newDistance - kTrackLength; + if (homeIndex > kHomeStretchLength - 1) return std::nullopt; // überzählig + return Destination{homeIndex == kHomeStretchLength - 1 ? PieceState::Finished : PieceState::InHomeStretch, homeIndex}; + } + + case PieceState::InHomeStretch: { + int newIndex = piece.position + diceValue; + if (newIndex > kHomeStretchLength - 1) return std::nullopt; // überzählig + return Destination{newIndex == kHomeStretchLength - 1 ? PieceState::Finished : PieceState::InHomeStretch, newIndex}; + } + + case PieceState::Finished: + return std::nullopt; // nie bewegbar + } + return std::nullopt; +} diff --git a/game/src/ludo/LudoRules.h b/game/src/ludo/gameMode/LudoRules.h similarity index 66% rename from game/src/ludo/LudoRules.h rename to game/src/ludo/gameMode/LudoRules.h index 4e2c8ee..b1e255d 100644 --- a/game/src/ludo/LudoRules.h +++ b/game/src/ludo/gameMode/LudoRules.h @@ -4,12 +4,18 @@ #ifndef COLORRACE_LUDORULES_H #define COLORRACE_LUDORULES_H -#include "LudoTypes.h" +#include + +#include "../LudoTypes.h" +#include "ludo/LudoGameState.h" // LudoRules.h namespace ludo { - + struct Destination { + PieceState state; + int position; + }; class LudoRules { public: // Alles hier: reine Funktionen, keine Member, kein Zustand. @@ -17,13 +23,12 @@ namespace ludo { static int getEntryOffset(PlayerColor color); + static std::optional computeDestination(const LudoGameState& state, + const Piece& piece, int diceValue); }; - struct Destination { - PieceState state; - int position; - }; + } // namespace ludo diff --git a/game/src/ludo/gameMode/PiecePathBuilder.cpp b/game/src/ludo/gameMode/PiecePathBuilder.cpp index b2ba145..523bdbc 100644 --- a/game/src/ludo/gameMode/PiecePathBuilder.cpp +++ b/game/src/ludo/gameMode/PiecePathBuilder.cpp @@ -7,7 +7,7 @@ #include #include "ludo/LudoGameMode.h" -#include "ludo/LudoRules.h" +#include "LudoRules.h" namespace { int stateOrder(ludo::PieceState state) { @@ -21,7 +21,7 @@ namespace { } } -std::vector ludo::PiecePathBuilder::computePath(PlayerColor color, PieceState startingState, +std::vector ludo::PiecePathBuilder::computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition) { auto errorContext = [&]() { return std::format( diff --git a/game/src/ludo/gameMode/PiecePathBuilder.h b/game/src/ludo/gameMode/PiecePathBuilder.h index 2ecd55d..d02735f 100644 --- a/game/src/ludo/gameMode/PiecePathBuilder.h +++ b/game/src/ludo/gameMode/PiecePathBuilder.h @@ -6,8 +6,8 @@ #define COLORRACE_PIECEPATHBUILDER_H #include + #include "PathNode.h" -#include "ludo/LudoGameMode.h" #include "ludo/LudoTypes.h" @@ -15,7 +15,7 @@ namespace ludo { class PiecePathBuilder { public: - static std::vector computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition); + static std::vector computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition); }; }