ADD: Tests for LudoGameMode::computePath
This commit is contained in:
parent
a278ce14c5
commit
12c617587f
@ -17,6 +17,15 @@ 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> {
|
||||
|
||||
@ -35,4 +35,108 @@ TEST(LudoGameMode, SecondSixMovesOutOfBlockedEntry) {
|
||||
const auto& piece = mode.getState().getPieces()[0];
|
||||
EXPECT_EQ(piece.state, ludo::PieceState::OnTrack);
|
||||
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