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
|
# Specify the source files
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
main.c
|
main.c
|
||||||
#tetris.c
|
snake.c
|
||||||
#util.c
|
#util.c
|
||||||
#file3.c
|
#file3.c
|
||||||
)
|
)
|
||||||
@@ -24,4 +24,4 @@ target_compile_options(snake PUBLIC -std=c99 -Wall)
|
|||||||
|
|
||||||
# Used libraries
|
# 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