Snake
This commit is contained in:
1 parent
d0a1e9e8ab
commit
4ec6b7993c
4 files changed
+214
-2
No files matched your search
+2
-2
@@ -5,7 +5,7 @@ project(snake)
|
||||
# Specify the source files
|
||||
set(SOURCES
|
||||
main.c
|
||||
#tetris.c
|
||||
snake.c
|
||||
#util.c
|
||||
#file3.c
|
||||
)
|
||||
@@ -24,4 +24,4 @@ target_compile_options(snake PUBLIC -std=c99 -Wall)
|
||||
|
||||
# Used libraries
|
||||
|
||||
#target_link_libraries(tetris PUBLIC ncurses SDL2 SDL2_mixer)
|
||||
target_link_libraries(snake PUBLIC ncurses)
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
srand(time(NULL)); // Seed for random number generation
|
||||
initscr(); // Initialize ncurses
|
||||
noecho(); // Don't echo pressed keys
|
||||
curs_set(0); // Hide the cursor
|
||||
setup();
|
||||
|
||||
while (!gameOver()) {
|
||||
draw();
|
||||
input();
|
||||
logic();
|
||||
usleep(100000); // Sleep for a short duration
|
||||
}
|
||||
|
||||
endwin(); // End ncurses mode
|
||||
printf("Game Over!\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ncurses.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("F"); // 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
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/***************************************************************************//**
|
||||
|
||||
@file snake.h
|
||||
|
||||
@author Jiri Stach
|
||||
|
||||
@date Created $date
|
||||
|
||||
@brief Snake game declarations.
|
||||
|
||||
@copyright Copyright (c), Jiri Stach. Released under the Revised
|
||||
BSD License. See LICENSE.txt for details.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SNAKE_H
|
||||
#define SNAKE_H
|
||||
|
||||
|
||||
void setup();
|
||||
void draw();
|
||||
void input();
|
||||
void logic();
|
||||
void generateFood();
|
||||
int gameOver();
|
||||
|
||||
|
||||
|
||||
#endif // SNAKE_H
|
||||
Reference in new issue
Block a user