From 4b03b40aeb469f5491b2d3de11358c622d8214d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Vl=C4=8Dek?= Date: Wed, 15 Apr 2026 23:11:02 +0000 Subject: [PATCH] re-add du4 --- du4/snake.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 du4/snake.c diff --git a/du4/snake.c b/du4/snake.c new file mode 100644 index 0000000..881f20b --- /dev/null +++ b/du4/snake.c @@ -0,0 +1,144 @@ +#include "snake.h" +#include +#include + +struct snake* add_snake(struct snake* snake,int x,int y) +{ + //vytvori novu prazdnu instanciu a alokujee jej pamat + struct snake* newSnake = (struct snake*)malloc(sizeof(struct snake)); + //prida X,Y suradnice do polia do novej hlavicky + newSnake->x = x; + newSnake->y = y; + + //nalinkuje ju na staru hlavicku + newSnake->next = snake; + + return newSnake; +} + +struct snake* remove_snake(struct snake* snake){ + + struct snake* currentPtr = snake; + struct snake* prevPtr; + + if (snake == NULL) + { + return NULL; + } + while (1) + { + //pomocny pointer -> ulozenie predoslej casti/node-u + prevPtr = currentPtr; + //skontroluje, ze ci dalsia cast je PRAZDNA. + if (currentPtr->next == NULL) + { + //uprava listu -> odlinkje tuto cast (tak aby prevPtr->next NEFERENCOVAL na uz uvolnenu cast) + prevPtr->next = NULL; + //uvolni pamat pre akt. cast (uvolni pamat) + free(currentPtr); + break; + } + //iteruj ku dalsiej casti (node) + currentPtr = currentPtr->next; + } + return snake; +} + +void free_snake(struct snake* sn) +{ + //pomocna smernikova premenna + struct snake* currentPtr = sn; + while (currentPtr != NULL) + { + //uloz dalsiu cast, zmaz aktualnu a posun sa na dalsiu + struct snake* nextPtr = currentPtr->next; + free(currentPtr); + currentPtr = nextPtr; + } +} + +int is_snake(struct snake* snake,int x,int y){ + + //helper pointer/smernikova premena + struct snake* currentPtr = snake; + + //iteracia cez vsetky casti az dokial sa nenajde cast/node s rovnakymi X,Y suradncami + while (currentPtr != NULL) + { + if (currentPtr->x == x && currentPtr->y == y) + { + return 1; + } + //prejde/iteruje na dalsiu cast + currentPtr = currentPtr->next; + } + return 0; +} + +/* Funguje na zaklade viacerych faz, ktore sa opakuju kazdy cyklus + FAZY: 1. -> Kontrola kolizie (seba + vs. stien) + 2. -> Kontrola logiky zobratia jedla (resp. kolizie s jedlom, update statusu, pripadny narast hada) + 3. -> Realizacia pohybu + 4. -> finalna kontrola poctu jedla */ +int step_state(struct state* st){ + int nx = (st->snake->x + st->sx); + int ny = (st->snake->y + st->sy); + + //helper lok. premena na kontrolovanie, ci uz jedlo bolo zjedene v tomto update cykle + bool hasEatenFoodinThisCycle = false; + + //** 1. faza + //ak je snake (nejak) mimo hracieho pola: + if (nx < 0 || ny < 0) + { + return END_WALL; + } + //vrati END_WALL, ak had narazi do steny (a jeho X,Y suradnice su mimo hrac. polia) + if (nx >= st->height || ny >= st->width) + { + return END_WALL; + } + + //** kontrola seba kolizie + if (is_snake(st->snake, nx, ny)) { return END_SNAKE;} + + //** 2. faza kontroly (zobratia) jedla: + for (int i = 0; i < FOOD_COUNT; i++) + { + //zoberie jedlo (AK sa X,Y suradnice rovnaju) + if (st->foodx[i] == nx && st->foody[i] == ny) + { + //updatne stav/state hry (-1 stav signalizuje, ze jedlo bolo uz zobrate) + st->foodx[i] = -1; + st->foody[i] = -1; + + add_snake(st->snake, nx, ny); + + hasEatenFoodinThisCycle = true; + + break; + } + //hra bude pokracovat normalne dalej, ak NIE JE vsetko jedlo zobrate + if (st->foodx[i] != -1) + { + return END_CONTINUE; + } + } + + //normalny pohyb snake-a (ak jedlo nebolo zjedene v tomto update cykle) + if (!hasEatenFoodinThisCycle) + { + st->snake = add_snake(st->snake, nx, ny); + st->snake = remove_snake(st->snake); + } + + //faza kontrola poctu jedla + for (int i = 0; i < FOOD_COUNT; i++) + { + if (st->foodx[i] != -1) + { + return END_CONTINUE; + } + } + return END_FOOD; +} \ No newline at end of file