Skip to content

Instantly share code, notes, and snippets.

@Lain62
Last active September 25, 2024 01:47
Show Gist options
  • Save Lain62/aed65ec3f2035749ae955343da73b078 to your computer and use it in GitHub Desktop.
Save Lain62/aed65ec3f2035749ae955343da73b078 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ncurses.h>
#define BOARDWIDTH 40
#define BOARDHEIGHT 20
#define SNAKEINITPOSX 10
#define SNAKEINITPOSY 10
#define DELAY 90
typedef enum {
LEFT,
RIGHT,
UP,
DOWN
} dir;
typedef struct {
int x;
int y;
} snakeCell;
typedef struct {
int x;
int y;
} foodCell;
typedef struct {
snakeCell *body;
size_t count;
size_t capacity;
} snakeBody;
snakeBody *createSnake() {
snakeBody *bodyTemp = malloc(sizeof(snakeBody));
snakeCell *cellTemp = malloc(sizeof(snakeCell));
if (bodyTemp == NULL || cellTemp == NULL) {
exit(127);
};
cellTemp[0].x = SNAKEINITPOSX;
cellTemp[0].y = SNAKEINITPOSY;
bodyTemp->body = cellTemp;
bodyTemp->count = 0;
bodyTemp->capacity = 0;
return bodyTemp;
}
void addSnakeBody(snakeBody *sBody, int x, int y) {
sBody->count += 1;
if (sBody->count >= sBody->capacity) {
if (sBody->capacity == 0)
sBody->capacity = 256;
else sBody->capacity *= 2;
sBody->body = realloc(sBody->body, sBody->capacity * sizeof(sBody->body));
}
sBody->body[sBody->count].x = x;
sBody->body[sBody->count].y = y;
}
void removeSnakeTail(snakeBody *body) {
for (int i = 0; i < body->count; i++) {
memmove(&body->body[i], &body->body[i+1], sizeof(snakeCell));
}
body->count -= 1;
}
void printSnakePos(snakeBody *body) {
for (int i = 0; i <= body->count; i++) {
printf(" [x: %d, y: %d] ", body->body[i].x, body->body[i].y);
}
printf("\n");
}
void genFood(foodCell *food) {
food->y = rand() % (BOARDHEIGHT - 2) + 1;
food->x = rand() % (BOARDWIDTH - 2) + 1;
}
void printFood(foodCell food) {
move(food.y, food.x);
addch('*');
}
void printSnake(snakeBody *snake) {
for (int i = 0; i < snake->count + 1; i++) {
move(snake->body[i].y, snake->body[i].x);
addch('O');
}
}
int main(void) {
bool is_running = true ;
dir current_dir = UP;
int ch;
snakeBody *snake = createSnake();
foodCell food = {0};
addSnakeBody(snake, snake->body[0].x, snake->body[snake->count].y - 1);
addSnakeBody(snake, snake->body[0].x, snake->body[snake->count].y - 1);
initscr();
curs_set(0);
refresh();
WINDOW *win = newwin(BOARDHEIGHT, BOARDWIDTH, 0, 0);
genFood(&food);
while(is_running) {
if (ch == 'x') {
is_running = false;
}
switch(ch) {
case 'a': {
if (current_dir != RIGHT)
current_dir = LEFT;
}; break;
case 'd': {
if (current_dir != LEFT)
current_dir = RIGHT;
}; break;
case 'w': {
if (current_dir != DOWN)
current_dir = UP;
}; break;
case 's': {
if (current_dir != UP)
current_dir = DOWN;
}; break;
}
switch(current_dir) {
case UP: {
if (snake->body[snake->count].y - 1 != 0)
addSnakeBody(snake, snake->body[snake->count].x, snake->body[snake->count].y - 1);
else
addSnakeBody(snake, snake->body[snake->count].x, BOARDHEIGHT - 1);
if (snake->body[snake->count].y - 1 == food.y && snake->body[snake->count].x == food.x)
genFood(&food);
else
removeSnakeTail(snake);
}; break;
case LEFT: {
if (snake->body[snake->count].x - 1 != 0)
addSnakeBody(snake, snake->body[snake->count].x - 1, snake->body[snake->count].y);
else
addSnakeBody(snake, BOARDWIDTH - 1, snake->body[snake->count].y);
if (snake->body[snake->count].y == food.y && snake->body[snake->count].x - 1 == food.x)
genFood(&food);
else
removeSnakeTail(snake);
}; break;
case RIGHT: {
if (snake->body[snake->count].x + 1 != BOARDWIDTH - 1)
addSnakeBody(snake, snake->body[snake->count].x + 1, snake->body[snake->count].y);
else
addSnakeBody(snake, 1, snake->body[snake->count].y);
if (snake->body[snake->count].y == food.y && snake->body[snake->count].x + 1 == food.x)
genFood(&food);
else
removeSnakeTail(snake);
}; break;
case DOWN: {
if (snake->body[snake->count].y + 1 != BOARDHEIGHT - 1)
addSnakeBody(snake, snake->body[snake->count].x, snake->body[snake->count].y + 1);
else
addSnakeBody(snake, snake->body[snake->count].x, 1);
if (snake->body[snake->count].y + 1 == food.y && snake->body[snake->count].x == food.x)
genFood(&food);
else
removeSnakeTail(snake);
}; break;
}
move(getmaxy(win), 0);
printw("Press x to quit");
refresh();
box(win, 0, 0);
wrefresh(win);
printFood(food);
printSnake(snake);
refresh();
timeout(DELAY);
ch = getch();
clear();
}
delwin(win);
endwin();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment