static void fillDeadEnd(Maze m, size_t x, size_t y) { int i; *get(m, x, y) = EMPTY; for (i = -1; i <= 1; i += 2) { if (deadEnd(m, x + i, y )) fillDeadEnd(m, x + i, y ); if (deadEnd(m, x , y + i)) fillDeadEnd(m, x , y + i); } }
void fillDeadEnd(std::vector<std::vector<int> >* walls, int size, int start, int end, int index, int recurLevel = 0, int maxRecurLevel = -1) { std::vector<int>* cell = &(*walls)[index]; if (index != start && index != end && isDeadEnd(*cell)) { int free = getFreeDirection(*cell); int next = getRelative(index, free, size); (*cell)[free] = 1; (*walls)[next][getOppositeDirection(free)] = 1; if (maxRecurLevel == -1 || recurLevel < maxRecurLevel) { fillDeadEnd(walls, size, start, end, next, recurLevel + 1, maxRecurLevel); } } }
void solve(FILE *fp) { Maze m = init(fp); size_t i, j, width = m.width, height = m.height; for (j = 0; j < height; ++j) { for (i = 0; i < width; ++i) { if (deadEnd(m, i, j)) { fillDeadEnd(m, i, j); } } } print(stdout, m); }
std::vector<int> MazeSolver::SolveMaze3(std::vector<std::vector<int> > walls) { /* Hybrid of the first and second solver, only one level of dead ends are filled */ int mazeSize = std::sqrt(walls.size()); int mazeStart = 0; int mazeEnd = mazeSize * mazeSize - 1; std::vector<int> deadEnds; for (int i = mazeStart + 1; i < mazeEnd - 1; i++) { fillDeadEnd(&walls, mazeSize, mazeStart, mazeEnd, i, 0, 1); } point pos(mazeSize - 1, mazeSize - 1); std::stack<maze_point> path; while (pos.x != 0 || pos.y != 0) { maze_point currentCell(pos); currentCell.setWalls(walls[currentCell.position.getIndex(mazeSize)]); if (!path.empty()) { currentCell.setExplored(currentCell.position.getDirection(path.top().position)); } int direction = currentCell.getFirstAvailablePath(); if (direction == -1) { while (!path.top().hasOneFreePath()) { path.pop(); } currentCell = path.top(); path.pop(); direction = currentCell.getFirstAvailablePath(); } currentCell.setExplored(direction); path.push(currentCell); pos = currentCell.position.getRelative(direction); } path.push(maze_point(pos)); return toIndexPath(path, mazeSize); }
void fillDeadEnds(std::vector<std::vector<int> >* walls, int size, int start, int end) { for (int i = start + 1; i < end - 1; i++) { fillDeadEnd(walls, size, start, end, i); } }