| ... | ... |
@@ -61,28 +61,34 @@ Maze hunt_and_kill(int w, int h, unsigned seed, C callback = [](Maze &){})
|
| 61 | 61 |
auto done = false; |
| 62 | 62 |
while (!done) |
| 63 | 63 |
{
|
| 64 |
+ #define FOR_NEIGHBOR(...) \ |
|
| 65 |
+ for (auto i = 0; i < 4; ++i) \ |
|
| 66 |
+ { \
|
|
| 67 |
+ auto ni = i%2*4-2; /* -2, +2, -2, +2 */ \ |
|
| 68 |
+ auto nx = ni* (i/2); /* 0, 0, -2, +2 */ \ |
|
| 69 |
+ auto ny = ni*!(i/2); /* -2, +2, 0, 0 */ \ |
|
| 70 |
+ __VA_ARGS__ \ |
|
| 71 |
+ } |
|
| 64 | 72 |
// Call callback. |
| 65 | 73 |
callback(maze); |
| 66 | 74 |
// Find number of neighbors. |
| 67 | 75 |
auto n = 0; |
| 68 |
- for (auto ny = -2; ny <= 2; ny += 2) |
|
| 69 |
- for (auto nx = -2; nx <= 2; nx += 2) |
|
| 70 |
- if (!nx != !ny) |
|
| 76 |
+ FOR_NEIGHBOR( |
|
| 71 | 77 |
if (maze(cx+nx, cy+ny) == Maze::WALL) |
| 72 | 78 |
++n; |
| 79 |
+ ) |
|
| 73 | 80 |
// If we have neighbors, carve path to random one. |
| 74 | 81 |
if (n != 0) |
| 75 | 82 |
{
|
| 76 | 83 |
n = std::rand() % n; |
| 77 |
- for (auto ny = -2; ny <= 2; ny += 2) |
|
| 78 |
- for (auto nx = -2; nx <= 2; nx += 2) |
|
| 79 |
- if (!nx != !ny) |
|
| 84 |
+ FOR_NEIGHBOR( |
|
| 80 | 85 |
if (maze(cx+nx, cy+ny) == Maze::WALL && n-- == 0) |
| 81 | 86 |
{
|
| 82 | 87 |
maze(cx+nx/2, cy+ny/2) = maze(cx+nx, cy+ny) = Maze::PATH; |
| 83 | 88 |
cx = cx+nx; |
| 84 | 89 |
cy = cy+ny; |
| 85 | 90 |
} |
| 91 |
+ ) |
|
| 86 | 92 |
continue; |
| 87 | 93 |
} |
| 88 | 94 |
// No neighbors, done unless there's an uncarved cell to restart at. |
| ... | ... |
@@ -90,17 +96,17 @@ Maze hunt_and_kill(int w, int h, unsigned seed, C callback = [](Maze &){})
|
| 90 | 96 |
for (; ry < h; ry += 2, rx = 1) |
| 91 | 97 |
for (; rx < w; rx += 2) |
| 92 | 98 |
if (maze(rx, ry) == Maze::WALL) |
| 93 |
- for (auto ny = -2; ny <= 2; ny += 2) |
|
| 94 |
- for (auto nx = -2; nx <= 2; nx += 2) |
|
| 95 |
- if (!nx != !ny) |
|
| 99 |
+ FOR_NEIGHBOR( |
|
| 96 | 100 |
if (maze(rx+nx, ry+ny) == Maze::PATH) |
| 97 | 101 |
{
|
| 98 | 102 |
cx = rx+nx; |
| 99 | 103 |
cy = ry+ny; |
| 100 | 104 |
return false; |
| 101 | 105 |
} |
| 106 |
+ ) |
|
| 102 | 107 |
return true; |
| 103 | 108 |
}(); |
| 109 |
+ #undef FOR_NEIGHBOR |
|
| 104 | 110 |
} |
| 105 | 111 |
// Exit. |
| 106 | 112 |
w -= (w + 1) % 2; |