From acd148b70b84ebe275e4b5631a9e5cc74025a0fc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 15 Dec 2019 12:45:45 +0100 Subject: [PATCH] add maze generator --- Algorithm/Maze/MazeGenerator.php | 158 +++++++++++++++++++++ tests/Algorithm/Maze/MazeGeneratorTest.php | 101 +++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 Algorithm/Maze/MazeGenerator.php create mode 100644 tests/Algorithm/Maze/MazeGeneratorTest.php diff --git a/Algorithm/Maze/MazeGenerator.php b/Algorithm/Maze/MazeGenerator.php new file mode 100644 index 000000000..84a846a2a --- /dev/null +++ b/Algorithm/Maze/MazeGenerator.php @@ -0,0 +1,158 @@ + 0 && $i < $height + 1 && $j > 0 && ($i !== $pos[0] + 1 || $j != $pos[1] + 1); + } + } + + while (0 < $n) { + $potential = [ + [$pos[0] + 1, $pos[1]], + [$pos[0], $pos[1] + 1], + [$pos[0] - 1, $pos[1]], + [$pos[0], $pos[1] - 1], + ]; + + $neighbors = []; + + for ($i = 0; $i < 4; ++$i) { + if ($unvisited[$potential[$i][0] + 1][$potential[$i][1] + 1] ?? false) { + $neighbors[] = $potential[$i]; + } + } + + if (!empty($neighbors)) { + --$n; + + $next = $neighbors[\mt_rand(0, \count($neighbors) - 1)]; + $unvisited[$next[0] + 1][$next[1] + 1] = false; + + if ($next[0] === $pos[0]) { + $horizontal[$next[0]][($next[1] + $pos[1] - 1) / 2] = true; + } else { + $vertical[($next[0] + $pos[0] - 1) / 2][$next[1]] = true; + } + + $path[] = $next; + $pos = $next; + } else { + $pos = \array_pop($path); + + if ($pos === null) { + $n = 0; + } + } + } + + $maze = []; + for ($i = 0; $i < $height * 2 + 1; ++$i) { + $line = []; + + if ($i % 2 === 0) { + for ($j = 0; $j < $width * 4 + 1; ++$j) { + if ($j % 4 === 0) { + $line[$j] = '+'; + } else { + $line[$j] = $i > 0 && ($vertical[$i / 2 - 1][(int) \floor($j / 4)] ?? false) ? ' ' : '-'; + } + } + } else { + for ($j = 0; $j < $width * 4 + 1; ++$j) { + if ($j % 4 === 0) { + $line[$j] = $j > 0 && ($horizontal[($i - 1) / 2][$j / 4 - 1] ?? false) ? ' ' : '|'; + } else { + $line[$j] = ' '; + } + } + } + + if ($i === 0) { + $line[1] = $line[2] = $line[3] = ' '; + } + + if ($height * 2 - 1 === $i) { + $line[4 * $width] = ' '; + } + + $maze[] = $line; + } + + return $maze; + } + + /** + * Render a maze + * + * @param array $maze Maze to render + * + * @return void + * + * @since 1.0.0 + */ + public static function render(array $maze) : void + { + foreach ($maze as $y => $row) { + foreach ($row as $x => $column) { + echo $column; + } + + echo "\n"; + } + } +} diff --git a/tests/Algorithm/Maze/MazeGeneratorTest.php b/tests/Algorithm/Maze/MazeGeneratorTest.php new file mode 100644 index 000000000..0ecc58b93 --- /dev/null +++ b/tests/Algorithm/Maze/MazeGeneratorTest.php @@ -0,0 +1,101 @@ +