diff --git a/src/engine/engine/grid_game_engine.c b/src/engine/engine/grid_game_engine.c index 3989236..f90bd6f 100644 --- a/src/engine/engine/grid_game_engine.c +++ b/src/engine/engine/grid_game_engine.c @@ -20,24 +20,24 @@ int modulo(const int number, const int mod) { 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); for (int y = 0; y < height; 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); } refresh(); } 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) { - if (grid_put(gp, x, y, c) == 1) { - mvaddch(y, x, c); +void update_grid(grid *gp, const char ch, coordinate c) { + if (grid_put(gp, ch, c) == 1) { + mvaddch(c.y, c.x, ch); } } diff --git a/src/engine/engine/grid_game_engine.h b/src/engine/engine/grid_game_engine.h index df8654f..6d9cc86 100644 --- a/src/engine/engine/grid_game_engine.h +++ b/src/engine/engine/grid_game_engine.h @@ -12,11 +12,6 @@ #define KEY_ESCAPE 27 -typedef struct { - int x; - int y; -} coordinate; - // Start at 1 since the color 0 is reserved for no_color. typedef enum { BLACK = 1, @@ -58,11 +53,12 @@ int modulo(int number, int mod); * * Input: * gp: A pointer to the grid. + * c: The location you want to show the grid at. * * Side effect: * 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. @@ -110,14 +106,13 @@ void disable_highlight(game_colors color); * * Input: * gp: A pointer to the grid. - * c: The character to update the location with. - * x: The x-coordinate of the spot you want to update. - * y: The y-coordinate of the spot you want to update. + * ch: The character to update the location with. + * c: The spot you want to update. * * Side effect: * 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. diff --git a/src/engine/grid/grid.c b/src/engine/grid/grid.c index 6489548..7ed63cc 100644 --- a/src/engine/grid/grid.c +++ b/src/engine/grid/grid.c @@ -22,8 +22,8 @@ typedef struct grid_data { /* * 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) { - return y * (gp->width + 1) + x; +static int internal_location(const grid *gp, const coordinate c) { + return c.y * (gp->width + 1) + c.x; } grid *grid_create_from_string(const char* input) { @@ -222,9 +222,9 @@ int grid_height(const grid *gp) { 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 (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; } @@ -232,26 +232,27 @@ int grid_contains(const grid *gp, const int x, const int y) { return 0; } -char grid_fetch(const grid *gp, const int x, const int y) { - if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { - return gp->locations[internal_location(gp, x, y)]; +char grid_fetch(const grid *gp, const coordinate c) { + if (gp != NULL && gp->locations != NULL && grid_contains(gp, c) == 1) { + return gp->locations[internal_location(gp, c)]; } return '\0'; } -int grid_put(grid *gp, const int x, const int y, const char c) { - if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { - gp->locations[internal_location(gp, x, y)] = c; +int grid_put(grid *gp, const char ch, const coordinate c) { + if (gp != NULL && gp->locations != NULL && grid_contains(gp, c) == 1) { + gp->locations[internal_location(gp, c)] = ch; return 1; } return 0; } 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 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'; return row; } @@ -282,11 +283,10 @@ grid *grid_copy(const grid *gp) { 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) { - *x = -1; - *y = -1; - return; + return not_found; } 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') { - *x = -1; - *y = -1; - return; + return not_found; } - *x = char_index % (gp->width + 1); - *y = char_index / (gp->width + 1); + return (coordinate){.x = char_index % (gp->width + 1), .y = char_index / (gp->width + 1)}; } diff --git a/src/engine/grid/grid.h b/src/engine/grid/grid.h index 838834e..16527b1 100644 --- a/src/engine/grid/grid.h +++ b/src/engine/grid/grid.h @@ -15,6 +15,11 @@ struct grid_data; typedef struct grid_data grid; +typedef struct { + int x; + int y; +} coordinate; + typedef enum { STATE_BEGIN, STATE_AAN_HET_SPELEN, @@ -124,36 +129,36 @@ int grid_height(const grid *gp); /* Kijk of de gegeven positie binnen het rooster valt. * * gp: een pointer naar het rooster. - * x,y: de positie. + * c: de positie. * * 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. * - * gp : een pointer naar het rooster - * x,y: de betreffende positie. + * gp: een pointer naar het rooster + * c: de betreffende positie. * * Uitvoer: het object op die positie, of '\0' als de positie buiten het * 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. * - * gp : een pointer naar het rooster - * x,y: de betreffende positie. - * c : het object. + * gp: een pointer naar het rooster + * ch: 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. * * 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 @@ -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 * de positie wordt gevonden. * - * gp : een pointer naar het rooster - * c : het object dat moet worden gezocht - * x,y: pointers naar de geheugenlocaties waar de gevonden positie moet worden - * geschreven. + * gp: een pointer naar het rooster + * c: het object dat moet worden gezocht * - * Uitvoer: via de pointers x en y. Als het object niet wordt gevonden worden - * *x en *y op -1 gezet. + * Uitvoer: de locatie van het object. (x and y zijn -1 als het niet gevonden is.) */ -void grid_find(const grid *gp, char c, int *x, int *y); +coordinate grid_find(const grid *gp, char c); #endif //_GRID_H diff --git a/src/games/manual/manual.c b/src/games/manual/manual.c index 57bcc84..ee80c0b 100644 --- a/src/games/manual/manual.c +++ b/src/games/manual/manual.c @@ -23,13 +23,13 @@ void manual(const coordinate display_location) { 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. timeout(200); for (int ch = getch(); ch != KEY_ESCAPE && ch != KEY_BACKSPACE; ch = getch()) { // 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); diff --git a/src/games/maze-runner/maze_runner.c b/src/games/maze-runner/maze_runner.c index 3aafe60..9927025 100644 --- a/src/games/maze-runner/maze_runner.c +++ b/src/games/maze-runner/maze_runner.c @@ -53,8 +53,7 @@ static grid *get_maze(void) { * de speler. */ static void maze_runner_move(grid *gp, const int dx, const int dy) { - coordinate player_position = {0, 0}; - grid_find(gp, LIVING_PLAYER, &player_position.x, &player_position.y); + const coordinate player_position = grid_find(gp, LIVING_PLAYER); if (player_position.y == -1) { printf("Player not found!"); @@ -62,8 +61,12 @@ static void maze_runner_move(grid *gp, const int dx, const int dy) { return; } - if (grid_contains(gp, player_position.x + dx, player_position.y + dy) == 1) { - char new_location = grid_fetch(gp, player_position.x + dx, player_position.y + dy); + coordinate new_player_position = player_position; + 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) { case WALL: break; @@ -71,15 +74,15 @@ static void maze_runner_move(grid *gp, const int dx, const int dy) { grid_put_state(gp, STATE_VERLOREN); enable_highlight(RED); - update_grid(gp, DEAD_PLAYER, player_position.x, player_position.y); + update_grid(gp, DEAD_PLAYER, player_position); disable_highlight(RED); break; case EMPTY: - update_grid(gp, EMPTY, player_position.x, player_position.y); - update_grid(gp, LIVING_PLAYER, player_position.x + dx, player_position.y + dy); + update_grid(gp, EMPTY, player_position); + update_grid(gp, LIVING_PLAYER, player_position); break; 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); break; } diff --git a/src/games/minigame-menu/minigame_menu.c b/src/games/minigame-menu/minigame_menu.c index 97e7561..abb3e62 100644 --- a/src/games/minigame-menu/minigame_menu.c +++ b/src/games/minigame-menu/minigame_menu.c @@ -24,8 +24,7 @@ typedef enum { } game; static game SELECTED_GAME = GAME_MANUAL; -static int OFFSET_Y = 5; -static int OFFSET_X = 5; +static coordinate OFFSET = {.x = 5, .y = 5}; /* * Launch a game from the menu. @@ -57,8 +56,6 @@ static void launch_game(const game game) { * Input: * menu: A pointer to the menu grid. * target: The menu option to highlight. - * offset_x: The x offset of the menu. - * offset_y: The y offset of the menu. * * Side effects: * 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)); 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); attroff(COLOR_PAIR(GREEN)); @@ -87,15 +84,13 @@ static void menu_highlight(const grid *menu) { * Input: * menu: A pointer to the menu grid. * 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: * Displays the menu */ static void show_menu(const grid *menu) { erase(); - show_grid_on_offset(menu, OFFSET_X, OFFSET_Y); + show_grid_on_offset(menu, OFFSET); menu_highlight(menu); refresh(); } @@ -179,6 +174,7 @@ void minigame_menu(void) { grid *menu = initialize_menu(); while (true) { if (navigate_menu() == 1) { + show_menu(menu); break; } } diff --git a/src/games/snake/snake.c b/src/games/snake/snake.c index 89aefa8..ef2b9db 100644 --- a/src/games/snake/snake.c +++ b/src/games/snake/snake.c @@ -132,9 +132,9 @@ static void generate_food(void) { for (int x = 0; x < MAP_WIDTH; x++) { for (int y = 0; y < MAP_HEIGHT; y++) { - if (grid_fetch(GRID, x, y) == CELL_EMPTY) { - const coordinate new_spot = {x, y}; - empty_spots[available_spots] = new_spot; + const coordinate location = {x, y}; + if (grid_fetch(GRID, location) == CELL_EMPTY) { + empty_spots[available_spots] = location; available_spots++; } } @@ -142,7 +142,7 @@ static void generate_food(void) { 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}; // 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(); 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. */ 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) { grid_put_state(GRID, STATE_VERLOREN); @@ -230,7 +230,7 @@ static void update_snake(const coordinate new_location) { if (action == SNAKE_MOVE) { 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: new_tail.y--; break; @@ -245,12 +245,12 @@ static void update_snake(const coordinate new_location) { break; } - grid_put(GRID, SNAKE_TAIL.x, SNAKE_TAIL.y, CELL_EMPTY); + grid_put(GRID, CELL_EMPTY, SNAKE_TAIL); SNAKE_TAIL = new_tail; } // 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; PREVIOUS_DIRECTION = CURRENT_DIRECTION; @@ -300,7 +300,7 @@ static void *snake_move(void *arg) { } 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); } return NULL; @@ -324,9 +324,9 @@ static void turn_snake(const direction dir) { && !same_coordinate(SNAKE_HEAD, SNAKE_TAIL)) { 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; - 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. erase(); - show_grid_on_offset(GRID, OFFSET_X, OFFSET_Y); + show_grid_on_offset(GRID, RENDER_AT); wait_for_start();