The Snake Game is a classic video game where the player controls a snake that moves around a grid or screen, aiming to eat food and grow longer while avoiding collisions with itself or the walls. It’s a fun and challenging game that tests the player’s reflexes and strategic thinking. In this article, we will present a C program that implements the Snake Game, allowing users to play and enjoy this timeless game on their computers.
Problem statement
The task at hand is to develop a C program that simulates the Snake Game. The program should create a grid or screen where the snake and food are displayed. The player should be able to control the snake’s movement using keyboard inputs, and the snake should grow longer as it consumes food. The game should end if the snake collides with itself or hits the boundaries of the grid.
Program
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <termios.h> #include <unistd.h> #include <fcntl.h> #define WIDTH 20 #define HEIGHT 20 int score; bool gameover; int x, y, fruitX, fruitY; int tailX[100], tailY[100]; int nTail; enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN }; enum Direction dir; struct termios orig_termios; void DisableRawMode() { tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); } void EnableRawMode() { tcgetattr(STDIN_FILENO, &orig_termios); atexit(DisableRawMode); struct termios raw = orig_termios; raw.c_lflag &= ~(ECHO | ICANON); tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); } void Setup() { gameover = false; dir = STOP; x = WIDTH / 2; y = HEIGHT / 2; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; score = 0; } void Draw() { system("clear"); int i, j; for (i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { if (j == 0) printf("#"); if (i == y && j == x) printf("O"); else if (i == fruitY && j == fruitX) printf("F"); else { bool printTail = false; for (int k = 0; k < nTail; k++) { if (i == tailY[k] && j == tailX[k]) { printf("o"); printTail = true; } } if (!printTail) printf(" "); } if (j == WIDTH - 1) printf("#"); } printf("\n"); } for (i = 0; i < WIDTH + 2; i++) printf("#"); printf("\n"); printf("Score: %d\n", score); } void Input() { char c; if (read(STDIN_FILENO, &c, 1) == 1) { switch (c) { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameover = true; break; } } } void Logic() { int prevX = tailX[0]; int prevY = tailY[0]; int prev2X, prev2Y; tailX[0] = x; tailY[0] = y; for (int i = 1; i < nTail; i++) { prev2X = tailX[i]; prev2Y = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = prev2X; prevY = prev2Y; } switch (dir) { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; default: break; } if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) gameover = true; for (int i = 0; i < nTail; i++) { if (x == tailX[i] && y == tailY[i]) gameover = true; } if (x == fruitX && y == fruitY) { score += 10; fruitX = rand() % WIDTH; fruitY = rand() % HEIGHT; nTail++; } } int main() { EnableRawMode(); Setup(); while (!gameover) { Draw(); Input(); Logic(); usleep(100000); } return 0; }