#include "world.h" #include "snake.h" #include #include #include // usleep #include // terminal config #include // non-blocking input // Enable non-blocking keyboard input void enable_nonblocking_input() { struct termios ttystate; tcgetattr(STDIN_FILENO, &ttystate); ttystate.c_lflag &= ~(ICANON | ECHO); // Disable buffering and echo tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // Non-blocking mode } // Reset terminal settings to default void disable_nonblocking_input() { struct termios ttystate; tcgetattr(STDIN_FILENO, &ttystate); ttystate.c_lflag |= ICANON | ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); } int main() { struct state game_world; init_world(&game_world, 30, 20); // Bigger field game_world.sx = 1; // Initial movement right game_world.sy = 0; enable_nonblocking_input(); while (1) { // Clear screen and print game state printf("\033[H\033[J"); // Clear terminal screen print_world(&game_world); // Read input char ch = getchar(); switch (ch) { case 'w': if (game_world.sy != 1) { game_world.sx = 0; game_world.sy = -1; } break; case 's': if (game_world.sy != -1) { game_world.sx = 0; game_world.sy = 1; } break; case 'a': if (game_world.sx != 1) { game_world.sx = -1; game_world.sy = 0; } break; case 'd': if (game_world.sx != -1) { game_world.sx = 1; game_world.sy = 0; } break; case 'q': printf("Quit.\n"); goto end; } // Step game int status = step_state(&game_world); if (status == END_WALL) { printf("Game Over: Hit the wall!\n"); break; } else if (status == END_SNAKE) { printf("Game Over: Ate itself!\n"); break; } usleep(200000); // Delay ~5 fps } end: disable_nonblocking_input(); free_snake(game_world.snake); return 0; }