From 04d6b474f928775ea0019928fdfbf08ecaae0997 Mon Sep 17 00:00:00 2001 From: Kirill Petrashin Date: Sat, 4 Apr 2026 15:41:19 +0300 Subject: Poorly implement the map editor --- main.c | 12 +++++++ map.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ map.h | 4 +++ 3 files changed, 139 insertions(+) diff --git a/main.c b/main.c index 8f2861f..fa2207b 100644 --- a/main.c +++ b/main.c @@ -51,6 +51,7 @@ void init_ncurses(void) { cbreak(); /* Process input one char at a time */ curs_set(0); /* Hide the cursor */ noecho(); /* Don't echo characters */ + keypad(stdscr, TRUE); initialize_colors(); } @@ -157,6 +158,7 @@ int main(int argc, char **argv) { case 'i': if(is_maze) { switch (c) { + /* TODO: handle if it's zero */ case 'y': mwidth -= 1; break; case 'o': mwidth += 1; break; case 'u': mheight += 1; break; @@ -190,6 +192,16 @@ int main(int argc, char **argv) { path = path_func(dirs, map, width, height, start_pos, end_pos, visited, anim); } break; + case 'e': + is_maze = 0; + visited_free(visited, height); + path_free(path, height); + + map_editor(&map, &width, &height, &start_pos, &end_pos); + + visited = visited_new(width, height); + path = path_func(dirs, map, width, height, start_pos, end_pos, visited, anim); + break; case 'q': map_free(map, height); path_free(path, height); endwin(); return 0; } } diff --git a/map.c b/map.c index 817f43c..c46c7db 100644 --- a/map.c +++ b/map.c @@ -10,6 +10,8 @@ #include "path.h" #include "priority_queue.h" +/* TODO: function to print a message maybe */ + int map_offset_x = 2; int map_offset_y = 1; @@ -215,6 +217,8 @@ Map file_plaintext_map(char *filename, size_t *width, size_t *height, Position * /* TODO: draw the start and goal with no background, allowing us to see the frontier/path/whatever's underneath. I think attr_get() will be useful */ /* TODO: only draw a portion of the map (for bigger ones) */ /* TODO: draw arrow for visited too */ +/* FIXME: clean up better maybe idk. There's a bug where parts of path may not be rendered if goal slightly above start in an empty area */ +/* FIXME: yeah there are plenty of bugs. the path just doesn't get rendered correctrly at times, even if it's calculated just fine. AND IT's SPECIFICALLY AFTER map_editor() WHAT IN THE ACTUAL FUCK AAAAAAAAAAAAAAAAAAAAAAAAAAAAA*/ void draw_map(Map map, size_t width, size_t height, Position start, Position goal, Position *cursor, Path path, char **visited, PositionPQ *frontier) { /* I think it flickers less when we do that */ wnoutrefresh(stdscr); @@ -391,3 +395,122 @@ 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); + mvprintw(*height + map_offset_y + 1, map_offset_x - 2, "You've entered the map editor. 'q' to quit"); + + MEVENT event; + mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL); + mouseinterval(0); + printf("\033[?1003h\n"); /* Makes the terminal report mouse movements */ + + char m1down = 0; + MapTile cur = EMPTY; + while (1) { + int ch = getch(); + + if (ch == 'q') break; + switch (ch) { + case 'h': map_offset_x += 2; break; + case 'l': map_offset_x -= 2; break; + case 'j': map_offset_y -= 1; break; + case 'k': map_offset_y += 1; break; + } + draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + + if (ch == KEY_MOUSE) { + if (getmouse(&event) == OK) { + if (event.bstate & BUTTON1_PRESSED) { + /* Translate event coordinates into map coordinates */ + size_t row = event.y - map_offset_y, + col = (event.x - map_offset_x) / 2; + + if (start->x == col && start->y == row) { /* Move the start */ + while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) { + row = event.y - map_offset_y; + col = (event.x - map_offset_x) / 2; + 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); + } + } + } else if (goal->x == col && goal->y == row) { /* Move the goal */ + while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) { + row = event.y - map_offset_y; + col = (event.x - map_offset_x) / 2; + 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); + } + } + } else if (row == *height) { /* Resize vertically */ + while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) {/* TODO: draw a line */}; + size_t new_height = event.y - map_offset_y; + if (event.y <= map_offset_y) continue; + Map new_map = empty_map(*width, new_height); + map_copy(*map, *width, *height, new_map, *width, new_height); + map_free(*map, *height); + *height = new_height; + *map = new_map; + if (start->y >= *height) { + start->y = *height - 1; + } + if (goal->y >= *height) { + goal->y = *height - 1; + } + clear(); + draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + } else if (col == *width) { /* Resize horizontally */ + while ((ch = getch()) == KEY_MOUSE && getmouse(&event) == OK && !(event.bstate & BUTTON1_RELEASED)) {/* TODO: draw a line */}; + size_t new_width = (event.x - map_offset_x) / 2; + if (event.x <= map_offset_x) continue; + Map new_map = empty_map(new_width, *height); + map_copy(*map, *width, *height, new_map, new_width, *height); + map_free(*map, *height); + *width = new_width; + *map = new_map; + if (start->x >= *width) { + start->x = *width - 1; + } + if (goal->x >= *width) { + goal->x = *width - 1; + } + clear(); + draw_map(*map, *width, *height, *start, *goal, NULL, NULL, NULL, NULL); + } else { /* Draw */ + m1down = 1; + if (row < *height && col < *width) { + if ((*map)[row][col] == WALL) + cur = EMPTY; + else + cur = WALL; + } + } + } else if (event.bstate & BUTTON1_RELEASED) { + m1down = 0; + } + /* Draw */ + if (m1down) { + size_t row = event.y - map_offset_y, + 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); + } + } + } + } + } + + printf("\033[?1003l\n"); /* Makes the terminal NOT report mouse movements */ +} + +void map_copy(Map src, size_t src_w, size_t src_h, Map dest, size_t dest_w, size_t dest_h) { + for (size_t row = 0; row < src_h && row < dest_h; row++) { + for (size_t col = 0; col < src_w && col < dest_w; col++) { + dest[row][col] = src[row][col]; + } + } +} diff --git a/map.h b/map.h index eb8ea9b..ecebbb9 100644 --- a/map.h +++ b/map.h @@ -51,4 +51,8 @@ void map_free(Map map, size_t height); 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); + +void map_copy(Map src, size_t src_w, size_t src_h, Map dest, size_t dest_w, size_t dest_h); + #endif /*MAP_H_ */ -- cgit v1.2.3