Adding board unit tests.

This commit is contained in:
Ólafur Waage 2021-09-28 14:34:48 +02:00
parent f916953056
commit 3a02ae2316
3 changed files with 91 additions and 26 deletions

View file

@ -60,7 +60,7 @@ static Cell cellAtPosition(GridPosition point) {
}
bool isWalkableForPacMan(GridPosition point) {
return cellAtPosition(point) != Cell::wall;
return cellAtPosition(point) != Cell::wall && cellAtPosition(point) != Cell::pen;
}
bool isWalkableForGhost(GridPosition point, GridPosition origin, bool isEyes) {
@ -79,6 +79,26 @@ bool isPortal(GridPosition point, Direction direction) {
(cellAtPosition(point) == Cell::right_portal && direction == Direction::RIGHT);
}
bool isIntersection(GridPosition point) {
if (!isWalkableForPacMan(point) || cellAtPosition(point) == Cell::left_portal || cellAtPosition(point) == Cell::right_portal) {
return false;
}
const GridPosition right{ point.x + 1, point.y };
const bool rightWalkable = isWalkableForPacMan(right);
const GridPosition left{ point.x - 1, point.y };
const bool leftWalkable = isWalkableForPacMan(left);
const GridPosition top{ point.x, point.y - 1 };
const bool topWalkable = isWalkableForPacMan(top);
const GridPosition bottom{ point.x, point.y + 1 };
const bool bottomWalkable = isWalkableForPacMan(bottom);
return (topWalkable && rightWalkable) || (rightWalkable && bottomWalkable) || (bottomWalkable && leftWalkable) || (leftWalkable && topWalkable);
}
GridPosition teleport(GridPosition point) {
size_t right = COLUMNS - 1;
size_t left = 0;
@ -124,26 +144,4 @@ std::vector<GridPosition> initialSuperPelletPositions() {
return positions;
}
// AI
bool isIntersection(GridPosition point) {
if (!isWalkableForPacMan(point) || cellAtPosition(point) == Cell::left_portal || cellAtPosition(point) == Cell::right_portal) {
return false;
}
const GridPosition right{ point.x + 1, point.y };
const bool rightWalkable = isWalkableForPacMan(right);
const GridPosition left{ point.x - 1, point.y };
const bool leftWalkable = isWalkableForPacMan(left);
const GridPosition top{ point.x, point.y - 1 };
const bool topWalkable = isWalkableForPacMan(top);
const GridPosition bottom{ point.x, point.y + 1 };
const bool bottomWalkable = isWalkableForPacMan(bottom);
return (topWalkable && rightWalkable) || (rightWalkable && bottomWalkable) || (bottomWalkable && leftWalkable) || (leftWalkable && topWalkable);
}
} // namespace pacman

View file

@ -12,10 +12,11 @@ bool isWalkableForPacMan(GridPosition point);
bool isWalkableForGhost(GridPosition point, GridPosition origin, bool isEyes);
bool isInPen(GridPosition point);
bool isPortal(GridPosition point, Direction direction);
bool isIntersection(GridPosition point);
GridPosition teleport(GridPosition point);
std::vector<GridPosition> initialPelletPositions();
std::vector<GridPosition> initialSuperPelletPositions();
inline Position penDoorPosition() {
@ -25,6 +26,4 @@ inline Position initialPacManPosition() {
return { 13.5, 23 };
}
bool isIntersection(GridPosition point);
} // namespace pacman

68
test/testBoard.cpp Normal file
View file

@ -0,0 +1,68 @@
#include "Board.hpp"
#include <catch2/catch.hpp>
// These tests assume a static game board.
TEST_CASE("Is walkable for Pac-Man", "[board]") {
REQUIRE_FALSE(pacman::isWalkableForPacMan(pacman::GridPosition{ 0, 0 })); // wall
REQUIRE_FALSE(pacman::isWalkableForPacMan(pacman::GridPosition{ 27, 0 })); // wall
REQUIRE_FALSE(pacman::isWalkableForPacMan(pacman::GridPosition{ 0, 30 })); // wall
REQUIRE_FALSE(pacman::isWalkableForPacMan(pacman::GridPosition{ 27, 30 })); // wall
REQUIRE_FALSE(pacman::isWalkableForPacMan(pacman::GridPosition{ 11, 13 })); // pen
REQUIRE(pacman::isWalkableForPacMan(pacman::GridPosition{ 1, 1 })); // pellet
REQUIRE(pacman::isWalkableForPacMan(pacman::GridPosition{ 1, 3 })); // power pellet
REQUIRE(pacman::isWalkableForPacMan(pacman::GridPosition{ 1, 14 })); // nothing
REQUIRE(pacman::isWalkableForPacMan(pacman::GridPosition{ 0, 14 })); // portal left
REQUIRE(pacman::isWalkableForPacMan(pacman::GridPosition{ 27, 14 })); // portal right
}
TEST_CASE("Is walkable for Ghost", "[board]") {
const pacman::GridPosition pen = pacman::GridPosition{ 11, 13 };
const pacman::GridPosition outside = pacman::GridPosition{ 1, 1 };
// wall check
REQUIRE_FALSE(pacman::isWalkableForGhost(pacman::GridPosition{ 0, 0 }, outside, false)); // wall
REQUIRE_FALSE(pacman::isWalkableForGhost(pacman::GridPosition{ 27, 0 }, outside, false)); // wall
REQUIRE_FALSE(pacman::isWalkableForGhost(pacman::GridPosition{ 0, 30 }, outside, false)); // wall
REQUIRE_FALSE(pacman::isWalkableForGhost(pacman::GridPosition{ 27, 30 }, outside, false)); // wall
// eyes can walk anywhere except walls
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 11, 13 }, outside, true)); // pen
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 1, 1 }, outside, true)); // pellet
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 1, 3 }, outside, true)); // power pellet
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 1, 14 }, outside, true)); // nothing
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 0, 14 }, outside, true)); // portal left
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 27, 14 }, outside, true)); // portal right
// can only walk in pen if that is your origin or current location
REQUIRE_FALSE(pacman::isWalkableForGhost(pacman::GridPosition{ 11, 13 }, outside, false)); // in pen, origin outside
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 1, 1 }, outside, false)); // outside, origin outside
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 1, 1 }, pen, false)); // outside, origin pen
REQUIRE(pacman::isWalkableForGhost(pacman::GridPosition{ 11, 13 }, pen, false)); // in pen, origin pen
}
TEST_CASE("Is portal", "[board]") {
const pacman::GridPosition portalRight = pacman::GridPosition{ 27, 14 };
const pacman::GridPosition portalLeft = pacman::GridPosition{ 0, 14 };
REQUIRE(pacman::isPortal(portalRight, pacman::Direction::RIGHT)); // right into right portal
REQUIRE(pacman::isPortal(portalLeft, pacman::Direction::LEFT)); // left into left portal
REQUIRE_FALSE(pacman::isPortal(portalRight, pacman::Direction::LEFT)); // left into right portal
REQUIRE_FALSE(pacman::isPortal(portalLeft, pacman::Direction::RIGHT)); // right into left portal
}
TEST_CASE("Teleport", "[board]") {
const pacman::GridPosition portalRight = pacman::GridPosition{ 27, 14 };
const pacman::GridPosition portalLeft = pacman::GridPosition{ 0, 14 };
if (pacman::isPortal(portalRight, pacman::Direction::RIGHT)) {
const pacman::GridPosition result = pacman::teleport(portalRight);
REQUIRE(result.x == portalLeft.x);
}
if (pacman::isPortal(portalLeft, pacman::Direction::LEFT)) {
const pacman::GridPosition result = pacman::teleport(portalLeft);
REQUIRE(result.x == portalRight.x);
}
}