snek time

This commit is contained in:
2024-12-23 22:38:16 +03:00
parent e58094787f
commit 6dafffb522
3 changed files with 274 additions and 8 deletions

228
snake/snek.c Normal file
View File

@@ -0,0 +1,228 @@
#include <raylib.h>
#include <stdlib.h>
#include <stdio.h>
/* typedef struct map_t { */
/* } Map; */
const int screenHeight = 800;
const int screenWidth = 800;
int fps = 60;
int rows = 10;
int cols = 10;
int size;
int food_x;
int food_y;
int score = 0;
char score_text[16] = "0";
typedef enum directions {
UP,
DOWN,
LEFT,
RIGHT
} Direction;
typedef struct snake_body {
int x;
int y;
} SnakeBody;
typedef struct snake_t {
SnakeBody *body;
int max_length;
int length;
int direction;
int frame_duration;
bool alive;
} Snake;
Snake make_snake(int max_len, int speed){
Snake snek;
if (max_len < 3){
snek.alive = false;
snek.length = 0;
return snek;
}
snek.body = (SnakeBody*) calloc(max_len, sizeof(SnakeBody));
snek.max_length = max_len;
snek.length = 3;
snek.body[0].x = GetRandomValue(0, cols - 1);
snek.body[0].y = GetRandomValue(0, rows - 1);
snek.frame_duration = fps / speed;
snek.direction = snek.body[0].x < cols / 2 ? RIGHT : LEFT;
snek.alive = true;
snek.body[1] = snek.body[2] = snek.body[0];
snek.body[1].x += snek.direction == LEFT ? 1 : -1;
snek.body[2].x += snek.direction == LEFT ? 2 : -2;
return snek;
}
void free_snake(Snake* s){
free(s->body);
}
void grow_snake(Snake* s){
int i = s->length;
if (i < s->max_length){
s->body[i] = (SnakeBody) {
2 * s->body[i - 1].x - s->body[i - 2].x,
2 * s->body[i - 1].y - s->body[i - 2].y
};
s->length++;
}
}
void draw_snake(Snake* s){
for (int i = 0; i < s->length; i++){
DrawRectangle(size * s->body[i].x, size * s->body[i].y, size, size, BLACK);
}
return ;
}
bool collides_with_snake(Snake* s, int x, int y){
for (int i = 0; i < s->length; i++){
if (s->body[i].x == x && s->body[i].y == y){
return true;
}
}
return false;
}
void place_food(Snake* s){
do {
food_x = GetRandomValue(0, cols - 1);
food_y = GetRandomValue(0, rows - 1);
} while (collides_with_snake(s, food_x, food_y));
}
void move_snake(Snake* s){
SnakeBody temp1 = s->body[0];
SnakeBody temp2;
switch (s->direction){
case LEFT:
s->body[0].x--;
if (s->body[0].x < 0 || s->body[0].x >= cols){
s->alive = false;
}
break;
case RIGHT:
s->body[0].x++;
if (s->body[0].x < 0 || s->body[0].x >= cols){
s->alive = false;
}
break;
case UP:
s->body[0].y--;
if (s->body[0].y < 0 || s->body[0].y >= rows){
s->alive = false;
}
break;
case DOWN:
s->body[0].y++;
if (s->body[0].x < 0 || s->body[0].y >= rows){
s->alive = false;
}
break;
}
for (int i = 1; i < s->length; i++){
if (s->body[0].x == s->body[i].x &&
s->body[0].y == s->body[i].y){
s->alive = false;
break;
}
temp2 = s->body[i];
s->body[i] = temp1;
temp1 = temp2;
}
}
/* int frame = 0; */
void update_snake(Snake* s){
static int frame = 0;
if (frame++ > s->frame_duration){
move_snake(s);
frame = 0;
}
int key;
while ((key = GetKeyPressed()) != 0){
switch (key){
case KEY_W:
s->direction = UP;
break;
case KEY_A:
s->direction = LEFT;
break;
case KEY_S:
s->direction = DOWN;
break;
case KEY_D:
s->direction = RIGHT;
break;
case KEY_G:
grow_snake(s);
}
}
if (collides_with_snake(s, food_x, food_y)){
food_x = food_y = -1;
score++;
snprintf(score_text, 16, "%d", score);
grow_snake(s);
place_food(s);
}
}
void draw_grid(int size){
/* DrawGrid(10, screenWidth / 10); */
for (int i = 0; i < rows; i++){
DrawLine(0, i * size, screenWidth, i * size, BLACK);
}
for (int j = 0; j < cols; j++){
DrawLine(j * size, 0, j * size, screenHeight, BLACK);
}
}
void init_game(){
InitWindow(screenHeight, screenHeight, "Snek");
SetTargetFPS(fps);
int width = screenWidth / cols;
int height = screenHeight / rows;
size = height > width ? width : height;
}
int main(void){
init_game();
Snake snek = make_snake(100, 5);
while (!WindowShouldClose()){
BeginDrawing();
ClearBackground(WHITE);
draw_grid(size);
if (snek.alive){
update_snake(&snek);
} else {
DrawText("Died!", screenWidth / 2, screenHeight / 2, 20, BLACK);
}
if (food_x >= 0){
DrawRectangle(size * food_x, size * food_y, size, size, RED);
}
draw_snake(&snek);
DrawText(score_text, 0, 0, 20, BLACK);
EndDrawing();
}
free_snake(&snek);
CloseWindow();
return 0;
}