From 1478f37cb08d18390a04f38f2394848308d1c1ab Mon Sep 17 00:00:00 2001 From: Miloslav Macko Date: Thu, 18 Apr 2024 17:07:21 +0200 Subject: [PATCH] 123 --- a2/snake.c | 165 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 54 deletions(-) diff --git a/a2/snake.c b/a2/snake.c index 68a34ae..9d58be1 100644 --- a/a2/snake.c +++ b/a2/snake.c @@ -2,41 +2,133 @@ #include #include -// Inicializuje stav hry +#define FOOD_COUNT 3 +#define MAX_SNAKE_LENGTH 100 + +// Define the direction constants +#define UP 0 +#define LEFT 1 +#define DOWN 2 +#define RIGHT 3 + +struct state { + int width; + int height; + int snake_length; + int snake_x[MAX_SNAKE_LENGTH]; + int snake_y[MAX_SNAKE_LENGTH]; + int foodx[FOOD_COUNT]; + int foody[FOOD_COUNT]; + int sx; + int sy; +}; + +// Function prototypes +void init_state(struct state* state, int width, int height); +void draw_state(struct state* state); +void process_input(struct state* state); +int step_state(struct state* state); +void generate_food(struct state* state); +int is_snake(struct state* state, int x, int y); +void free_snake(struct state* state); + +// Add a new segment to the snake +void add_snake(struct state* state, int x, int y) { + state->snake_x[state->snake_length] = x; + state->snake_y[state->snake_length] = y; + state->snake_length++; +} + +// Check if the given position is occupied by the snake +int is_snake(struct state* state, int x, int y) { + for (int i = 0; i < state->snake_length; i++) { + if (state->snake_x[i] == x && state->snake_y[i] == y) { + return 1; + } + } + return 0; +} + +// Free the memory allocated for the snake +void free_snake(struct state* state) { + // No dynamic memory allocation for the snake in this implementation +} + +// Move the snake by one step +int step_state(struct state* state) { + // Move the snake body + for (int i = state->snake_length - 1; i > 0; i--) { + state->snake_x[i] = state->snake_x[i - 1]; + state->snake_y[i] = state->snake_y[i - 1]; + } + + // Move the snake head + state->snake_x[0] += state->sx; + state->snake_y[0] += state->sy; + + // Check for collisions with walls + if (state->snake_x[0] < 0 || state->snake_x[0] >= state->width || + state->snake_y[0] < 0 || state->snake_y[0] >= state->height) { + return 1; // Collision with wall + } + + // Check for collisions with itself + for (int i = 1; i < state->snake_length; i++) { + if (state->snake_x[i] == state->snake_x[0] && state->snake_y[i] == state->snake_y[0]) { + return 2; // Collision with itself + } + } + + // Check for collisions with food + for (int i = 0; i < FOOD_COUNT; i++) { + if (state->snake_x[0] == state->foodx[i] && state->snake_y[0] == state->foody[i]) { + // Increase the snake length + state->snake_length++; + if (state->snake_length >= MAX_SNAKE_LENGTH) { + return 3; // Snake length exceeds the maximum + } + // Move the food to a new random position + state->foodx[i] = rand() % state->width; + state->foody[i] = rand() % state->height; + return 0; // Food eaten + } + } + + return 0; // No collision +} + void init_state(struct state* state, int width, int height) { state->width = width; state->height = height; - state->snake = add_snake(NULL, width / 2, height / 2); + state->snake_length = 1; + state->snake_x[0] = width / 2; + state->snake_y[0] = height / 2; state->sx = 0; - state->sy = 1; - for(int i = 0; i < FOOD_COUNT; i++) { + state->sy = -1; // Start moving upward + for (int i = 0; i < FOOD_COUNT; i++) { state->foodx[i] = rand() % width; state->foody[i] = rand() % height; } } -// Generuje nové jedlo na náhodnej pozícii void generate_food(struct state* state) { - for(int i = 0; i < FOOD_COUNT; i++) { - if(state->foodx[i] == -1) { - do { - state->foodx[i] = rand() % state->width; - state->foody[i] = rand() % state->height; - } while(is_snake(state->snake, state->foodx[i], state->foody[i])); - } + for (int i = 0; i < FOOD_COUNT; i++) { + state->foodx[i] = rand() % state->width; + state->foody[i] = rand() % state->height; } } -// Vykresli stav hry void draw_state(struct state* state) { - for(int y = 0; y < state->height; y++) { - for(int x = 0; x < state->width; x++) { - if(is_snake(state->snake, x, y)) { - printf("S"); + for (int y = 0; y < state->height; y++) { + for (int x = 0; x < state->width; x++) { + if (x == state->snake_x[0] && y == state->snake_y[0]) { + printf("H"); // Snake head + } else if (is_snake(state, x, y)) { + printf("S"); // Snake body } else { int is_food = 0; - for(int i = 0; i < FOOD_COUNT; i++) { - if(state->foodx[i] == x && state->foody[i] == y) { + for (int i = 0; i < FOOD_COUNT; i++) { + if (state->foodx[i] == x && state->foody[i] == y) { is_food = 1; break; } @@ -48,38 +140,3 @@ void draw_state(struct state* state) { } } -// Spracuje vstup od hráča -void process_input(struct state* state) { - char input = getchar(); - switch(input) { - case 'w': state->sx = 0; state->sy = -1; break; - case 'a': state->sx = -1; state->sy = 0; break; - case 's': state->sx = 0; state->sy = 1; break; - case 'd': state->sx = 1; state->sy = 0; break; - } -} - -// Hlavná slučka hry -void game_loop(struct state* state) { - while(1) { - draw_state(state); - process_input(state); - int result = step_state(state); - if(result == END_WALL || result == END_SNAKE) { - printf("Game over!\n"); - break; - } - if(result == END_FOOD) { - generate_food(state); - } - } -} - -int main() { - srand(time(NULL)); - struct state state; - init_state(&state, 20, 20); - game_loop(&state); - free_snake(state.snake); - return 0; -}