Last active
September 25, 2024 01:47
-
-
Save Lain62/aed65ec3f2035749ae955343da73b078 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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