diff options
| author | Kirill Petrashin <kirill8201@yandex.ru> | 2026-04-14 22:41:56 +0300 |
|---|---|---|
| committer | Kirill Petrashin <kirill8201@yandex.ru> | 2026-04-14 22:41:56 +0300 |
| commit | c9ac361e1282bfaa895a1456222bca2d86253a96 (patch) | |
| tree | 4c2b5a90ad35d25b21224af80a519c9ae353b983 /map.c | |
| parent | 768509d6bb91269abf1ee1d93c32d236b146e98a (diff) | |
| download | astar-c9ac361e1282bfaa895a1456222bca2d86253a96.tar.xz | |
Implement live pathfinding in map editor
Diffstat (limited to 'map.c')
| -rw-r--r-- | map.c | 84 |
1 files changed, 60 insertions, 24 deletions
@@ -436,8 +436,13 @@ void print_map_out(Map map, size_t width, size_t height) { } } -void map_editor(Map *map, size_t *width, size_t *height, Position *start, Position *goal) { - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); +void map_editor(Map *map, size_t *width, size_t *height, Position *start, Position *goal, int dirs) { + char should_pathfind = 0; + + char **visited = NULL; + Path path = NULL; + + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); set_message("You've entered the map editor. 'q' to quit"); print_message(*height); @@ -451,7 +456,8 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi while (1) { int ch = getch(); - if (ch == 'q') {clear_message(); break; } + /* FIXME: move this to the switch statement */ + if (ch == 'q') { clear_message(); visited_free(visited, *height); path_free(path, *height); break; } /* Handle keyboard keys */ switch (ch) { case 'h': map_offset_x += 2; break; @@ -466,6 +472,19 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi case 'z': clear(); map_offset_x = 2; map_offset_y = 1; break; /* Move to top left corner */ case 'x': clear(); map_offset_x = - *width * 2 + COLS - 2; map_offset_y = - *height + LINES - 2; break; /* Move to bottom right corner */ + case 'a': + should_pathfind = !should_pathfind; + if (should_pathfind) { + set_message("Will pathfind"); + visited = visited_new(*width, *height); + path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + } else { + set_message("Won't pathfind"); + visited_free(visited, *height); visited = NULL; + path_free(path, *height); path = NULL; + } + print_message(*height); + break; case 'g': switch (getch()) { @@ -481,6 +500,14 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi break; } break; + + case 'd': + if (path_func == astar_path) { set_message("Dijkstra"); path_func = &dijkstra_path; } + else { set_message("A*"); path_func = &astar_path; }; + path_free(path, *height); + if (should_pathfind) path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + break; + case 's': curs_set(2); /* Show the cursor */ echo(); /* Echo characters */ @@ -516,7 +543,8 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi if (row < *height && col < *width && (*map)[row][col] != WALL && (col != goal->x || row != goal->y)) { start->x = col; start->y = row; - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + if (should_pathfind) path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } } } else if (goal->x == col && goal->y == row) { /* Move the goal */ @@ -526,7 +554,8 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi if (row < *height && col < *width && (*map)[row][col] != WALL && (col != start->x || row != start->y)) { goal->x = col; goal->y = row; - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + if (should_pathfind) path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } } } else if (row == *height) { /* Resize vertically */ @@ -536,16 +565,12 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi } /* Wait for BUTTON1_RELEASED */ - size_t old_event_y = event.y; while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) { if (event.y <= map_offset_y) continue; - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); for (size_t i = map_offset_x; i < *width*2 + map_offset_x; i++) { - if (old_event_y > *height + map_offset_y + 1) - mvaddch(old_event_y, i, ' '); mvaddch(event.y, i, '='); } - old_event_y = event.y; }; size_t new_height = event.y - map_offset_y; @@ -553,12 +578,16 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi Map new_map = empty_map(*width, new_height); map_copy(*map, *width, *height, new_map, *width, new_height); + map_free(*map, *height); + visited_free(visited, *height); + path_free(path, *height); *height = new_height; *map = new_map; /* Make sure start and goal aren't outside of the map */ + /* FIXME: they can get stuck in walls */ if (start->y >= *height) { start->y = *height - 1; } @@ -566,8 +595,11 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi goal->y = *height - 1; } - clear(); - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + if (should_pathfind) { + visited = visited_new(*width, *height); + path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + } + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } else if (col == *width) { /* Resize horizontally */ size_t new_width = (event.x - map_offset_x) / 2; @@ -578,20 +610,14 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi } /* Wait for BUTTON1_RELEASED */ - size_t old_new_width = (event.x - map_offset_x) / 2; /* Used to erase the old line */ while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) { size_t new_width = (event.x - map_offset_x) / 2; if (event.x <= map_offset_x || new_width == 0) continue; - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); for (size_t i = map_offset_y; i < *height + map_offset_y; i++) { - if (old_new_width > *width + map_offset_x/2) { - mvaddch(i, old_new_width * 2 + map_offset_x, ' '); - mvaddch(i, old_new_width * 2 + map_offset_x + 1, ' '); - } mvaddch(i, new_width * 2 + map_offset_x, '|'); mvaddch(i, new_width * 2 + map_offset_x + 1, '|'); } - old_new_width = new_width; }; new_width = (event.x - map_offset_x) / 2; @@ -599,7 +625,10 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi Map new_map = empty_map(new_width, *height); map_copy(*map, *width, *height, new_map, new_width, *height); + map_free(*map, *height); + visited_free(visited, *height); + path_free(path, *height); *width = new_width; *map = new_map; @@ -612,8 +641,11 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi goal->x = *width - 1; } - clear(); - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + if (should_pathfind) { + visited = visited_new(*width, *height); + path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + } + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } else { /* Start drawing */ m1down = 1; if (row < *height && col < *width) { @@ -632,13 +664,17 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi col = (event.x - map_offset_x) / 2; if (row < *height && col < *width) { (*map)[row][col] = cur; - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + path_free(path, *height); + if (should_pathfind) { + path = path_func(dirs, *map, *width, *height, *start, *goal, visited, 0); + } + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } } } } else { /* Only update the map if not a mouse event */ - - draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + /* FIXME: I don't like in how many places we call draw_map(), maybe there's a better way? */ + draw_map(*map, *width, *height, *start, *goal, NULL, path, visited, NULL); } } |
