UPD: Move computeDestination to LudoRules
This commit is contained in:
parent
a3bb54f041
commit
7426374b00
@ -287,8 +287,8 @@ add_library(GameLib STATIC
|
|||||||
game/src/gameLayer/GameInput.cpp
|
game/src/gameLayer/GameInput.cpp
|
||||||
game/src/gameLayer/GameInput.h
|
game/src/gameLayer/GameInput.h
|
||||||
game/src/gameLayer/gameController/LudoGameControllerContext.h
|
game/src/gameLayer/gameController/LudoGameControllerContext.h
|
||||||
game/src/ludo/LudoRules.cpp
|
game/src/ludo/gameMode/LudoRules.cpp
|
||||||
game/src/ludo/LudoRules.h
|
game/src/ludo/gameMode/LudoRules.h
|
||||||
game/src/ludo/gameMode/PiecePathBuilder.cpp
|
game/src/ludo/gameMode/PiecePathBuilder.cpp
|
||||||
game/src/ludo/gameMode/PiecePathBuilder.h
|
game/src/ludo/gameMode/PiecePathBuilder.h
|
||||||
game/src/ludo/gameMode/PathNode.h
|
game/src/ludo/gameMode/PathNode.h
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "gameMode/LudoRules.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
void ludo::LudoGameMode::sendCommand(const std::variant<MovePieceCommand, RollDiceCommand> &command) {
|
void ludo::LudoGameMode::sendCommand(const std::variant<MovePieceCommand, RollDiceCommand> &command) {
|
||||||
@ -19,34 +20,6 @@ std::vector<ludo::LudoEvent> ludo::LudoGameMode::pollEvents() {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::optional<ludo::LudoGameMode::Destination> 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<int> ludo::LudoGameMode::findLowestHomeSlotPiece(PlayerColor color) const {
|
std::optional<int> ludo::LudoGameMode::findLowestHomeSlotPiece(PlayerColor color) const {
|
||||||
for (int i = 0; i < static_cast<int>(m_gameState.m_pieces.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(m_gameState.m_pieces.size()); ++i) {
|
||||||
const auto& piece = m_gameState.m_pieces[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];
|
Piece& piece = m_gameState.m_pieces[pieceIndex];
|
||||||
int fromPosition = piece.position;
|
int fromPosition = piece.position;
|
||||||
|
|
||||||
Destination destination = computeDestination(piece, diceValue).value();
|
Destination destination = LudoRules::computeDestination(m_gameState, piece, diceValue).value();
|
||||||
|
|
||||||
PieceState startState = piece.state;
|
PieceState startState = piece.state;
|
||||||
PieceState targetState = destination.state;
|
PieceState targetState = destination.state;
|
||||||
@ -182,7 +155,7 @@ std::vector<int> ludo::LudoGameMode::getMoveablePieceIndices(PlayerColor color,
|
|||||||
const Piece& piece = m_gameState.getPieces()[i];
|
const Piece& piece = m_gameState.getPieces()[i];
|
||||||
if (piece.color != color) continue;
|
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
|
// Überschuss in der Zielgeraden abfangen: computeDestination liefert bei Überschuss
|
||||||
// aktuell denselben Zustand zurück, wie unten in computeDestination definiert
|
// aktuell denselben Zustand zurück, wie unten in computeDestination definiert
|
||||||
@ -201,7 +174,7 @@ std::vector<int> ludo::LudoGameMode::getMoveablePieceIndices(PlayerColor color,
|
|||||||
|
|
||||||
std::optional<int> ludo::LudoGameMode::wouldCapture(int pieceIndex, int diceValue) const {
|
std::optional<int> ludo::LudoGameMode::wouldCapture(int pieceIndex, int diceValue) const {
|
||||||
const auto& piece = m_gameState.m_pieces[pieceIndex];
|
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;
|
if (dest.value().state != PieceState::OnTrack) return std::nullopt;
|
||||||
|
|
||||||
for (int i = 0; i < static_cast<int>(m_gameState.m_pieces.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(m_gameState.m_pieces.size()); ++i) {
|
||||||
|
|||||||
@ -15,19 +15,6 @@
|
|||||||
#include "game/TurnBasedGameMode.h"
|
#include "game/TurnBasedGameMode.h"
|
||||||
|
|
||||||
namespace ludo {
|
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<int>(node.state)
|
|
||||||
<< ", position=" << node.position << "}";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class LudoGameMode: public engine::TurnBasedGameMode<LudoCommand, LudoEvent, LudoGameState> {
|
class LudoGameMode: public engine::TurnBasedGameMode<LudoCommand, LudoEvent, LudoGameState> {
|
||||||
public:
|
public:
|
||||||
@ -56,13 +43,6 @@ namespace ludo {
|
|||||||
PieceState targetState = PieceState::OnTrack;
|
PieceState targetState = PieceState::OnTrack;
|
||||||
PieceState startState = PieceState::OnTrack;
|
PieceState startState = PieceState::OnTrack;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Destination {
|
|
||||||
PieceState state;
|
|
||||||
int position;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::optional<Destination> computeDestination(const Piece &piece, int diceValue) const;
|
|
||||||
[[nodiscard]] std::optional<int> findLowestHomeSlotPiece(PlayerColor color) const;
|
[[nodiscard]] std::optional<int> findLowestHomeSlotPiece(PlayerColor color) const;
|
||||||
|
|
||||||
MoveResult movePieceInternal(int pieceIndex, int diceValue);
|
MoveResult movePieceInternal(int pieceIndex, int diceValue);
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by sebastian on 05.08.26.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "LudoRules.h"
|
|
||||||
|
|
||||||
int ludo::LudoRules::getEntryOffset(PlayerColor color) {
|
|
||||||
return static_cast<int>(color) * 10;
|
|
||||||
}
|
|
||||||
@ -42,7 +42,7 @@ void ludo::PiecePresenter::onPieceMoved(const ludo::PieceMovedEvent &event, cons
|
|||||||
auto entity = m_pieceEntities[event.pieceIndex];
|
auto entity = m_pieceEntities[event.pieceIndex];
|
||||||
|
|
||||||
engine::animation::TransformAnimationComponent animationComponent;
|
engine::animation::TransformAnimationComponent animationComponent;
|
||||||
std::vector<ludo::PathNode> path = PiecePathBuilder::computePath(piece.color, event.startState, event.fromPosition, event.targetState, event.toPosition);
|
std::vector<PathNode> path = PiecePathBuilder::computePath(piece.color, event.startState, event.fromPosition, event.targetState, event.toPosition);
|
||||||
std::vector<glm::vec3> pathPositions;
|
std::vector<glm::vec3> pathPositions;
|
||||||
for (const auto& node : path) {
|
for (const auto& node : path) {
|
||||||
pathPositions.push_back(m_layout.getWorldPosition(piece.color, node.state, node.position));
|
pathPositions.push_back(m_layout.getWorldPosition(piece.color, node.state, node.position));
|
||||||
|
|||||||
37
game/src/ludo/gameMode/LudoRules.cpp
Normal file
37
game/src/ludo/gameMode/LudoRules.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 05.08.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "LudoRules.h"
|
||||||
|
|
||||||
|
int ludo::LudoRules::getEntryOffset(PlayerColor color) {
|
||||||
|
return static_cast<int>(color) * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ludo::Destination> 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;
|
||||||
|
}
|
||||||
@ -4,12 +4,18 @@
|
|||||||
|
|
||||||
#ifndef COLORRACE_LUDORULES_H
|
#ifndef COLORRACE_LUDORULES_H
|
||||||
#define COLORRACE_LUDORULES_H
|
#define COLORRACE_LUDORULES_H
|
||||||
#include "LudoTypes.h"
|
#include <optional>
|
||||||
|
|
||||||
|
#include "../LudoTypes.h"
|
||||||
|
#include "ludo/LudoGameState.h"
|
||||||
|
|
||||||
|
|
||||||
// LudoRules.h
|
// LudoRules.h
|
||||||
namespace ludo {
|
namespace ludo {
|
||||||
|
struct Destination {
|
||||||
|
PieceState state;
|
||||||
|
int position;
|
||||||
|
};
|
||||||
class LudoRules {
|
class LudoRules {
|
||||||
public:
|
public:
|
||||||
// Alles hier: reine Funktionen, keine Member, kein Zustand.
|
// Alles hier: reine Funktionen, keine Member, kein Zustand.
|
||||||
@ -17,13 +23,12 @@ namespace ludo {
|
|||||||
|
|
||||||
static int getEntryOffset(PlayerColor color);
|
static int getEntryOffset(PlayerColor color);
|
||||||
|
|
||||||
|
static std::optional<Destination> computeDestination(const LudoGameState& state,
|
||||||
|
const Piece& piece, int diceValue);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Destination {
|
|
||||||
PieceState state;
|
|
||||||
int position;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ludo
|
} // namespace ludo
|
||||||
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
#include "ludo/LudoGameMode.h"
|
#include "ludo/LudoGameMode.h"
|
||||||
#include "ludo/LudoRules.h"
|
#include "LudoRules.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int stateOrder(ludo::PieceState state) {
|
int stateOrder(ludo::PieceState state) {
|
||||||
@ -21,7 +21,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ludo::PathNode> ludo::PiecePathBuilder::computePath(PlayerColor color, PieceState startingState,
|
std::vector<PathNode> ludo::PiecePathBuilder::computePath(PlayerColor color, PieceState startingState,
|
||||||
int startPosition, PieceState targetState, int targetPosition) {
|
int startPosition, PieceState targetState, int targetPosition) {
|
||||||
auto errorContext = [&]() {
|
auto errorContext = [&]() {
|
||||||
return std::format(
|
return std::format(
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
#define COLORRACE_PIECEPATHBUILDER_H
|
#define COLORRACE_PIECEPATHBUILDER_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
#include "PathNode.h"
|
#include "PathNode.h"
|
||||||
#include "ludo/LudoGameMode.h"
|
|
||||||
#include "ludo/LudoTypes.h"
|
#include "ludo/LudoTypes.h"
|
||||||
|
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ namespace ludo {
|
|||||||
|
|
||||||
class PiecePathBuilder {
|
class PiecePathBuilder {
|
||||||
public:
|
public:
|
||||||
static std::vector<ludo::PathNode> computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition);
|
static std::vector<PathNode> computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user