diff --git a/du5/snake.c b/du5/snake.c new file mode 100644 index 0000000..82ec194 --- /dev/null +++ b/du5/snake.c @@ -0,0 +1,87 @@ +#include "snake.h" +#include + +struct snake* add_snake(struct snake* head, int x, int y) { + struct snake* node = (struct snake*)malloc(sizeof(struct snake)); + if (!node) return NULL; + + node->x = x; + node->y = y; + node->next = head; + return node; +} + +struct snake* remove_snake(struct snake* head) { + if (!head) return NULL; + if (!head->next) { + free(head); + return NULL; + } + + struct snake* current = head; + while (current->next && current->next->next) { + current = current->next; + } + + free(current->next); + current->next = NULL; + return head; +} + +void free_snake(struct snake* head) { + while (head) { + struct snake* temp = head; + head = head->next; + free(temp); + } +} + +int is_snake(struct snake* head, int x, int y) { + struct snake* temp = head; + while (temp) { + if (temp->x == x && temp->y == y) { + return 1; + } + temp = temp->next; + } + return 0; +} + +int step_state(struct state* st) { + int new_x = st->snake->x + st->sx; + int new_y = st->snake->y + st->sy; + + // Collision with walls + if (new_x < 0 || new_y < 0 || new_x >= st->width || new_y >= st->height) { + return END_WALL; + } + + // Collision with itself + if (is_snake(st->snake, new_x, new_y)) { + return END_SNAKE; + } + + // Check food collision + for (int i = 0; i < FOOD_COUNT; ++i) { + if (st->foodx[i] == new_x && st->foody[i] == new_y) { + st->foodx[i] = -1; + st->foody[i] = -1; + st->snake = add_snake(st->snake, new_x, new_y); + + int food_remaining = 0; + for (int j = 0; j < FOOD_COUNT; ++j) { + if (st->foodx[j] >= 0 && st->foody[j] >= 0) { + food_remaining = 1; + break; + } + } + + return food_remaining ? END_CONTINUE : END_FOOD; + } + } + + // Normal move: add head, remove tail + st->snake = add_snake(st->snake, new_x, new_y); + st->snake = remove_snake(st->snake); + return END_CONTINUE; +}