#include "dijkstra.h" #include static int passable(uint8_t t) { return t == T_FLOOR || t == T_CORRIDOR || t == T_DOOR || t == T_BRIDGE || t == T_STAIRS_UP || t == T_STAIRS_DOWN; } void bfs_from(grid_t g, int sx, int sy, dist_map_t dist, int extra_passable_x, int extra_passable_y) { for (int y = 0; y < DROWS; y++) for (int x = 0; x < DCOLS; x++) dist[y][x] = DIST_UNREACHABLE; if (!grid_in_bounds(sx, sy)) return; static const int dx4[4] = {1, -1, 0, 0}; static const int dy4[4] = {0, 0, 1, -1}; int qx[DCOLS * DROWS]; int qy[DCOLS * DROWS]; int head = 0, tail = 0; dist[sy][sx] = 0; qx[tail] = sx; qy[tail] = sy; tail++; while (head < tail) { int cx = qx[head], cy = qy[head]; head++; int16_t d = dist[cy][cx]; for (int i = 0; i < 4; i++) { int nx = cx + dx4[i], ny = cy + dy4[i]; if (!grid_in_bounds(nx, ny)) continue; int is_extra = (nx == extra_passable_x && ny == extra_passable_y); if (!is_extra && !passable(g[ny][nx].terrain)) continue; if (dist[ny][nx] <= d + 1) continue; dist[ny][nx] = d + 1; qx[tail] = nx; qy[tail] = ny; tail++; } } } int is_connected(grid_t g, int *out_unreached) { int sx = -1, sy = -1, total = 0; for (int y = 0; y < DROWS; y++) { for (int x = 0; x < DCOLS; x++) { if (passable(g[y][x].terrain)) { if (sx < 0) { sx = x; sy = y; } total++; } } } if (total == 0) { if (out_unreached) *out_unreached = 0; return 1; } static dist_map_t dist; bfs_from(g, sx, sy, dist, -1, -1); int reached = 0; for (int y = 0; y < DROWS; y++) for (int x = 0; x < DCOLS; x++) if (passable(g[y][x].terrain) && dist[y][x] != DIST_UNREACHABLE) reached++; if (out_unreached) *out_unreached = total - reached; return reached == total; }