0% found this document useful (0 votes)
14 views10 pages

Snake Game

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views10 pages

Snake Game

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

#include <stdio.

h>

#include <stdlib.h>

#include <termios.h>

#include <unistd.h>

#include <time.h>

#include <string.h>

#include <fcntl.h>

#define HEIGHT 20

#define WIDTH 60

#define MAX_TAIL_LENGTH (WIDTH * HEIGHT)

typedef enum { UP, DOWN, LEFT, RIGHT, STOP } Direction;

typedef enum { EASY, MEDIUM, HARD, EXTREME } Difficulty;

typedef struct {

Direction dir;

int score;

int fruit_x, fruit_y;

int head_x, head_y;

int tail_length;

int tail_x[MAX_TAIL_LENGTH];

int tail_y[MAX_TAIL_LENGTH];

Difficulty difficulty;

int base_speed;

int min_speed;

int current_speed;

} GameState;

GameState game;

struct termios old_props;


// Function prototypes

void setup();

void clear_screen();

void draw();

void input();

void game_play();

void set_terminal_attributes();

void reset_terminal_attributes();

int input_available();

int is_position_free(int x, int y);

void show_menu();

void init_difficulty(Difficulty diff);

// Terminal setup for non-blocking input

void set_terminal_attributes() {

tcgetattr(STDIN_FILENO, &old_props);

struct termios new_props = old_props;

new_props.c_lflag &= ~(ICANON | ECHO);

tcsetattr(STDIN_FILENO, TCSANOW, &new_props);

fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);

void reset_terminal_attributes() {

tcsetattr(STDIN_FILENO, TCSANOW, &old_props);

int input_available() {

fd_set set;

struct timeval timeout;


FD_ZERO(&set);

FD_SET(STDIN_FILENO, &set);

timeout.tv_sec = 0;

timeout.tv_usec = 0;

return select(STDIN_FILENO + 1, &set, NULL, NULL, &timeout) > 0;

void clear_screen() {

printf("\033[H\033[J");

int is_position_free(int x, int y) {

if (x == game.head_x && y == game.head_y)

return 0;

for (int i = 0; i < game.tail_length; i++)

if (game.tail_x[i] == x && game.tail_y[i] == y)

return 0;

return 1;

void show_menu() {

clear_screen();

printf("\n\t\tWelcome to The Snake Game!\n\n");

printf("\tChoose difficulty:\n");

printf("\t1. Easy (Slow speed)\n");

printf("\t2. Medium (Balanced speed)\n");

printf("\t3. Hard (Fast speed)\n");

printf("\t4. Extreme (Very fast)\n\n");

printf("\tPress Q to quit\n");

while (1) {
while (!input_available());

char choice = getchar();

switch (choice) {

case '1': init_difficulty(EASY); return;

case '2': init_difficulty(MEDIUM); return;

case '3': init_difficulty(HARD); return;

case '4': init_difficulty(EXTREME); return;

case 'q': case 'Q': exit(0);

void init_difficulty(Difficulty diff) {

game.difficulty = diff;

switch (diff) {

case EASY:

game.base_speed = 250000;

game.min_speed = 100000;

break;

case MEDIUM:

game.base_speed = 180000;

game.min_speed = 60000;

break;

case HARD:

game.base_speed = 120000;

game.min_speed = 40000;

break;

case EXTREME:

game.base_speed = 100000;

game.min_speed = 30000;

break;
}

game.current_speed = game.base_speed;

void setup() {

game.head_x = WIDTH / 2;

game.head_y = HEIGHT / 2;

game.dir = STOP;

game.score = 0;

game.tail_length = 0;

do {

game.fruit_x = rand() % WIDTH;

game.fruit_y = rand() % HEIGHT;

} while (!is_position_free(game.fruit_x, game.fruit_y));

game.current_speed = game.base_speed;

void draw() {

clear_screen();

printf("\t\tSnake Game - ");

switch (game.difficulty) {

case EASY: printf("Easy"); break;

case MEDIUM: printf("Medium"); break;

case HARD: printf("Hard"); break;

case EXTREME: printf("Extreme"); break;

printf("\n");

if (game.dir == STOP)
printf("\t\tPAUSED (Press SPACE to resume)\n");

for (int i = 0; i < WIDTH + 2; i++) printf("#");

printf("\n");

for (int i = 0; i < HEIGHT; i++) {

printf("#");

for (int j = 0; j < WIDTH; j++) {

if (i == game.head_y && j == game.head_x) {

printf("O");

} else if (i == game.fruit_y && j == game.fruit_x) {

printf("F");

} else {

int printed = 0;

for (int k = 0; k < game.tail_length; k++) {

if (game.tail_x[k] == j && game.tail_y[k] == i) {

printf("o");

printed = 1;

break;

if (!printed) printf(" ");

printf("#\n");

for (int i = 0; i < WIDTH + 2; i++) printf("#");

printf("\nScore: %d | Speed: %dms\n", game.score, game.current_speed / 1000);

printf("Controls: WASD = Move | SPACE = Pause | M = Menu | X = Exit\n");

}
void input() {

static Direction last_dir = RIGHT;

if (input_available()) {

char ch = getchar();

switch (ch) {

case 'a': case 'A':

if (game.dir != RIGHT) game.dir = LEFT;

break;

case 's': case 'S':

if (game.dir != UP) game.dir = DOWN;

break;

case 'd': case 'D':

if (game.dir != LEFT) game.dir = RIGHT;

break;

case 'w': case 'W':

if (game.dir != DOWN) game.dir = UP;

break;

case 'x': case 'X':

reset_terminal_attributes();

exit(0);

break;

case ' ':

if (game.dir == STOP) {

game.dir = last_dir;

} else {

last_dir = game.dir;

game.dir = STOP;

break;
case 'm': case 'M':

show_menu();

setup();

break;

void game_play() {

if (game.dir == STOP) return;

for (int i = game.tail_length - 1; i > 0; i--) {

game.tail_x[i] = game.tail_x[i - 1];

game.tail_y[i] = game.tail_y[i - 1];

if (game.tail_length > 0) {

game.tail_x[0] = game.head_x;

game.tail_y[0] = game.head_y;

switch (game.dir) {

case UP: game.head_y--; break;

case DOWN: game.head_y++; break;

case LEFT: game.head_x--; break;

case RIGHT: game.head_x++; break;

default: break;

if (game.head_x < 0) game.head_x = WIDTH - 1;

if (game.head_x >= WIDTH) game.head_x = 0;

if (game.head_y < 0) game.head_y = HEIGHT - 1;


if (game.head_y >= HEIGHT) game.head_y = 0;

for (int i = 0; i < game.tail_length; i++) {

if (game.tail_x[i] == game.head_x && game.tail_y[i] == game.head_y) {

printf("\nGame Over! Final score: %d\n", game.score);

reset_terminal_attributes();

exit(0);

if (game.head_x == game.fruit_x && game.head_y == game.fruit_y) {

game.score += 10;

game.tail_length++;

do {

game.fruit_x = rand() % WIDTH;

game.fruit_y = rand() % HEIGHT;

} while (!is_position_free(game.fruit_x, game.fruit_y));

int main() {

srand(time(NULL));

set_terminal_attributes();

atexit(reset_terminal_attributes);

show_menu();

setup();

while (1) {

draw();
input();

game_play();

int target_speed = game.base_speed - (game.score * 3000);

if (target_speed < game.min_speed) target_speed = game.min_speed;

game.current_speed = target_speed;

usleep(game.current_speed);

You might also like