diff options
| author | sonny <sonny@shady.money> | 2025-08-10 22:27:58 -0400 |
|---|---|---|
| committer | sonny <sonny@shady.money> | 2025-08-10 22:27:58 -0400 |
| commit | 5456927ef4f5b52f8ed48a76c0f95f9f282aba4c (patch) | |
| tree | 51d6164c0e0e9811003df415dc3e654f4c9e1033 | |
| download | snake-5456927ef4f5b52f8ed48a76c0f95f9f282aba4c.tar.gz snake-5456927ef4f5b52f8ed48a76c0f95f9f282aba4c.zip | |
src/snake.c: Create file and Make targets
| -rw-r--r-- | src/Makefile | 23 | ||||
| -rw-r--r-- | src/snake.c | 266 |
2 files changed, 289 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..231f6b0 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,23 @@ +# +# Main Config +# + +CC = gcc +CFLAGS = -std=c99 -Wall -s -O2 -pedantic +LDFLAGS = -lraylib + +SRC = snake.c +OBJ = ${SRC:.c=.o} +TARGET = snake + +all: ${TARGET} + +$(TARGET): $(OBJ) + $(CC) $(CFLAGS) $(OBJ) -o $@ $(LDFLAGS) + +clean: + rm -f ${OBJ} ${TARGET} + +.DEFAULT_GOAL: all + +.PHONY: clean diff --git a/src/snake.c b/src/snake.c new file mode 100644 index 0000000..240d732 --- /dev/null +++ b/src/snake.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: MIT +// Written by: Sonny X. <sonny@shady.money> +#include <stdlib.h> +#include <raylib.h> + +/* Constants */ +#define GRID_SZ_DEFAULT 24 +#define SCREEN_SZ_DEFAULT (GRID_SZ_DEFAULT * GRID_SZ_DEFAULT) +#define COLOR_BG (Color){199.f, 217.f, 240.f, 255.f} +#define COLOR_FG (Color){61.f, 70.f, 82.f, 255.f} +#define SNAKE_MAX 1 +#define FOOD_MAX 1 +#define SNAKE_SZ_DEFAULT 4 +#define SNAKE_GAME_SPEED 12 + +typedef struct { + int x; + int y; +} food_t; +food_t *new_food(void); +void food_move(food_t *, int, int); +void food_update(food_t *); +void food_draw(food_t *); + +food_t *food[FOOD_MAX]; + +typedef struct { + int x[SCREEN_SZ_DEFAULT]; + int y[SCREEN_SZ_DEFAULT]; + + int dir_x, dir_y; + int score; + + int dead; // n = 0 == dead! +} snake_t; +snake_t *new_snake(void); +void snake_move(snake_t *, int, int); +void snake_update(snake_t *); +void snake_draw(snake_t *); + +snake_t *snake[SNAKE_MAX]; + +food_t *new_food(void) +{ + food_t *f = malloc(sizeof(snake_t)); + + if (!f) + return (void *)0; + + f->x = 15; + f->y = 10; + + return f; +} + +void food_move(food_t *f, int x, int y) +{ + f->x = x; + f->y = y; +} + +void food_update(food_t *f) +{ + int rx, ry; + + rx = rand() % GRID_SZ_DEFAULT; + ry = rand() % GRID_SZ_DEFAULT; + + food_move(f, rx, ry); +} + +void food_draw(food_t *f) +{ + DrawRectangle(f->x * GRID_SZ_DEFAULT, f->y * GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, GRID_SZ_DEFAULT, COLOR_FG); +} + +snake_t *new_snake(void) +{ + snake_t *s = malloc(sizeof(snake_t)); + + if (!s) + return (void *)0; + + s->x[0] = 5; + s->y[0] = 10; + + s->dir_x = 1; + s->dir_y = 0; + s->score = 4; + + s->dead = 0; + + return s; +} + +void snake_move(snake_t *s, int dir_x, int dir_y) +{ + if (dir_x == 1) { + if (s->dir_x == -1) { + return; + } + } + if (dir_y == 1) { + if (s->dir_y == -1) { + return; + } + } + if (dir_x == -1) { + if (s->dir_x == 1) { + return; + } + } + if (dir_y == -1) { + if (s->dir_y == 1) { + return; + } + } + + s->dir_x = dir_x; + s->dir_y = dir_y; +} + +void snake_update(snake_t *s) +{ + int k; + + if (s->dead) + return; + + k = GetKeyPressed(); + switch (k) { + case KEY_D: + snake_move(s, 1, 0); + break; + case KEY_S: + snake_move(s, 0, 1); + break; + case KEY_A: + snake_move(s, -1, 0); + break; + case KEY_W: + snake_move(s, 0, -1); + break; + } + + for (int i = s->score - 1; i > 0; i--) { + s->x[i] = s->x[i - 1]; + s->y[i] = s->y[i - 1]; + } + + s->x[0] += s->dir_x; + s->y[0] += s->dir_y; + + for (int i = 1; i < s->score; i++) { + if (s->x[0] == s->x[i] && s->y[0] == s->y[i]) { + s->dead = 1; + } + } + + if (s->x[0] > (GRID_SZ_DEFAULT-1) || s->y[0] > (GRID_SZ_DEFAULT-1)) + s->dead = 1; + if (s->x[0] < 0 || s->y[0] < 0) + s->dead = 1; +} + +void snake_draw(snake_t *s) +{ + if (!s) + return; + + for (int i = 0; i < s->score; i++) { + DrawRectangle(s->x[i] * GRID_SZ_DEFAULT, + s->y[i] * GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, + COLOR_FG); + } +} + +void __update(void); +void __draw(void); +void __init(void); +void __exit(void); +void __loop(void); + +void __update(void) +{ + for (int i = 0; i < SNAKE_MAX; i++) { + snake_update(snake[i]); + } + + if (snake[0]->x[0] == food[0]->x && snake[0]->y[0] == food[0]->y) { + snake[0]->score++; + food_update(food[0]); + } +} + +void __draw(void) +{ + BeginDrawing(); + ClearBackground(COLOR_BG); + + for (int i = 0; i < SNAKE_MAX; i++) { + snake_draw(snake[i]); + } + + for (int i = 0; i < FOOD_MAX; i++) { + food_draw(food[i]); + } + + DrawText(TextFormat("%d", (snake[0]->score - SNAKE_SZ_DEFAULT)), + GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, + COLOR_FG); + + if (snake[0]->dead) { + DrawText("game over", + GRID_SZ_DEFAULT, + 2 * GRID_SZ_DEFAULT, + GRID_SZ_DEFAULT, + COLOR_FG); + } + + EndDrawing(); +} + +void __init(void) +{ + ClearWindowState(FLAG_WINDOW_RESIZABLE); + InitWindow(SCREEN_SZ_DEFAULT, SCREEN_SZ_DEFAULT, "Snake"); + SetTargetFPS(SNAKE_GAME_SPEED); + + snake[0] = new_snake(); + food[0] = new_food(); +} + +void __exit(void) +{ + for (int i = 0; i < FOOD_MAX; i++) { + free(food[i]); + } + + for (int i = 0; i < SNAKE_MAX; i++) { + free(snake[i]); + } + + CloseWindow(); +} + +void __loop(void) +{ + __init(); + do { + __update(); + __draw(); + } while (!WindowShouldClose()); + __exit(); +} + +int main(void) +{ + __loop(); + return 0; +} |
