From c6db3a75f756d790ede966c34adc3dbc793803d1 Mon Sep 17 00:00:00 2001 From: Kirill Petrashin Date: Wed, 15 Apr 2026 18:13:42 +0300 Subject: Try to implement costs, fail --- main.c | 28 +++++++++++++++++++++++----- map.c | 31 +++++++++++++++++++++++++++++++ map.h | 8 ++++++++ maps/cost_test | 11 +++++++++++ maps/cost_wall | 11 +++++++++++ 5 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 maps/cost_test create mode 100644 maps/cost_wall diff --git a/main.c b/main.c index f299d1f..93ce49f 100644 --- a/main.c +++ b/main.c @@ -15,8 +15,6 @@ #include "bmp.h" /* So, TODO for now: - - Allow maps to have costs - - Maybe make map editor the main thing - More messages - check ppq_insert() order - more info in anim()? @@ -29,6 +27,8 @@ - time - Comments */ +/* FIXME: Costs are broken */ + void sigint_handler(int sig) { (void)sig; /* We know it's a SIGINT */ endwin(); @@ -63,6 +63,7 @@ int main(int argc, char **argv) { Position start_pos, end_pos; size_t width, height; Map map = NULL; + size_t **cell_costs = NULL; size_t mwidth = 20; /* Maze width */ size_t mheight = 10; /* Maze height */ @@ -86,8 +87,6 @@ int main(int argc, char **argv) { * -b {filename} to just generate a bitmap, no interface * -4 for four directions * -8 for eight directions */ - /* TODO: Argument to choose the algorithm */ - /* TODO: Argument to set seed */ int opt; while ((opt = getopt(argc, argv, ":adm:f:b:48")) != -1) { switch (opt) { @@ -277,7 +276,26 @@ int main(int argc, char **argv) { path_free(path, height); path = path_func(dirs, map, NULL, width, height, start_pos, end_pos, visited, anim); } - break; + break; + + case 'c': /* Load a cost file */ + curs_set(2); /* Show the cursor */ + echo(); /* Echo characters */ + + set_message(FILENAME_PROMPT); + print_message(height); + char cost_filename[FILENAME_BUF_SIZE] = "\0"; + mvgetnstr(height + map_offset_y + 1, map_offset_x - 2 + sizeof(FILENAME_PROMPT), cost_filename, FILENAME_BUF_SIZE - 1); + + cell_costs = file_plaintext_costs(cost_filename, width, height); + path_free(path, height); + path = path_func(dirs, map, cell_costs, width, height, start_pos, end_pos, visited, anim); + /* TODO: figure out how to print actual costs */ + cost_free(cell_costs, height); + + curs_set(0); /* Hide the cursor */ + noecho(); /* Don't echo characters */ + break; case 'e': is_maze = 0; diff --git a/map.c b/map.c index 22b88ec..a0d0f23 100644 --- a/map.c +++ b/map.c @@ -248,6 +248,35 @@ Map file_plaintext_map(char *filename, size_t *width, size_t *height, Position * return map; } +size_t **file_plaintext_costs(char *filename, size_t width, size_t height) { + FILE *file = fopen(filename, "r"); + if (file == NULL) { + error("Failed to open file %s\n", filename); + } + + size_t fw, fh; /* file width and height */ + if (fscanf(file, "%zux%zu\n", &fw, &fh) != 2) { + error("Failed reading size of cost file %s\n", filename); + } + if (fw != width || fh != height) { + set_message("Wrong size (%zux%zu vs %zux%zu) in cost file %s\n", fw, fh, width, height, filename); + print_message(height); + return NULL; + } + + size_t **costs = cost_new(width, height); + if (costs == NULL) error("Failed to create a new costs array\n"); + + for (size_t row = 0; row < fh; row++) { + for (size_t col = 0; col < fw; col++) { + if (fscanf(file, "%zu", &costs[row][col]) != 1) error("Failed reading cost on x = %zu, y = %zu in cost file %s\n", col, row, filename); + } + fgetc(file); /* the newline */ + } + + return costs; +} + void map_to_file_plaintext(char *filename, Map map, size_t width, size_t height, Position start, Position end) { FILE *file = fopen(filename, "w"); if (file == NULL) { @@ -606,6 +635,7 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi for (size_t i = map_offset_x; i < *width*2 + map_offset_x; i++) { mvaddch(event.y, i, '='); } + mvprintw(event.y, map_offset_x, "%u", event.y - map_offset_y); }; size_t new_height = event.y - map_offset_y; @@ -653,6 +683,7 @@ void map_editor(Map *map, size_t *width, size_t *height, Position *start, Positi mvaddch(i, new_width * 2 + map_offset_x, '|'); mvaddch(i, new_width * 2 + map_offset_x + 1, '|'); } + mvprintw(map_offset_y, new_width*2 + map_offset_x, "%u", (event.x - map_offset_x) / 2); }; new_width = (event.x - map_offset_x) / 2; diff --git a/map.h b/map.h index 978db21..93672b7 100644 --- a/map.h +++ b/map.h @@ -48,6 +48,14 @@ Map rbt_maze_map(size_t width, size_t height, unsigned int seed); Map file_plaintext_map(char *filename, size_t *width, size_t *height, Position *start_pos, Position *end_pos); /* The reverse of above */ void map_to_file_plaintext(char *filename, Map map, size_t width, size_t height, Position start, Position end); +/* Loads integer costs from a file. Sizes have to match. + * File format: + * 5x4 + * 10 20 30 40 5 + * 20 49 5 3 2 + * 1 2 4 5 2 + * 5 1 95 2 5 */ +size_t **file_plaintext_costs(char *filename, size_t width, size_t height); /* Draw the map. Bet you didn't expect that. * path could be NULL to draw a map with no path. So can cursor, frontier and visited */ diff --git a/maps/cost_test b/maps/cost_test new file mode 100644 index 0000000..481f1c1 --- /dev/null +++ b/maps/cost_test @@ -0,0 +1,11 @@ +10x10 +1 2 3 4 5 6 7 8 9 0 +2 3 4 5 6 7 8 9 0 1 +3 4 5 6 7 8 9 0 1 2 +4 5 6 7 8 9 0 1 2 3 +5 6 7 8 9 0 1 2 3 4 +6 7 8 9 0 1 2 3 4 5 +7 8 9 0 1 2 3 4 5 6 +8 9 0 1 2 3 4 5 6 7 +9 0 1 2 3 4 5 6 7 8 +0 1 2 3 4 5 6 7 8 9 diff --git a/maps/cost_wall b/maps/cost_wall new file mode 100644 index 0000000..2f3c089 --- /dev/null +++ b/maps/cost_wall @@ -0,0 +1,11 @@ +10x10 +0 0 0 0 0 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 +0 0 0 0 9 0 0 0 0 0 -- cgit v1.2.3