#include #include #include #include #include "path.h" #include "map.h" #include "structs.h" #include "priority_queue.h" int anim(Map map, size_t width, size_t height, Position start, Position end, Position *cur, char visited[height][width], PositionPQ *frontier) { draw_map(map, width, height, 0, 0, start, end, cur, NULL, visited, frontier); mvprintw(height+2, 0, "cur: %zu %zu", cur->x, cur->y); /* TODO: input, automatic mode */ switch (getch()) { case 'q': return -1; } return 0; } /* BLOODY FUCK IT WORKS */ Path breadth_first_search_path_4dir(Map map, size_t width, size_t height, Position start, Position end, char visited[height][width], char should_anim) { Path path = malloc(sizeof(PathNode)*height); if (path == NULL) return NULL; for (size_t row = 0; row < height; row++) { path[row] = malloc(sizeof(PathNode) * width); if (path[row] == NULL) return NULL; memset(path[row], 0, width * sizeof(PathNode)); } PositionPQ *frontier = ppq_new(start, 0); memset(visited, 0, height * width * sizeof(char)); while (frontier != NULL) { Position cur = ppq_pop(&frontier); visited[cur.y][cur.x] = 1; if (cur.x == end.x && cur.y == end.y) { return path; /* Found path */ } Position na[4]; unsigned int nc = neighbours_4dir(na, cur, width, height, visited); for (unsigned int i = 0; i < nc; i++) { /* The Russian constitution doesn't allow walking on walls */ if (map[na[i].y][na[i].x] == WALL) continue; ppq_insert(&frontier, na[i], 0); path[na[i].y][na[i].x].parent = cur; } if (should_anim) { if (anim(map, width, height, start, end, &cur, visited, frontier) == -1) return NULL; } } return NULL; } Path breadth_first_search_path_8dir(Map map, size_t width, size_t height, Position start, Position end, char visited[height][width], char should_anim) { Path path = malloc(sizeof(PathNode)*height); if (path == NULL) return NULL; for (size_t row = 0; row < height; row++) { path[row] = malloc(sizeof(PathNode) * width); if (path[row] == NULL) return NULL; memset(path[row], 0, width * sizeof(PathNode)); } PositionPQ *frontier = ppq_new(start, 0); memset(visited, 0, height * width * sizeof(char)); while (frontier != NULL) { Position cur = ppq_pop(&frontier); visited[cur.y][cur.x] = 1; if (cur.x == end.x && cur.y == end.y) { return path; /* Found path */ } Position na[8]; unsigned int nc = neighbours_8dir(na, cur, width, height, visited); for (unsigned int i = 0; i < nc; i++) { /* The Russian constitution doesn't allow walking on walls */ if (map[na[i].y][na[i].x] == WALL) continue; if (ppq_insert(&frontier, na[i], 0) != 3) { path[na[i].y][na[i].x].parent = cur; } } if (should_anim) { if (anim(map, width, height, start, end, &cur, visited, frontier) == -1) return NULL; } } return NULL; } /* FIXME: Rewrite this shit */ Path astar_path_4dir(Map map, size_t width, size_t height, Position start, Position end) { Path path = malloc(sizeof(PathNode)*height); if (path == NULL) return NULL; for (size_t row = 0; row < height; row++) { path[row] = malloc(sizeof(PathNode) * width); if (path[row] == NULL) return NULL; memset(path[row], 0, width * sizeof(PathNode)); } size_t costs[height][width]; memset(costs, 0xFF, height*width*sizeof(size_t)); (void)start, (void)end, (void)map; return NULL; } /* FIXME: I feel like there's a better way to do this, but not sure */ size_t manhattan_distance(Position a, Position b) { size_t d = 0; if (a.x > b.x) { d += a.x - b.x; } else { d += b.x - a.x; } if (a.y > b.y) { d += a.y - b.y; } else { d += b.y - a.y; } return d; }