aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cavegen.c86
-rw-r--r--cavegen.h18
-rw-r--r--main.c111
3 files changed, 130 insertions, 85 deletions
diff --git a/cavegen.c b/cavegen.c
index 11a88cb..9c3a4af 100644
--- a/cavegen.c
+++ b/cavegen.c
@@ -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;
}
diff --git a/cavegen.h b/cavegen.h
index 829c7a6..450f905 100644
--- a/cavegen.h
+++ b/cavegen.h
@@ -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_
diff --git a/main.c b/main.c
index 3dcc0d7..5b4f3b0 100644
--- a/main.c
+++ b/main.c
@@ -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();