Files
Snake/snake.c
T
2025-07-29 14:28:00 +02:00

161 lines
3.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ncurses.h>
#include "snake.h"
#define WIDTH 20
#define HEIGHT 20
typedef struct {
int x;
int y;
} Point;
typedef struct {
Point body[100]; // Maximum length of the snake
int length;
} Snake;
Point food;
Snake snake;
int direction; // 0: UP, 1: DOWN, 2: LEFT, 3: RIGHT
void setup() {
snake.length = 1;
snake.body[0].x = WIDTH / 2;
snake.body[0].y = HEIGHT / 2;
direction = 3; // Start moving to the right
generateFood();
}
void draw() {
clear(); // Clear the screen
for (int i = 0; i < WIDTH + 2; i++)
printw("#");
printw("\n");
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if (j == 0)
printw("#"); // Left wall
if (i == food.y && j == food.x)
printw("*"); // Food
else {
int isSnakePart = 0;
for (int k = 0; k < snake.length; k++) {
if (snake.body[k].x == j && snake.body[k].y == i) {
printw("O"); // Snake body
isSnakePart = 1;
}
}
if (!isSnakePart)
printw(" ");
}
if (j == WIDTH - 1)
printw("#"); // Right wall
}
printw("\n");
}
for (int i = 0; i < WIDTH + 2; i++)
printw("#");
printw("\n");
refresh(); // Refresh the screen to show changes
}
void input() {
keypad(stdscr, TRUE); // Enable special keys
halfdelay(1); // Wait for input for a short time
int ch = getch();
switch (ch) {
case KEY_UP:
if (direction != 1) direction = 0; // Up
break;
case KEY_DOWN:
if (direction != 0) direction = 1; // Down
break;
case KEY_LEFT:
if (direction != 3) direction = 2; // Left
break;
case KEY_RIGHT:
if (direction != 2) direction = 3; // Right
break;
}
}
void logic() {
Point prevSegment = snake.body[0];
Point prev2Segment;
// Update the head of the snake based on the direction
switch (direction) {
case 0: // UP
snake.body[0].y--;
break;
case 1: // DOWN
snake.body[0].y++;
break;
case 2: // LEFT
snake.body[0].x--;
break;
case 3: // RIGHT
snake.body[0].x++;
break;
}
// Update the body segments
for (int i = 1; i < snake.length; i++) {
prev2Segment = snake.body[i];
snake.body[i] = prevSegment;
prevSegment = prev2Segment;
}
// Check if the snake has eaten the food
if (snake.body[0].x == food.x && snake.body[0].y == food.y) {
snake.length++;
generateFood(); // Generate new food
}
}
void generateFood() {
int validPosition = 0;
while (!validPosition) {
food.x = rand() % WIDTH;
food.y = rand() % HEIGHT;
// Check if the food position overlaps with the snake
validPosition = 1; // Assume valid until proven otherwise
for (int i = 0; i < snake.length; i++) {
if (snake.body[i].x == food.x && snake.body[i].y == food.y) {
validPosition = 0; // Found overlap, need to generate again
break;
}
}
}
}
int gameOver() {
// Check for wall collisions
if (snake.body[0].x < 0 || snake.body[0].x >= WIDTH ||
snake.body[0].y < 0 || snake.body[0].y >= HEIGHT) {
return 1; // Game over due to wall collision
}
// Check for self-collision
for (int i = 1; i < snake.length; i++) {
if (snake.body[i].x == snake.body[0].x &&
snake.body[i].y == snake.body[0].y) {
return 1; // Game over due to self-collision
}
}
return 0; // Game is still running
}