/* * Created by snapshot112 on 8/10/2025 */ #include "grid_game_engine.h" #include #include #include int same_coordinate(const coordinate a, const coordinate b) { return a.x == b.x && a.y == b.y; } int modulo(const int number, const int mod) { int result = number % mod; if (result < 0) { result += mod; //This is not how math is supposed to work C, damnit. } return result; } void show_grid_on_offset(const grid *gp, const int starting_x, const int starting_y) { 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); free(rij); } refresh(); } void show_grid(const grid *gp) { show_grid_on_offset(gp, 0, 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); } } /* * Shows the victory screen. * * Side Effect: * Clears the console and prints the victory message. */ static void display_victory(const coordinate location) { mvaddstr(location.y, location.x, "YOU WON!!!!!"); } /* * Shows the GAME OVER screen. * * Side Effect: * Clears the console and prints the GAME OVER message. */ static void display_loss(const coordinate location) { mvaddstr(location.y, location.x, "GAME OVER"); } /* * Shows the quit screen * * Side Effect: * Clears the console and prints the quit message. */ static void display_quit(const coordinate location) { mvaddstr(location.y, location.x, "You quit the game"); } /* * Shows the hacker man screen * * Side Effect: * Clears the console and prints the hacker man message. */ static void display_hackerman(const coordinate location) { mvaddstr(location.y, location.x, "The hacker man strikes again..."); } void graceful_exit(const coordinate message_location) { mvaddstr(message_location.y, message_location.x, "Press ENTER to exit."); while (1) { switch (getch()) { case KEY_BACKSPACE: case KEY_ESCAPE: case KEY_ENTER: case '\n': return; } } } void game_exit_message(const grid *gp, coordinate location) { const state current_state = grid_fetch_state(gp); switch (current_state) { case STATE_GEWONNEN: display_victory(location); break; case STATE_VERLOREN: display_loss(location); break; case STATE_QUIT: display_quit(location); break; default: display_hackerman(location); } location.y += 2; graceful_exit(location); refresh(); } void enable_highlight(const game_colors color) { attron(COLOR_PAIR(color)); } void disable_highlight(const game_colors color) { attroff(COLOR_PAIR(color)); } /* * Initialize ncurses. * * This enables cbreak, noecho, hides the cursor and enables the extra keys. * This also creates the color pairs needed for game_colors and sets ESCDELAY to 0. */ static void init_ncurses(void) { ESCDELAY = 0; setlocale(LC_ALL, ""); initscr(); cbreak(); // So you can cancel the game with ctrl + c. keypad(stdscr, TRUE); // Enable extra keys like the arrow keys. noecho(); // Don't write the keyboard input to the console. curs_set(0); // Hides the cursor. start_color(); init_pair(BLACK, COLOR_BLACK, COLOR_BLACK); init_pair(WHITE, COLOR_BLACK, COLOR_WHITE); init_pair(BLUE, COLOR_BLACK, COLOR_BLUE); init_pair(GREEN, COLOR_BLACK, COLOR_GREEN); init_pair(CYAN, COLOR_BLACK, COLOR_CYAN); init_pair(MAGENTA, COLOR_BLACK, COLOR_MAGENTA); init_pair(YELLOW, COLOR_BLACK, COLOR_YELLOW); init_pair(RED, COLOR_BLACK, COLOR_RED); clear(); } void init_engine(void) { init_ncurses(); } void cleanup_engine(void) { endwin(); }