Skip to content

Instantly share code, notes, and snippets.

@codekitchen
Created February 13, 2017 01:06
Show Gist options
  • Save codekitchen/b0ce51a6eb3245e0d21e78933b2d3334 to your computer and use it in GitHub Desktop.
Save codekitchen/b0ce51a6eb3245e0d21e78933b2d3334 to your computer and use it in GitHub Desktop.
optimized flood fill algorithm for random puzzle generation
class PuzzleGenerator {
// ... other stuff ...
class FloodFillRange {
public int startX, endX, Y;
}
// Does a flood fill of the board starting at an arbitrary floor tile,
// and then verifies that the whole board was filled.
// If not, then there's floor that isn't reachable from some other floor.
bool Reachable() {
bool[,] visited = new bool[size.y, size.x];
var q = new Queue<FloodFillRange>();
// Fill one horizontal line, starting at the given point,
// and stopping when we hit a wall (or the edge of the board).
System.Action<int, int> lineFill = (int x, int y) => {
int lx, rx;
// go left until stopped, marking as we go
for (lx = x; lx >= 0; --lx) {
if (board[y, lx].tile != BLANK)
break;
visited[y, lx] = true;
}
// go right until stopped, marking as we go
for (rx = x + 1; rx < size.x; ++rx) {
if (board[y, rx].tile != BLANK)
break;
visited[y, rx] = true;
}
// contract 1 from each side to get back to the last tile we visited
q.Enqueue(new FloodFillRange { startX = lx + 1, endX = rx - 1, Y = y });
};
// find start pos
foreach (var pos in eachPosition()) {
if (board[pos.y, pos.x].tile == BLANK) {
// prime the queue starting at this position
lineFill(pos.x, pos.y);
break;
}
}
while (q.Count > 0) {
var range = q.Dequeue();
for (int x = range.startX; x <= range.endX; ++x) {
int y = range.Y - 1;
if (y >= 0 && !visited[y, x] && board[y, x].tile == BLANK)
lineFill(x, y);
y = range.Y + 1;
if (y < size.y && !visited[y, x] && board[y, x].tile == BLANK)
lineFill(x, y);
}
}
// look for any still-blank squares
foreach (var pos in eachPosition()) {
if (board[pos.y, pos.x].tile == BLANK && !visited[pos.y, pos.x])
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment