ADD: Tests for LudoGameMode::computePath
This commit is contained in:
parent
a278ce14c5
commit
12c617587f
@ -17,6 +17,15 @@ namespace ludo {
|
|||||||
struct PathNode {
|
struct PathNode {
|
||||||
PieceState state;
|
PieceState state;
|
||||||
int position;
|
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> {
|
||||||
|
|||||||
@ -35,4 +35,108 @@ TEST(LudoGameMode, SecondSixMovesOutOfBlockedEntry) {
|
|||||||
const auto& piece = mode.getState().getPieces()[0];
|
const auto& piece = mode.getState().getPieces()[0];
|
||||||
EXPECT_EQ(piece.state, ludo::PieceState::OnTrack);
|
EXPECT_EQ(piece.state, ludo::PieceState::OnTrack);
|
||||||
EXPECT_EQ(piece.position, 6);
|
EXPECT_EQ(piece.position, 6);
|
||||||
|
}
|
||||||
|
using ColorPosParam = std::tuple<ludo::PlayerColor, int>;
|
||||||
|
|
||||||
|
class MoveOutOfHomeTest : public ::testing::TestWithParam<ColorPosParam> {};
|
||||||
|
|
||||||
|
void assertPathIsWellFormed(const std::vector<ludo::PathNode>& path) {
|
||||||
|
using ludo::PieceState;
|
||||||
|
for (size_t i = 1; i < path.size(); ++i) {
|
||||||
|
const auto& prev = path[i - 1];
|
||||||
|
const auto& cur = path[i];
|
||||||
|
|
||||||
|
if (prev.state == PieceState::OnTrack && cur.state == PieceState::OnTrack) {
|
||||||
|
EXPECT_EQ(cur.position, (prev.position + 1) % ludo::kTrackLength) << "at i=" << i;
|
||||||
|
} else if (prev.state == PieceState::InHomeStretch && cur.state == PieceState::InHomeStretch) {
|
||||||
|
EXPECT_EQ(cur.position, prev.position + 1) << "at i=" << i;
|
||||||
|
} else if (prev.state == PieceState::OnTrack && cur.state == PieceState::InHomeStretch) {
|
||||||
|
EXPECT_EQ(cur.position, 0) << "at i=" << i;
|
||||||
|
} else if (prev.state == PieceState::InHomeStretch && cur.state == PieceState::Finished) {
|
||||||
|
EXPECT_EQ(prev.position, ludo::kHomeStretchLength - 1) << "at i=" << i;
|
||||||
|
} else if (prev.state == PieceState::AtHome && cur.state == PieceState::OnTrack) {
|
||||||
|
// ok, Position ist der Entry-Offset - separat geprüft
|
||||||
|
} else {
|
||||||
|
ADD_FAILURE() << "unerwarteter Zustandswechsel bei i=" << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(MoveOutOfHomeTest, EntersTrackAtEntryOffset) {
|
||||||
|
auto [color, startPos] = GetParam();
|
||||||
|
const int entry = ludo::LudoGameMode::getEntryOffset(color);
|
||||||
|
|
||||||
|
auto path = ludo::LudoGameMode::computePath(
|
||||||
|
color, ludo::PieceState::AtHome, startPos,
|
||||||
|
ludo::PieceState::OnTrack, entry);
|
||||||
|
|
||||||
|
ASSERT_EQ(path.size(), 2u);
|
||||||
|
EXPECT_EQ(path[0].state, ludo::PieceState::AtHome);
|
||||||
|
EXPECT_EQ(path[0].position, startPos);
|
||||||
|
EXPECT_EQ(path[1].state, ludo::PieceState::OnTrack);
|
||||||
|
EXPECT_EQ(path[1].position, entry);
|
||||||
|
assertPathIsWellFormed(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
AllColorsAllHomeSlots,
|
||||||
|
MoveOutOfHomeTest,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::Values(ludo::PlayerColor::Red, ludo::PlayerColor::Blue,
|
||||||
|
ludo::PlayerColor::Green, ludo::PlayerColor::Yellow),
|
||||||
|
::testing::Range(0, 4)));
|
||||||
|
|
||||||
|
int expectedStepCount(ludo::PlayerColor color, ludo::PieceState fromState, int fromPos, ludo::PieceState toState, int toPos) {
|
||||||
|
using ludo::PieceState;
|
||||||
|
const int entry = ludo::LudoGameMode::getEntryOffset(color);
|
||||||
|
int steps = 0;
|
||||||
|
PieceState state = fromState;
|
||||||
|
int pos = fromPos;
|
||||||
|
|
||||||
|
if (state == PieceState::AtHome) {
|
||||||
|
steps += 1;
|
||||||
|
state = PieceState::OnTrack;
|
||||||
|
pos = entry;
|
||||||
|
}
|
||||||
|
if (state == PieceState::OnTrack) {
|
||||||
|
if (toState == PieceState::OnTrack) {
|
||||||
|
return steps + (toPos - pos + ludo::kTrackLength) % ludo::kTrackLength;
|
||||||
|
}
|
||||||
|
steps += (entry - pos + ludo::kTrackLength) % ludo::kTrackLength; // bis zum Entry
|
||||||
|
steps += 1; // Abbiegen in Home Stretch (Pos 0)
|
||||||
|
state = PieceState::InHomeStretch;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
// state == InHomeStretch
|
||||||
|
if (toState == PieceState::InHomeStretch) {
|
||||||
|
return steps + (toPos - pos);
|
||||||
|
}
|
||||||
|
// toState == Finished
|
||||||
|
return steps + (ludo::kHomeStretchLength - 1 - pos) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(LudoGameMode, PathLengthMatchesIndependentFormula) {
|
||||||
|
using namespace ludo;
|
||||||
|
const std::vector<PlayerColor> colors = {
|
||||||
|
PlayerColor::Red, PlayerColor::Blue, PlayerColor::Green, PlayerColor::Yellow};
|
||||||
|
|
||||||
|
for (auto color : colors) {
|
||||||
|
for (int start = 0; start < kTrackLength; ++start) {
|
||||||
|
auto path = LudoGameMode::computePath(
|
||||||
|
color, PieceState::OnTrack, start,
|
||||||
|
PieceState::InHomeStretch, 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(path.size() - 1,
|
||||||
|
expectedStepCount(color, PieceState::OnTrack, start,
|
||||||
|
PieceState::InHomeStretch, 0))
|
||||||
|
<< "color=" << static_cast<int>(color) << " start=" << start;
|
||||||
|
|
||||||
|
EXPECT_EQ(path.front(), (PathNode{PieceState::OnTrack, start}));
|
||||||
|
EXPECT_EQ(path.back(), (PathNode{PieceState::InHomeStretch, 0}));
|
||||||
|
|
||||||
|
assertPathIsWellFormed(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user