Browse Source

Use Point in path_ functions that reference position

In cases like path_get_h_cost this allows simplifying logic where Point provides functions for the intended behaviour in a much simpler to understand package.

This also makes it clearer which functions are const/don't modify the node and which potentially have side effects.
pull/2415/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
a8ed1998d1
  1. 7
      Source/controls/plrctrls.cpp
  2. 2
      Source/monster.cpp
  3. 89
      Source/path.cpp
  4. 14
      Source/path.h
  5. 2
      Source/player.cpp
  6. 76
      test/path_test.cpp

7
Source/controls/plrctrls.cpp

@ -91,7 +91,7 @@ int GetDistance(Point destination, int maxDistance)
}
int8_t walkpath[MAX_PATH_LENGTH];
int steps = FindPath([](Point position) { return PosOkPlayer(MyPlayerId, position); }, Players[MyPlayerId].position.future.x, Players[MyPlayerId].position.future.y, destination.x, destination.y, walkpath);
int steps = FindPath([](Point position) { return PosOkPlayer(MyPlayerId, position); }, Players[MyPlayerId].position.future, destination, walkpath);
if (steps > maxDistance)
return 0;
@ -293,10 +293,7 @@ void FindMeleeTarget()
continue;
}
PATHNODE pPath;
pPath.position = { node.x, node.y };
if (path_solid_pieces(&pPath, dx, dy)) {
if (path_solid_pieces({ node.x, node.y }, { dx, dy })) {
queue.push_back({ dx, dy, node.steps + 1 });
visited[dx][dy] = true;
}

2
Source/monster.cpp

@ -2116,7 +2116,7 @@ bool AiPlanWalk(int i)
assert((DWORD)i < MAXMONSTERS);
auto &monster = Monsters[i];
if (FindPath([&monster](Point position) { return IsTileAccessible(monster, position); }, monster.position.tile.x, monster.position.tile.y, monster.enemyPosition.x, monster.enemyPosition.y, path) == 0) {
if (FindPath([&monster](Point position) { return IsTileAccessible(monster, position); }, monster.position.tile, monster.enemyPosition, path) == 0) {
return false;
}

89
Source/path.cpp

@ -92,7 +92,7 @@ bool IsTileWalkable(Point position, bool ignoreDoors)
* check that each step is a valid position. Store the step directions (see
* path_directions) in path, which must have room for 24 steps
*/
int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH])
int FindPath(const std::function<bool(Point)> &posOk, Point start, Point destination, int8_t path[MAX_PATH_LENGTH])
{
// clear all nodes, create root nodes for the visited/frontier linked lists
gdwCurNodes = 0;
@ -101,16 +101,15 @@ int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, in
gdwCurPathStep = 0;
PATHNODE *pathStart = path_new_step();
pathStart->g = 0;
pathStart->h = path_get_h_cost(sx, sy, dx, dy);
pathStart->position.x = sx;
pathStart->h = path_get_h_cost(start, destination);
pathStart->f = pathStart->h + pathStart->g;
pathStart->position.y = sy;
pathStart->position = start;
path_2_nodes->NextNode = pathStart;
// A* search until we find (dx,dy) or fail
PATHNODE *nextNode;
while ((nextNode = GetNextPath()) != nullptr) {
// reached the end, success!
if (nextNode->position.x == dx && nextNode->position.y == dy) {
if (nextNode->position == destination) {
PATHNODE *current = nextNode;
int pathLength = 0;
while (current->Parent != nullptr) {
@ -128,7 +127,7 @@ int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, in
return 0;
}
// ran out of nodes, abort!
if (!path_get_path(posOk, nextNode, dx, dy))
if (!path_get_path(posOk, nextNode, destination))
return 0;
}
// frontier is empty, no path!
@ -138,16 +137,10 @@ int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, in
/**
* @brief heuristic, estimated cost from (sx,sy) to (dx,dy)
*/
int path_get_h_cost(int sx, int sy, int dx, int dy)
int path_get_h_cost(Point source, Point destination)
{
int deltaX = abs(sx - dx);
int deltaY = abs(sy - dy);
int min = deltaX < deltaY ? deltaX : deltaY;
int max = deltaX > deltaY ? deltaX : deltaY;
// see path_check_equal for why this is times 2
return 2 * (min + max);
return 2 * source.ManhattanDistance(destination);
}
/**
@ -157,9 +150,9 @@ int path_get_h_cost(int sx, int sy, int dx, int dy)
* of sqrt(2). That's approximately 1.5, so they multiply all step costs by 2,
* except diagonal steps which are times 3
*/
int path_check_equal(PATHNODE *pPath, int dx, int dy)
int path_check_equal(Point position, Point destination)
{
if (pPath->position.x == dx || pPath->position.y == dy)
if (position.x == destination.x || position.y == destination.y)
return 2;
return 3;
@ -184,7 +177,7 @@ PATHNODE *GetNextPath()
}
/**
* @brief check if stepping from pPath to (dx,dy) cuts a corner.
* @brief check if stepping from a given position to a neighbouring tile cuts a corner.
*
* If you step from A to B, both Xs need to be clear:
*
@ -193,21 +186,23 @@ PATHNODE *GetNextPath()
*
* @return true if step is allowed
*/
bool path_solid_pieces(PATHNODE *pPath, int dx, int dy)
bool path_solid_pieces(Point position, Point destination)
{
// These checks are written as if working backwards from the destination to the source, given
// both tiles are expected to be adjacent this doesn't matter beyond being a bit confusing
bool rv = true;
switch (path_directions[3 * (dy - pPath->position.y) + 3 - pPath->position.x + 1 + dx]) {
case 5:
rv = IsTileNotSolid({ dx, dy + 1 }) && IsTileNotSolid({ dx + 1, dy });
switch (path_directions[3 * (destination.y - position.y) + 3 - position.x + 1 + destination.x]) {
case 5: // Stepping north
rv = IsTileNotSolid(destination + DIR_SW) && IsTileNotSolid(destination + DIR_SE);
break;
case 6:
rv = IsTileNotSolid({ dx, dy + 1 }) && IsTileNotSolid({ dx - 1, dy });
case 6: // Stepping east
rv = IsTileNotSolid(destination + DIR_SW) && IsTileNotSolid(destination + DIR_NW);
break;
case 7:
rv = IsTileNotSolid({ dx, dy - 1 }) && IsTileNotSolid({ dx - 1, dy });
case 7: // Stepping south
rv = IsTileNotSolid(destination + DIR_NE) && IsTileNotSolid(destination + DIR_NW);
break;
case 8:
rv = IsTileNotSolid({ dx + 1, dy }) && IsTileNotSolid({ dx, dy - 1 });
case 8: // Stepping west
rv = IsTileNotSolid(destination + DIR_SE) && IsTileNotSolid(destination + DIR_NE);
break;
}
return rv;
@ -218,13 +213,13 @@ bool path_solid_pieces(PATHNODE *pPath, int dx, int dy)
*
* @return false if we ran out of preallocated nodes to use, else true
*/
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, int x, int y)
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, Point destination)
{
for (auto dir : PathDirs) {
Point tile = pPath->position + dir;
bool ok = posOk(tile);
if ((ok && path_solid_pieces(pPath, tile.x, tile.y)) || (!ok && tile == Point { x, y })) {
if (!path_parent_path(pPath, tile.x, tile.y, x, y))
if ((ok && path_solid_pieces(pPath->position, tile)) || (!ok && tile == destination)) {
if (!path_parent_path(pPath, tile, destination))
return false;
}
}
@ -237,13 +232,13 @@ bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, int
*
* @return true if step successfully added, false if we ran out of nodes to use
*/
bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
bool path_parent_path(PATHNODE *pPath, Point candidatePosition, Point destinationPosition)
{
int nextG = pPath->g + path_check_equal(pPath, dx, dy);
int nextG = pPath->g + path_check_equal(pPath->position, candidatePosition);
// 3 cases to consider
// case 1: (dx,dy) is already on the frontier
PATHNODE *dxdy = path_get_node1(dx, dy);
PATHNODE *dxdy = path_get_node1(candidatePosition);
if (dxdy != nullptr) {
int i;
for (i = 0; i < 8; i++) {
@ -252,7 +247,7 @@ bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
}
pPath->Child[i] = dxdy;
if (nextG < dxdy->g) {
if (path_solid_pieces(pPath, dx, dy)) {
if (path_solid_pieces(pPath->position, candidatePosition)) {
// we'll explore it later, just update
dxdy->Parent = pPath;
dxdy->g = nextG;
@ -261,7 +256,7 @@ bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
}
} else {
// case 2: (dx,dy) was already visited
dxdy = path_get_node2(dx, dy);
dxdy = path_get_node2(candidatePosition);
if (dxdy != nullptr) {
int i;
for (i = 0; i < 8; i++) {
@ -269,7 +264,7 @@ bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
break;
}
pPath->Child[i] = dxdy;
if (nextG < dxdy->g && path_solid_pieces(pPath, dx, dy)) {
if (nextG < dxdy->g && path_solid_pieces(pPath->position, candidatePosition)) {
// update the node
dxdy->Parent = pPath;
dxdy->g = nextG;
@ -284,9 +279,9 @@ bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
return false;
dxdy->Parent = pPath;
dxdy->g = nextG;
dxdy->h = path_get_h_cost(dx, dy, sx, sy);
dxdy->h = path_get_h_cost(candidatePosition, destinationPosition);
dxdy->f = nextG + dxdy->h;
dxdy->position = { dx, dy };
dxdy->position = candidatePosition;
// add it to the frontier
path_next_node(dxdy);
@ -302,13 +297,13 @@ bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
}
/**
* @brief return a node for (dx,dy) on the frontier, or NULL if not found
* @brief return a node for a position on the frontier, or NULL if not found
*/
PATHNODE *path_get_node1(int dx, int dy)
PATHNODE *path_get_node1(Point targetPosition)
{
PATHNODE *result = path_2_nodes->NextNode;
while (result != nullptr) {
if (result->position.x == dx && result->position.y == dy)
if (result->position == targetPosition)
return result;
result = result->NextNode;
}
@ -316,13 +311,13 @@ PATHNODE *path_get_node1(int dx, int dy)
}
/**
* @brief return a node for (dx,dy) if it was visited, or NULL if not found
* @brief return a node for a given position if it was visited, or NULL if not found
*/
PATHNODE *path_get_node2(int dx, int dy)
PATHNODE *path_get_node2(Point targetPosition)
{
PATHNODE *result = pnode_ptr->NextNode;
while (result != nullptr) {
if (result->position.x == dx && result->position.y == dy)
if (result->position == targetPosition)
return result;
result = result->NextNode;
}
@ -363,10 +358,10 @@ void path_set_coords(PATHNODE *pPath)
if (pathAct == nullptr)
break;
if (pathOld->g + path_check_equal(pathOld, pathAct->position.x, pathAct->position.y) < pathAct->g) {
if (path_solid_pieces(pathOld, pathAct->position.x, pathAct->position.y)) {
if (pathOld->g + path_check_equal(pathOld->position, pathAct->position) < pathAct->g) {
if (path_solid_pieces(pathOld->position, pathAct->position)) {
pathAct->Parent = pathOld;
pathAct->g = pathOld->g + path_check_equal(pathOld, pathAct->position.x, pathAct->position.y);
pathAct->g = pathOld->g + path_check_equal(pathOld->position, pathAct->position);
pathAct->f = pathAct->g + pathAct->h;
path_push_active_step(pathAct);
}

14
Source/path.h

@ -29,14 +29,14 @@ struct PATHNODE {
bool IsTileNotSolid(Point position);
bool IsTileSolid(Point position);
bool IsTileWalkable(Point position, bool ignoreDoors = false);
int FindPath(const std::function<bool(Point)> &posOk, int sx, int sy, int dx, int dy, int8_t path[MAX_PATH_LENGTH]);
int path_get_h_cost(int sx, int sy, int dx, int dy);
int FindPath(const std::function<bool(Point)> &posOk, Point start, Point destination, int8_t path[MAX_PATH_LENGTH]);
int path_get_h_cost(Point source, Point destination);
PATHNODE *GetNextPath();
bool path_solid_pieces(PATHNODE *pPath, int dx, int dy);
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, int x, int y);
bool path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy);
PATHNODE *path_get_node1(int dx, int dy);
PATHNODE *path_get_node2(int dx, int dy);
bool path_solid_pieces(Point position, Point destination);
bool path_get_path(const std::function<bool(Point)> &posOk, PATHNODE *pPath, Point destination);
bool path_parent_path(PATHNODE *pPath, Point candidatePosition, Point destinationPosition);
PATHNODE *path_get_node1(Point);
PATHNODE *path_get_node2(Point);
void path_next_node(PATHNODE *pPath);
void path_set_coords(PATHNODE *pPath);
void path_push_active_step(PATHNODE *pPath);

2
Source/player.cpp

@ -3538,7 +3538,7 @@ void MakePlrPath(int pnum, Point targetPosition, bool endspace)
return;
}
int path = FindPath([pnum](Point position) { return PosOkPlayer(pnum, position); }, player.position.future.x, player.position.future.y, targetPosition.x, targetPosition.y, player.walkpath);
int path = FindPath([pnum](Point position) { return PosOkPlayer(pnum, position); }, player.position.future, targetPosition, player.walkpath);
if (path == 0) {
return;
}

76
test/path_test.cpp

@ -12,32 +12,32 @@ TEST(PathTest, Heuristics)
{
constexpr Point source { 25, 32 };
Point destination = source;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 0) << "Wrong cost for travelling to the same tile";
EXPECT_EQ(path_get_h_cost(source, destination), 0) << "Wrong cost for travelling to the same tile";
destination = source + Direction::DIR_NE;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
destination = source + Direction::DIR_SE;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
destination = source + Direction::DIR_SW;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
destination = source + Direction::DIR_NW;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 2) << "Wrong cost for travelling to horizontal/vertical adjacent tile";
destination = source + Direction::DIR_N;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to diagonally adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to diagonally adjacent tile";
destination = source + Direction::DIR_E;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to diagonally adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to diagonally adjacent tile";
destination = source + Direction::DIR_S;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to diagonally adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to diagonally adjacent tile";
destination = source + Direction::DIR_W;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to diagonally adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to diagonally adjacent tile";
destination = source + Direction::DIR_SW + Direction::DIR_SE; // Effectively the same as DIR_S
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to diagonally adjacent tile";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to diagonally adjacent tile";
destination = source + Direction::DIR_NE + Direction::DIR_N;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 6) << "Wrong cost for travelling to a { 2, 1 } offset";
EXPECT_EQ(path_get_h_cost(source, destination), 6) << "Wrong cost for travelling to a { 2, 1 } offset";
destination = source + Direction::DIR_SE + Direction::DIR_SE;
EXPECT_EQ(path_get_h_cost(source.x, source.y, destination.x, destination.y), 4) << "Wrong cost for travelling to a { 2, 0 } offset";
EXPECT_EQ(path_get_h_cost(source, destination), 4) << "Wrong cost for travelling to a { 2, 0 } offset";
}
TEST(PathTest, Solid)
@ -58,55 +58,51 @@ TEST(PathTest, Solid)
TEST(PathTest, SolidPieces)
{
PATHNODE node1 { 0, 0, 0, { 0, 0 } };
PATHNODE node2 { 0, 0, 0, { 0, 1 } };
PATHNODE node3 { 0, 0, 0, { 1, 0 } };
PATHNODE node4 { 0, 0, 0, { 1, 1 } };
dPiece[0][0] = 0;
dPiece[0][1] = 0;
dPiece[1][0] = 0;
dPiece[1][1] = 0;
nSolidTable[0] = false;
EXPECT_TRUE(path_solid_pieces(&node1, 1, 1)) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces(&node4, 0, 0)) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces(&node3, 0, 1)) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces(&node2, 1, 0)) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "A step in open space is free of solid pieces";
EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "A step in open space is free of solid pieces";
nSolidTable[1] = true;
dPiece[1][0] = 1;
EXPECT_TRUE(path_solid_pieces(&node2, 1, 0)) << "Can path to a destination which is solid";
EXPECT_TRUE(path_solid_pieces(&node3, 0, 1)) << "Can path from a starting position which is solid";
EXPECT_TRUE(path_solid_pieces(&node2, 1, 1)) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces(&node3, 1, 1)) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces(&node1, 1, 0)) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces(&node4, 1, 0)) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_FALSE(path_solid_pieces(&node1, 1, 1)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces(&node4, 0, 0)) << "Can't cut a solid corner";
EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can path to a destination which is solid";
EXPECT_TRUE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can path from a starting position which is solid";
EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 1 })) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces({ 1, 0 }, { 1, 1 })) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces({ 0, 0 }, { 1, 0 })) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_TRUE(path_solid_pieces({ 1, 1 }, { 1, 0 })) << "Stepping in a cardinal direction ignores solid pieces";
EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't cut a solid corner";
dPiece[0][1] = 1;
EXPECT_FALSE(path_solid_pieces(&node1, 1, 1)) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces(&node4, 0, 0)) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't walk through the boundary between two corners";
dPiece[1][0] = 0;
EXPECT_FALSE(path_solid_pieces(&node1, 1, 1)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces(&node4, 0, 0)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't cut a solid corner";
dPiece[0][1] = 0;
dPiece[0][0] = 1;
EXPECT_FALSE(path_solid_pieces(&node3, 0, 1)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces(&node2, 1, 0)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't cut a solid corner";
dPiece[1][1] = 1;
EXPECT_FALSE(path_solid_pieces(&node3, 0, 1)) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces(&node2, 1, 0)) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't walk through the boundary between two corners";
EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't walk through the boundary between two corners";
dPiece[0][0] = 0;
EXPECT_FALSE(path_solid_pieces(&node3, 0, 1)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces(&node2, 1, 0)) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't cut a solid corner";
EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't cut a solid corner";
dPiece[1][1] = 0;
}
void CheckPath(Point startPosition, Point destinationPosition, std::vector<int8_t> expectedSteps)
{
static int8_t pathSteps[MAX_PATH_LENGTH];
auto pathLength = FindPath([](Point) { return true; }, startPosition.x, startPosition.y, destinationPosition.x, destinationPosition.y, pathSteps);
auto pathLength = FindPath([](Point) { return true; }, startPosition, destinationPosition, pathSteps);
EXPECT_EQ(pathLength, expectedSteps.size()) << "Wrong path length for a path from " << startPosition << " to " << destinationPosition;
// Die early if the wrong path length is returned as we don't want to read oob in expectedSteps

Loading…
Cancel
Save