diff options
author | Jacob Janzen <jacob.a.s.janzen@gmail.com> | 2024-02-12 12:51:08 -0600 |
---|---|---|
committer | Jacob Janzen <jacob.a.s.janzen@gmail.com> | 2024-02-12 12:51:08 -0600 |
commit | f534c8d2c4cd8c8692cd7d831afb3041cc584c2b (patch) | |
tree | 49687d4df101f6f1c6f3688bcca02eac7021d232 | |
parent | 8e873b2f45814508cbc6532ed2aac22729b53290 (diff) |
refactor
-rw-r--r-- | cavegen.c | 86 | ||||
-rw-r--r-- | cavegen.h | 18 | ||||
-rw-r--r-- | main.c | 111 |
3 files changed, 130 insertions, 85 deletions
@@ -3,10 +3,7 @@ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> -#include <time.h> -#define HEIGHT 100 -#define WIDTH 180 #define MAX_STEPS 200 #define NUM_WALKERS 100 @@ -18,60 +15,51 @@ enum direction { NUM_DIRS, }; -void create_cave(bool **map, struct point **open, int *open_tiles) +void create_cave( + enum tile_type **map, struct point **open_tiles, int *num_open_tiles, + struct point *up, struct point *down +) { - srand(time(NULL)); - *map = malloc(sizeof(bool) * HEIGHT * WIDTH); + // create a map consisting entirely of walls + *map = malloc(sizeof(enum tile_type) * HEIGHT * WIDTH); for (int i = 0; i < HEIGHT; ++i) { for (int j = 0; j < WIDTH; ++j) { - (*map)[i * WIDTH + j] = false; + (*map)[i * WIDTH + j] = WALL; } } - int start_x = WIDTH / 2; - int start_y = HEIGHT / 2; - *open_tiles = 1; - *open = malloc(sizeof(struct point) * HEIGHT * WIDTH); - struct point p = {.x = start_x, .y = start_y}; - (*open)[0] = p; + // start in the middle of the screen + int start_x = WIDTH / 2; + int start_y = HEIGHT / 2; + + // make the starting point GROUND + (*map)[start_y * WIDTH + start_x] = GROUND; + *open_tiles = malloc(sizeof(struct point) * HEIGHT * WIDTH); + *num_open_tiles = 1; + (*open_tiles)[0].x = start_x; + (*open_tiles)[0].y = start_y; for (int i = 0; i < NUM_WALKERS; ++i) { - struct point curr_point = (*open)[rand() % *open_tiles]; - int x_pos = curr_point.x; - int y_pos = curr_point.y; + // get a random open point + struct point curr_point = (*open_tiles)[rand() % *num_open_tiles]; + + int x_pos = curr_point.x; + int y_pos = curr_point.y; + // iterate until the walk exits the array or MAX_STEPS is reached for (int j = 1; j < MAX_STEPS - 1 && x_pos < WIDTH - 1 && x_pos >= 1 && y_pos < HEIGHT - 1 && y_pos >= 1; ++j) { - if (!((*map)[y_pos * WIDTH + x_pos])) { - (*map)[y_pos * WIDTH + x_pos] = true; - struct point p = {.x = x_pos, .y = y_pos}; - (*open)[(*open_tiles)++] = p; - } - enum direction dir = rand() % NUM_DIRS; - switch (dir) { - case UP : --y_pos; break; - case LEFT : --x_pos; break; - case RIGHT : ++x_pos; break; - case DOWN : ++y_pos; break; - default : exit(EXIT_FAILURE); // should not occur + // add new open point if the current point is still a wall + if ((*map)[y_pos * WIDTH + x_pos] == WALL) { + (*open_tiles)[*num_open_tiles].x = x_pos; + (*open_tiles)[*num_open_tiles].y = y_pos; + ++(*num_open_tiles); } - } - } - for (int i = 0; i < NUM_WALKERS; ++i) { - struct point curr_point = (*open)[rand() % *open_tiles]; - int x_pos = curr_point.x; - int y_pos = curr_point.y; + (*map)[y_pos * WIDTH + x_pos] = GROUND; // assign ground - for (int j = 1; j < MAX_STEPS - 1 && x_pos < WIDTH - 1 && x_pos >= 1 && - y_pos < HEIGHT - 1 && y_pos >= 1; - ++j) { - if (!((*map)[y_pos * WIDTH + x_pos])) { - (*map)[y_pos * WIDTH + x_pos] = true; - struct point p = {.x = x_pos, .y = y_pos}; - (*open)[(*open_tiles)++] = p; - } + // move in a random direction enum direction dir = rand() % NUM_DIRS; switch (dir) { case UP : --y_pos; break; @@ -82,4 +70,18 @@ void create_cave(bool **map, struct point **open, int *open_tiles) } } } + + // assign the up stair and remove from open tiles + int in = rand() % *num_open_tiles; + *up = (*open_tiles)[in]; + (*open_tiles)[in] = (*open_tiles)[*num_open_tiles - 1]; + --(*num_open_tiles); + (*map)[up->y * WIDTH + up->x] = UP_STAIR; + + // assign the down stair and remove from open tiles + in = rand() % *num_open_tiles; + *down = (*open_tiles)[in]; + (*open_tiles)[in] = (*open_tiles)[*num_open_tiles - 1]; + --(*num_open_tiles); + (*map)[down->y * WIDTH + down->x] = DOWN_STAIR; } @@ -3,16 +3,24 @@ #include <stdbool.h> -#define HEIGHT 100 -#define WIDTH 180 -#define MAX_STEPS 200 -#define NUM_WALKERS 100 +#define HEIGHT 100 +#define WIDTH 180 + +enum tile_type { + WALL, + GROUND, + UP_STAIR, + DOWN_STAIR, +}; struct point { int x; int y; }; -void create_cave(bool **map, struct point **open, int *open_tiles); +void create_cave( + enum tile_type **map, struct point **open, int *open_tiles, + struct point *up, struct point *down +); #endif // CAVEGEN_H_ @@ -1,6 +1,7 @@ #include <curses.h> #include <locale.h> #include <stdlib.h> +#include <time.h> #include "cavegen.h" @@ -11,7 +12,17 @@ #define MESSAGE_PANEL_WIDTH 100 #define MESSAGE_PANEL_HEIGHT 3 +#define MAX_ENTITIES 100 + +struct entity { + char *name; + int xpos; + int ypos; + char *disp_ch; +}; + WINDOW *create_newwin(int height, int width, int starty, int startx) + { WINDOW *local_win = newwin(height, width, starty, startx); box(local_win, 0, 0); @@ -22,6 +33,7 @@ WINDOW *create_newwin(int height, int width, int starty, int startx) void initialize(void) { + srand(time(NULL)); setlocale(LC_ALL, ""); // allow extended ASCII initscr(); // initialize curses @@ -51,38 +63,47 @@ void initialize(void) refresh(); } -void display_map(WINDOW *win, bool *map, int cam_y, int cam_x) +void display_map( + WINDOW *win, enum tile_type *map, struct entity *entities, int num_entities +) { for (int i = 1; i < MAIN_PANEL_HEIGHT - 1; ++i) { for (int j = 1; j < MAIN_PANEL_WIDTH - 1; ++j) { - int i1 = i - 1 + cam_y; - int j1 = j - 1 + cam_x; + int i1 = i - 1 + entities[0].ypos; + int j1 = j - 1 + entities[0].xpos; if (i1 > HEIGHT || j1 > WIDTH || i1 < 0 || j1 < 0) { mvwaddch(win, i, j, ' '); - } else if (map[i1 * WIDTH + j1]) { + } else if (map[i1 * WIDTH + j1] == GROUND) { mvwaddch(win, i, j, '.'); - } else if (i1 > 0 && map[(i1 - 1) * WIDTH + j1]) { + } else if (map[i1 * WIDTH + j1] == UP_STAIR) { + mvwaddch(win, i, j, '<'); + } else if (map[i1 * WIDTH + j1] == DOWN_STAIR) { + mvwaddch(win, i, j, '>'); + } else if (i1 > 0 && map[(i1 - 1) * WIDTH + j1] != WALL) { mvwprintw(win, i, j, "█"); - } else if (i1 < HEIGHT - 1 && map[(i1 + 1) * WIDTH + j1]) { + } else if (i1 < HEIGHT - 1 && map[(i1 + 1) * WIDTH + j1] != WALL) { mvwprintw(win, i, j, "█"); - } else if (j1 > 0 && map[i1 * WIDTH + j1 - 1]) { + } else if (j1 > 0 && map[i1 * WIDTH + j1 - 1] != WALL) { mvwprintw(win, i, j, "█"); - } else if (j1 < WIDTH - 1 && map[i1 * WIDTH + j1 + 1]) { + } else if (j1 < WIDTH - 1 && map[i1 * WIDTH + j1 + 1] != WALL) { mvwprintw(win, i, j, "█"); } else { mvwaddch(win, i, j, ' '); } } } - mvwaddch(win, MAIN_PANEL_HEIGHT / 2, MAIN_PANEL_WIDTH / 2, '@'); + + for (int i = 1; i < num_entities; ++i) { + mvwprintw( + win, entities[i].ypos - entities[0].ypos + 1, + entities[i].xpos - entities[0].xpos + 1, entities[i].disp_ch + ); + } wrefresh(win); } int main(void) { - int starty = 12; - int startx = 40; - initialize(); // create the windows @@ -116,49 +137,63 @@ int main(void) wattron(main_win, COLOR_PAIR(1)); wrefresh(main_win); - bool *map; - struct point *open_tiles; - int num_open_tiles; - create_cave(&map, &open_tiles, &num_open_tiles); - - int xpos = rand() % num_open_tiles; - int ypos = rand() % num_open_tiles; - startx = xpos = MAIN_PANEL_WIDTH / 2 + 1; - starty = ypos = MAIN_PANEL_HEIGHT / 2 + 1; - - display_map(main_win, map, starty, startx); + enum tile_type *map; + struct point *open_tiles; + int num_open_tiles; + struct point up; + struct point down; + create_cave(&map, &open_tiles, &num_open_tiles, &up, &down); + + struct entity *entities = malloc(sizeof(struct entity) * MAX_ENTITIES); + entities[0].disp_ch = ""; + entities[0].name = "camera"; + entities[0].xpos = up.x - MAIN_PANEL_WIDTH / 2 + 1; + entities[0].ypos = up.y - MAIN_PANEL_HEIGHT / 2 + 1; + entities[1].disp_ch = "@"; + entities[1].name = "player"; + entities[1].xpos = up.x; + entities[1].ypos = up.y; + int num_entities = 2; + + display_map(main_win, map, entities, num_entities); int ch; while ((ch = getch()) != KEY_F(1)) { - xpos = startx + MAIN_PANEL_WIDTH / 2 - 1; - ypos = starty + MAIN_PANEL_HEIGHT / 2 - 1; switch (ch) { case 'k' : - if (ypos > 0) { - if (map[(ypos - 1) * WIDTH + xpos]) - --starty; + if (entities[1].ypos > 0) { + if (map[(entities[1].ypos - 1) * WIDTH + entities[1].xpos]) { + --entities[0].ypos; + --entities[1].ypos; + } } break; case 'j' : - if (ypos < HEIGHT - 1) { - if (map[(ypos + 1) * WIDTH + xpos]) - ++starty; + if (entities[1].ypos < HEIGHT - 1) { + if (map[(entities[1].ypos + 1) * WIDTH + entities[1].xpos]) { + ++entities[0].ypos; + ++entities[1].ypos; + } } break; case 'h' : - if (xpos > 0) { - if (map[ypos * WIDTH + xpos - 1]) - --startx; + if (entities[1].xpos > 0) { + if (map[entities[1].ypos * WIDTH + entities[1].xpos - 1]) { + --entities[0].xpos; + --entities[1].xpos; + } } break; case 'l' : - if (xpos < WIDTH - 1) { - if (map[ypos * WIDTH + xpos + 1]) - ++startx; + if (entities[1].xpos < WIDTH - 1) { + if (map[entities[1].ypos * WIDTH + entities[1].xpos + 1]) { + ++entities[0].xpos; + ++entities[1].xpos; + } } break; } - display_map(main_win, map, starty, startx); + display_map(main_win, map, entities, num_entities); } endwin(); |