aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsonny <sonny@shady.money>2025-08-10 22:27:58 -0400
committersonny <sonny@shady.money>2025-08-10 22:27:58 -0400
commit5456927ef4f5b52f8ed48a76c0f95f9f282aba4c (patch)
tree51d6164c0e0e9811003df415dc3e654f4c9e1033
downloadsnake-5456927ef4f5b52f8ed48a76c0f95f9f282aba4c.tar.gz
snake-5456927ef4f5b52f8ed48a76c0f95f9f282aba4c.zip
src/snake.c: Create file and Make targets
-rw-r--r--src/Makefile23
-rw-r--r--src/snake.c266
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;
+}