UPD: Compute MoveResult before mutating state of piece
This commit is contained in:
parent
f86e1b872a
commit
4ab4ea5262
@ -20,41 +20,17 @@ std::vector<ludo::LudoEvent> ludo::LudoGameMode::pollEvents() {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> ludo::LudoGameMode::findLowestHomeSlotPiece(PlayerColor color) const {
|
ludo::LudoRules::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIndex, int diceValue) {
|
||||||
for (int i = 0; i < static_cast<int>(m_gameState.m_pieces.size()); ++i) {
|
auto result = LudoRules::computeMoveResult(m_gameState, pieceIndex, diceValue);
|
||||||
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::LudoGameMode::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIndex, int diceValue) {
|
|
||||||
Piece& piece = m_gameState.m_pieces[pieceIndex];
|
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();
|
if (result.captured) {
|
||||||
|
Piece& capturedPiece = m_gameState.m_pieces[result.capturedPieceIndex];
|
||||||
PieceState startState = piece.state;
|
capturedPiece.state = PieceState::AtHome;
|
||||||
PieceState targetState = destination.state;
|
capturedPiece.position = -1;
|
||||||
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<int>(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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -78,8 +54,8 @@ void ludo::LudoGameMode::handle(const RollDiceCommand &command) {
|
|||||||
publishEvent(DiceRolledEvent(command.player, m_gameState.m_diceValue));
|
publishEvent(DiceRolledEvent(command.player, m_gameState.m_diceValue));
|
||||||
|
|
||||||
if (m_gameState.m_diceValue == 6) {
|
if (m_gameState.m_diceValue == 6) {
|
||||||
if (auto homeIndex = findLowestHomeSlotPiece(getColorOf(command.player))) {
|
if (auto homeIndex = LudoRules::findLowestHomeSlotPiece(m_gameState, getColorOf(command.player))) {
|
||||||
if (!LudoRules::isBlockedByOwnPiece(m_gameState, getColorOf(command.player), PieceState::OnTrack, getEntryOffset(getColorOf(command.player)))) {
|
if (!LudoRules::isBlockedByOwnPiece(m_gameState, getColorOf(command.player), PieceState::OnTrack, LudoRules::getEntryOffset(getColorOf(command.player)))) {
|
||||||
autoReleasePiece(*homeIndex);
|
autoReleasePiece(*homeIndex);
|
||||||
finishTurn();
|
finishTurn();
|
||||||
return;
|
return;
|
||||||
@ -154,10 +130,6 @@ int ludo::LudoGameMode::rollDice() {
|
|||||||
return m_diceSource->roll();
|
return m_diceSource->roll();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ludo::LudoGameMode::getEntryOffset(PlayerColor color) {
|
|
||||||
return static_cast<int>(color) * 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ludo::LudoGameMode::publishEvent(LudoEvent event) {
|
void ludo::LudoGameMode::publishEvent(LudoEvent event) {
|
||||||
m_pendingEvents.push_back(event);
|
m_pendingEvents.push_back(event);
|
||||||
m_eventBus.publish(event);
|
m_eventBus.publish(event);
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include "LudoTypes.h"
|
#include "LudoTypes.h"
|
||||||
#include "core/events/EventBus.h"
|
#include "core/events/EventBus.h"
|
||||||
#include "game/TurnBasedGameMode.h"
|
#include "game/TurnBasedGameMode.h"
|
||||||
|
#include "gameMode/LudoRules.h"
|
||||||
|
|
||||||
namespace ludo {
|
namespace ludo {
|
||||||
|
|
||||||
@ -26,24 +27,12 @@ namespace ludo {
|
|||||||
|
|
||||||
[[nodiscard]] const LudoGameState& getState() const override { return m_gameState; }
|
[[nodiscard]] const LudoGameState& getState() const override { return m_gameState; }
|
||||||
[[nodiscard]] PlayerColor getColorOf(engine::PlayerID playerID) const;
|
[[nodiscard]] PlayerColor getColorOf(engine::PlayerID playerID) const;
|
||||||
|
|
||||||
[[nodiscard]] static int getEntryOffset(PlayerColor color);
|
|
||||||
|
|
||||||
|
|
||||||
void setDiceSource(std::unique_ptr<IDiceSource> diceSource) { m_diceSource = std::move(diceSource); }
|
void setDiceSource(std::unique_ptr<IDiceSource> diceSource) { m_diceSource = std::move(diceSource); }
|
||||||
private:
|
private:
|
||||||
engine::EventBus<LudoEvent>& m_eventBus;
|
engine::EventBus<LudoEvent>& 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<int> findLowestHomeSlotPiece(PlayerColor color) const;
|
|
||||||
|
|
||||||
MoveResult movePieceInternal(int pieceIndex, int diceValue);
|
|
||||||
|
LudoRules::MoveResult movePieceInternal(int pieceIndex, int diceValue);
|
||||||
void autoReleasePiece(int pieceIndex);
|
void autoReleasePiece(int pieceIndex);
|
||||||
|
|
||||||
void handle(const RollDiceCommand &command);
|
void handle(const RollDiceCommand &command);
|
||||||
|
|||||||
@ -82,3 +82,39 @@ std::vector<int> ludo::LudoRules::getMoveablePieceIndices(const LudoGameState &s
|
|||||||
}
|
}
|
||||||
return moveablePieceIndices;
|
return moveablePieceIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<int> ludo::LudoRules::findLowestHomeSlotPiece(const LudoGameState &state, PlayerColor color) {
|
||||||
|
for (int i = 0; i < static_cast<int>(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<int>(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;
|
||||||
|
}
|
||||||
|
|||||||
@ -33,6 +33,19 @@ namespace ludo {
|
|||||||
|
|
||||||
static std::vector<int> getMoveablePieceIndices(const LudoGameState& state, PlayerColor color, int diceValue);
|
static std::vector<int> getMoveablePieceIndices(const LudoGameState& state, PlayerColor color, int diceValue);
|
||||||
|
|
||||||
|
static std::optional<int> 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);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user