replaced x and y positions with coordinate

This commit is contained in:
2025-10-30 12:07:27 +01:00
parent 299612634b
commit fb7856b69e
8 changed files with 78 additions and 85 deletions

View File

@@ -20,24 +20,24 @@ int modulo(const int number, const int mod) {
return result; return result;
} }
void show_grid_on_offset(const grid *gp, const int starting_x, const int starting_y) { void show_grid_on_offset(const grid *gp, const coordinate offset) {
const int height = grid_height(gp); const int height = grid_height(gp);
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
char *rij = grid_fetch_row(gp, y); char *rij = grid_fetch_row(gp, y);
mvprintw(starting_y + y, starting_x, "%s", rij); mvprintw(offset.y + y, offset.x, "%s", rij);
free(rij); free(rij);
} }
refresh(); refresh();
} }
void show_grid(const grid *gp) { void show_grid(const grid *gp) {
show_grid_on_offset(gp, 0, 0); show_grid_on_offset(gp, (coordinate){.x = 0, .y = 0});
} }
void update_grid(grid *gp, const char c, const int x, const int y) { void update_grid(grid *gp, const char ch, coordinate c) {
if (grid_put(gp, x, y, c) == 1) { if (grid_put(gp, ch, c) == 1) {
mvaddch(y, x, c); mvaddch(c.y, c.x, ch);
} }
} }

View File

@@ -12,11 +12,6 @@
#define KEY_ESCAPE 27 #define KEY_ESCAPE 27
typedef struct {
int x;
int y;
} coordinate;
// Start at 1 since the color 0 is reserved for no_color. // Start at 1 since the color 0 is reserved for no_color.
typedef enum { typedef enum {
BLACK = 1, BLACK = 1,
@@ -58,11 +53,12 @@ int modulo(int number, int mod);
* *
* Input: * Input:
* gp: A pointer to the grid. * gp: A pointer to the grid.
* c: The location you want to show the grid at.
* *
* Side effect: * Side effect:
* The console is cleared and the grid is printed. * The console is cleared and the grid is printed.
*/ */
void show_grid_on_offset(const grid *gp, int starting_x, int starting_y); void show_grid_on_offset(const grid *gp, coordinate c);
/* /*
* Displays the given grid with ncurses. * Displays the given grid with ncurses.
@@ -110,14 +106,13 @@ void disable_highlight(game_colors color);
* *
* Input: * Input:
* gp: A pointer to the grid. * gp: A pointer to the grid.
* c: The character to update the location with. * ch: The character to update the location with.
* x: The x-coordinate of the spot you want to update. * c: The spot you want to update.
* y: The y-coordinate of the spot you want to update.
* *
* Side effect: * Side effect:
* The update gets applied both on the grid and on the screen. * The update gets applied both on the grid and on the screen.
*/ */
void update_grid(grid *gp, char c, int x, int y); void update_grid(grid *gp, char ch, coordinate c);
/* /*
* Display the ending screen that matches the end state of the grid. * Display the ending screen that matches the end state of the grid.

View File

@@ -22,8 +22,8 @@ typedef struct grid_data {
/* /*
* Translate x and y coordinates to a location index on the grid. * Translate x and y coordinates to a location index on the grid.
*/ */
static int internal_location(const grid *gp, const int x, const int y) { static int internal_location(const grid *gp, const coordinate c) {
return y * (gp->width + 1) + x; return c.y * (gp->width + 1) + c.x;
} }
grid *grid_create_from_string(const char* input) { grid *grid_create_from_string(const char* input) {
@@ -222,9 +222,9 @@ int grid_height(const grid *gp) {
return gp->height; return gp->height;
} }
int grid_contains(const grid *gp, const int x, const int y) { int grid_contains(const grid *gp, const coordinate c) {
if (gp != NULL && gp->locations != NULL) { if (gp != NULL && gp->locations != NULL) {
if (x >= 0 && y >= 0 && x < gp->width && y < gp->height) if (c.x >= 0 && c.y >= 0 && c.x < gp->width && c.y < gp->height)
{ {
return 1; return 1;
} }
@@ -232,26 +232,27 @@ int grid_contains(const grid *gp, const int x, const int y) {
return 0; return 0;
} }
char grid_fetch(const grid *gp, const int x, const int y) { char grid_fetch(const grid *gp, const coordinate c) {
if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { if (gp != NULL && gp->locations != NULL && grid_contains(gp, c) == 1) {
return gp->locations[internal_location(gp, x, y)]; return gp->locations[internal_location(gp, c)];
} }
return '\0'; return '\0';
} }
int grid_put(grid *gp, const int x, const int y, const char c) { int grid_put(grid *gp, const char ch, const coordinate c) {
if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { if (gp != NULL && gp->locations != NULL && grid_contains(gp, c) == 1) {
gp->locations[internal_location(gp, x, y)] = c; gp->locations[internal_location(gp, c)] = ch;
return 1; return 1;
} }
return 0; return 0;
} }
char *grid_fetch_row(const grid *gp, const int y) { char *grid_fetch_row(const grid *gp, const int y) {
if (gp != NULL && gp->locations != NULL && grid_contains(gp, 0, y) == 1) { const coordinate row_start = {.x = 0, .y = y};
if (gp != NULL && gp->locations != NULL && grid_contains(gp, row_start) == 1) {
// we're going to remove the newline so this is long enough // we're going to remove the newline so this is long enough
char *row = malloc((gp->width + 1) * sizeof(char)); char *row = malloc((gp->width + 1) * sizeof(char));
memcpy(row, &gp->locations[internal_location(gp, 0, y)], gp->width * sizeof(char)); memcpy(row, &gp->locations[internal_location(gp, row_start)], gp->width * sizeof(char));
row[gp->width] = '\0'; row[gp->width] = '\0';
return row; return row;
} }
@@ -282,11 +283,10 @@ grid *grid_copy(const grid *gp) {
return NULL; return NULL;
} }
void grid_find(const grid *gp, const char c, int *x, int *y) { coordinate grid_find(const grid *gp, const char c) {
const coordinate not_found = {.x = -1, .y = -1};
if (gp == NULL || gp->locations == NULL) { if (gp == NULL || gp->locations == NULL) {
*x = -1; return not_found;
*y = -1;
return;
} }
const char search[2] = {c}; const char search[2] = {c};
@@ -295,11 +295,8 @@ void grid_find(const grid *gp, const char c, int *x, int *y) {
if (gp->locations[char_index] == '\0') if (gp->locations[char_index] == '\0')
{ {
*x = -1; return not_found;
*y = -1;
return;
} }
*x = char_index % (gp->width + 1); return (coordinate){.x = char_index % (gp->width + 1), .y = char_index / (gp->width + 1)};
*y = char_index / (gp->width + 1);
} }

View File

@@ -15,6 +15,11 @@
struct grid_data; struct grid_data;
typedef struct grid_data grid; typedef struct grid_data grid;
typedef struct {
int x;
int y;
} coordinate;
typedef enum { typedef enum {
STATE_BEGIN, STATE_BEGIN,
STATE_AAN_HET_SPELEN, STATE_AAN_HET_SPELEN,
@@ -124,36 +129,36 @@ int grid_height(const grid *gp);
/* Kijk of de gegeven positie binnen het rooster valt. /* Kijk of de gegeven positie binnen het rooster valt.
* *
* gp: een pointer naar het rooster. * gp: een pointer naar het rooster.
* x,y: de positie. * c: de positie.
* *
* Uitvoer: 1 als de positie binnen het rooster valt, anders 0. * Uitvoer: 1 als de positie binnen het rooster valt, anders 0.
*/ */
int grid_contains(const grid *gp, int x, int y); int grid_contains(const grid *gp, coordinate c);
/* Kijk welk object er staat op een bepaalde positie in het rooster. /* Kijk welk object er staat op een bepaalde positie in het rooster.
* *
* gp : een pointer naar het rooster * gp: een pointer naar het rooster
* x,y: de betreffende positie. * c: de betreffende positie.
* *
* Uitvoer: het object op die positie, of '\0' als de positie buiten het * Uitvoer: het object op die positie, of '\0' als de positie buiten het
* rooster valt. * rooster valt.
*/ */
char grid_fetch(const grid *gp, int x, int y); char grid_fetch(const grid *gp, coordinate c);
/* Schrijf een bepaald object op een bepaalde positie in het rooster. /* Schrijf een bepaald object op een bepaalde positie in het rooster.
* *
* gp : een pointer naar het rooster * gp: een pointer naar het rooster
* x,y: de betreffende positie. * ch: het object.
* c : het object. * c: de locatie.
* *
* Effect: als (x,y) binnen het rooster ligt, wordt het object op * Effect: als c binnen het rooster ligt, wordt het object op
* de opgegeven positie geplaatst, anders verandert er niets. * de opgegeven positie geplaatst, anders verandert er niets.
* *
* Uitvoer: 1 als het object is geplaatst, of 0 als het buiten de grenzen lag. * Uitvoer: 1 als het object is geplaatst, of 0 als het buiten de grenzen lag.
*/ */
int grid_put(grid *gp, int x, int y, char c); int grid_put(grid *gp, char ch, coordinate c);
/* Zoek een bepaald object in het rooster, en geef de coordinaten van het /* Zoek een bepaald object in het rooster, en geef de coordinaten van het
@@ -161,14 +166,11 @@ int grid_put(grid *gp, int x, int y, char c);
* het gezochte soort in het rooster voorkomen, is niet gedefinieerd van welke * het gezochte soort in het rooster voorkomen, is niet gedefinieerd van welke
* de positie wordt gevonden. * de positie wordt gevonden.
* *
* gp : een pointer naar het rooster * gp: een pointer naar het rooster
* c : het object dat moet worden gezocht * c: het object dat moet worden gezocht
* x,y: pointers naar de geheugenlocaties waar de gevonden positie moet worden
* geschreven.
* *
* Uitvoer: via de pointers x en y. Als het object niet wordt gevonden worden * Uitvoer: de locatie van het object. (x and y zijn -1 als het niet gevonden is.)
* *x en *y op -1 gezet.
*/ */
void grid_find(const grid *gp, char c, int *x, int *y); coordinate grid_find(const grid *gp, char c);
#endif //_GRID_H #endif //_GRID_H

View File

@@ -23,13 +23,13 @@ void manual(const coordinate display_location) {
fclose(fp); fclose(fp);
show_grid_on_offset(grid, display_location.x, display_location.y); show_grid_on_offset(grid, display_location);
// Wait until ESCAPE or BACKSPACE is pressed. // Wait until ESCAPE or BACKSPACE is pressed.
timeout(200); timeout(200);
for (int ch = getch(); ch != KEY_ESCAPE && ch != KEY_BACKSPACE; ch = getch()) { for (int ch = getch(); ch != KEY_ESCAPE && ch != KEY_BACKSPACE; ch = getch()) {
// Update the screen in the meantime to accommodate windows resizes. // Update the screen in the meantime to accommodate windows resizes.
show_grid_on_offset(grid, display_location.x, display_location.y); show_grid_on_offset(grid, display_location);
} }
grid_cleanup(grid); grid_cleanup(grid);

View File

@@ -53,8 +53,7 @@ static grid *get_maze(void) {
* de speler. * de speler.
*/ */
static void maze_runner_move(grid *gp, const int dx, const int dy) { static void maze_runner_move(grid *gp, const int dx, const int dy) {
coordinate player_position = {0, 0}; const coordinate player_position = grid_find(gp, LIVING_PLAYER);
grid_find(gp, LIVING_PLAYER, &player_position.x, &player_position.y);
if (player_position.y == -1) { if (player_position.y == -1) {
printf("Player not found!"); printf("Player not found!");
@@ -62,8 +61,12 @@ static void maze_runner_move(grid *gp, const int dx, const int dy) {
return; return;
} }
if (grid_contains(gp, player_position.x + dx, player_position.y + dy) == 1) { coordinate new_player_position = player_position;
char new_location = grid_fetch(gp, player_position.x + dx, player_position.y + dy); new_player_position.x += dx;
new_player_position.y += dy;
if (grid_contains(gp, new_player_position) == 1) {
const char new_location = grid_fetch(gp, new_player_position);
switch (new_location) { switch (new_location) {
case WALL: case WALL:
break; break;
@@ -71,15 +74,15 @@ static void maze_runner_move(grid *gp, const int dx, const int dy) {
grid_put_state(gp, STATE_VERLOREN); grid_put_state(gp, STATE_VERLOREN);
enable_highlight(RED); enable_highlight(RED);
update_grid(gp, DEAD_PLAYER, player_position.x, player_position.y); update_grid(gp, DEAD_PLAYER, player_position);
disable_highlight(RED); disable_highlight(RED);
break; break;
case EMPTY: case EMPTY:
update_grid(gp, EMPTY, player_position.x, player_position.y); update_grid(gp, EMPTY, player_position);
update_grid(gp, LIVING_PLAYER, player_position.x + dx, player_position.y + dy); update_grid(gp, LIVING_PLAYER, player_position);
break; break;
case MAZE_EXIT: case MAZE_EXIT:
update_grid(gp, EMPTY, player_position.x, player_position.y); update_grid(gp, EMPTY, player_position);
grid_put_state(gp, STATE_GEWONNEN); grid_put_state(gp, STATE_GEWONNEN);
break; break;
} }

View File

@@ -24,8 +24,7 @@ typedef enum {
} game; } game;
static game SELECTED_GAME = GAME_MANUAL; static game SELECTED_GAME = GAME_MANUAL;
static int OFFSET_Y = 5; static coordinate OFFSET = {.x = 5, .y = 5};
static int OFFSET_X = 5;
/* /*
* Launch a game from the menu. * Launch a game from the menu.
@@ -57,8 +56,6 @@ static void launch_game(const game game) {
* Input: * Input:
* menu: A pointer to the menu grid. * menu: A pointer to the menu grid.
* target: The menu option to highlight. * target: The menu option to highlight.
* offset_x: The x offset of the menu.
* offset_y: The y offset of the menu.
* *
* Side effects: * Side effects:
* If a valid menu option is provided: It will be highlighted in green. * If a valid menu option is provided: It will be highlighted in green.
@@ -74,7 +71,7 @@ static void menu_highlight(const grid *menu) {
attron(COLOR_PAIR(GREEN)); attron(COLOR_PAIR(GREEN));
char* row = grid_fetch_row(menu, SELECTED_GAME); char* row = grid_fetch_row(menu, SELECTED_GAME);
mvprintw(OFFSET_Y + (int)SELECTED_GAME, OFFSET_X, "%s", row); mvprintw(OFFSET.y + (int)SELECTED_GAME, OFFSET.x, "%s", row);
free(row); free(row);
attroff(COLOR_PAIR(GREEN)); attroff(COLOR_PAIR(GREEN));
@@ -87,15 +84,13 @@ static void menu_highlight(const grid *menu) {
* Input: * Input:
* menu: A pointer to the menu grid. * menu: A pointer to the menu grid.
* default_selection: The starting selection in the menu. * default_selection: The starting selection in the menu.
* offset_x: The x offset of the menu.
* offset_y: The y offset of the menu.
* *
* Side Effects: * Side Effects:
* Displays the menu * Displays the menu
*/ */
static void show_menu(const grid *menu) { static void show_menu(const grid *menu) {
erase(); erase();
show_grid_on_offset(menu, OFFSET_X, OFFSET_Y); show_grid_on_offset(menu, OFFSET);
menu_highlight(menu); menu_highlight(menu);
refresh(); refresh();
} }
@@ -179,6 +174,7 @@ void minigame_menu(void) {
grid *menu = initialize_menu(); grid *menu = initialize_menu();
while (true) { while (true) {
if (navigate_menu() == 1) { if (navigate_menu() == 1) {
show_menu(menu);
break; break;
} }
} }

View File

@@ -132,9 +132,9 @@ static void generate_food(void) {
for (int x = 0; x < MAP_WIDTH; x++) { for (int x = 0; x < MAP_WIDTH; x++) {
for (int y = 0; y < MAP_HEIGHT; y++) { for (int y = 0; y < MAP_HEIGHT; y++) {
if (grid_fetch(GRID, x, y) == CELL_EMPTY) { const coordinate location = {x, y};
const coordinate new_spot = {x, y}; if (grid_fetch(GRID, location) == CELL_EMPTY) {
empty_spots[available_spots] = new_spot; empty_spots[available_spots] = location;
available_spots++; available_spots++;
} }
} }
@@ -142,7 +142,7 @@ static void generate_food(void) {
const coordinate food_location = empty_spots[modulo(rand(), available_spots)]; const coordinate food_location = empty_spots[modulo(rand(), available_spots)];
grid_put(GRID, food_location.x, food_location.y, CELL_FOOD); grid_put(GRID, CELL_FOOD, food_location);
} }
/* /*
@@ -176,7 +176,7 @@ static void initialize(void) {
MESSAGE_LOCATION = (coordinate){.x = RENDER_AT.x, .y = RENDER_AT.y + grid_height(GRID) + 2}; MESSAGE_LOCATION = (coordinate){.x = RENDER_AT.x, .y = RENDER_AT.y + grid_height(GRID) + 2};
// Create the first body part and spawn the first piece of food. // Create the first body part and spawn the first piece of food.
grid_put(GRID, SNAKE_HEAD.x, SNAKE_HEAD.y, get_body_part(CURRENT_DIRECTION)); grid_put(GRID, get_body_part(CURRENT_DIRECTION), SNAKE_HEAD);
generate_food(); generate_food();
pthread_mutex_init(&SNAKE_MUTEX, NULL); pthread_mutex_init(&SNAKE_MUTEX, NULL);
@@ -220,7 +220,7 @@ static snake_action collision_check(const char c) {
* Moving to a location the snake can't reach is undefined behaviour. * Moving to a location the snake can't reach is undefined behaviour.
*/ */
static void update_snake(const coordinate new_location) { static void update_snake(const coordinate new_location) {
const snake_action action = collision_check(grid_fetch(GRID, new_location.x, new_location.y)); const snake_action action = collision_check(grid_fetch(GRID, new_location));
if (action == SNAKE_DIE) { if (action == SNAKE_DIE) {
grid_put_state(GRID, STATE_VERLOREN); grid_put_state(GRID, STATE_VERLOREN);
@@ -230,7 +230,7 @@ static void update_snake(const coordinate new_location) {
if (action == SNAKE_MOVE) { if (action == SNAKE_MOVE) {
coordinate new_tail = SNAKE_TAIL; coordinate new_tail = SNAKE_TAIL;
switch (get_body_part_direction(grid_fetch(GRID, SNAKE_TAIL.x, SNAKE_TAIL.y))) { switch (get_body_part_direction(grid_fetch(GRID, SNAKE_TAIL))) {
case DIRECTION_UP: case DIRECTION_UP:
new_tail.y--; new_tail.y--;
break; break;
@@ -245,12 +245,12 @@ static void update_snake(const coordinate new_location) {
break; break;
} }
grid_put(GRID, SNAKE_TAIL.x, SNAKE_TAIL.y, CELL_EMPTY); grid_put(GRID, CELL_EMPTY, SNAKE_TAIL);
SNAKE_TAIL = new_tail; SNAKE_TAIL = new_tail;
} }
// New head placed after tail moves. It can occupy the empty space created by the tail moving. // New head placed after tail moves. It can occupy the empty space created by the tail moving.
grid_put(GRID, new_location.x, new_location.y, get_body_part(CURRENT_DIRECTION)); grid_put(GRID, get_body_part(CURRENT_DIRECTION), new_location);
SNAKE_HEAD = new_location; SNAKE_HEAD = new_location;
PREVIOUS_DIRECTION = CURRENT_DIRECTION; PREVIOUS_DIRECTION = CURRENT_DIRECTION;
@@ -300,7 +300,7 @@ static void *snake_move(void *arg) {
} }
update_snake(new_location); update_snake(new_location);
show_grid_on_offset(GRID, OFFSET_X, OFFSET_Y); show_grid_on_offset(GRID, RENDER_AT);
pthread_mutex_unlock(&SNAKE_MUTEX); pthread_mutex_unlock(&SNAKE_MUTEX);
} }
return NULL; return NULL;
@@ -324,9 +324,9 @@ static void turn_snake(const direction dir) {
&& !same_coordinate(SNAKE_HEAD, SNAKE_TAIL)) { && !same_coordinate(SNAKE_HEAD, SNAKE_TAIL)) {
return; return;
} }
grid_put(GRID, SNAKE_HEAD.x, SNAKE_HEAD.y, get_body_part(dir)); grid_put(GRID, get_body_part(dir), SNAKE_HEAD);
CURRENT_DIRECTION = dir; CURRENT_DIRECTION = dir;
show_grid_on_offset(GRID, OFFSET_X, OFFSET_Y); show_grid_on_offset(GRID, RENDER_AT);
} }
/* /*
@@ -426,7 +426,7 @@ void snake(void) {
// Show game. // Show game.
erase(); erase();
show_grid_on_offset(GRID, OFFSET_X, OFFSET_Y); show_grid_on_offset(GRID, RENDER_AT);
wait_for_start(); wait_for_start();