diff --git a/a2/snake.c b/a2/snake.c index 137e744..0850bba 100644 --- a/a2/snake.c +++ b/a2/snake.c @@ -1,83 +1,118 @@ -#include "snake.h" +#include #include +#include -#define FOOD_COUNT 20 +#define WIDTH 20 +#define HEIGHT 20 +#define FOOD_COUNT 3 -struct state { - struct snake* snake; - int sx, sy; - int width, height; - int foodx[FOOD_COUNT], foody[FOOD_COUNT]; +enum EndGame { END_WALL, END_SNAKE, END_FOOD, END_CONTINUE }; + +struct snake { + int x, y; + struct snake* next; }; -struct snake* add_snake(struct snake* snake, int x, int y) { - struct snake* new_head = (struct snake*) malloc(sizeof(struct snake)); - new_head->x = x; - new_head->y = y; - new_head->next = snake; - return new_head; -} +struct state { + int width, height; + int sx, sy; + struct snake* snake; + int foodx[FOOD_COUNT]; + int foody[FOOD_COUNT]; +}; -struct snake* remove_snake(struct snake* snake) { - if (snake == NULL || snake->next == NULL) { - return NULL; - } - struct snake* temp = snake; - while(temp->next->next != NULL) { - temp = temp->next; - } - free(temp->next); - temp->next = NULL; - return snake; -} -int is_snake(struct snake* snake, int x, int y) { - while(snake != NULL) { - if(snake->x == x && snake->y == y) { - return 1; - } - snake = snake->next; - } +void initialize(struct state* state); +void render(struct state* state); +void handle_input(struct state* state); +void game_loop(struct state* state); +void cleanup(struct state* state); + +int main() { + struct state game_state; + initialize(&game_state); + game_loop(&game_state); + cleanup(&game_state); return 0; } -void free_snake(struct snake* snake) { - struct snake* temp; - while(snake != NULL) { - temp = snake; - snake = snake->next; - free(temp); +void initialize(struct state* state) { + state->width = WIDTH; + state->height = HEIGHT; + state->sx = 1; + state->sy = 0; + state->snake = add_snake(NULL, 5, 5); + + for (int i = 0; i < FOOD_COUNT; i++) { + state->foodx[i] = rand() % state->width; + state->foody[i] = rand() % state->height; } } -int step_state(struct state* state) { - int new_x = state->snake->x + state->sx; - int new_y = state->snake->y + state->sy; - - if(new_x < 0 || new_x >= state->width || new_y < 0 || new_y >= state->height) { - return END_WALL; - } - - if(is_snake(state->snake, new_x, new_y)) { - return END_SNAKE; - } - - for(int i = 0; i < FOOD_COUNT; i++) { - if(state->foodx[i] == new_x && state->foody[i] == new_y) { - state->foodx[i] = -1; - state->foody[i] = -1; - state->snake = add_snake(state->snake, new_x, new_y); - for(int j = 0; j < FOOD_COUNT; j++) { - if(state->foodx[j] != -1) { - return END_CONTINUE; +void render(struct state* state) { + system("cls"); + + for (int y = 0; y < state->height; y++) { + for (int x = 0; x < state->width; x++) { + if (is_snake(state->snake, x, y)) { + printf("* "); + } else { + int food = 0; + for (int i = 0; i < FOOD_COUNT; i++) { + if (state->foodx[i] == x && state->foody[i] == y) { + printf("o "); + food = 1; + break; + } } + if (!food) printf(". "); } - return END_FOOD; + } + printf("\n"); + } +} + +void handle_input(struct state* state) { + if (_kbhit()) { + char key = _getch(); + switch (key) { + case 'w': + state->sx = 0; state->sy = -1; + break; + case 's': + state->sx = 0; state->sy = 1; + break; + case 'a': + state->sx = -1; state->sy = 0; + break; + case 'd': + state->sx = 1; state->sy = 0; + break; + case 'q': + exit(0); + break; + default: + break; } } - - state->snake = add_snake(state->snake, new_x, new_y); - state->snake = remove_snake(state->snake); - - return END_CONTINUE; +} + +void game_loop(struct state* state) { + while (1) { + render(state); + handle_input(state); + int result = step_state(state); + if (result == END_WALL || result == END_SNAKE) { + printf("Game Over!\n"); + break; + } else if (result == END_FOOD) { + printf("You ate all the food! You win!\n"); + break; + } + + } +} + +void cleanup(struct state* state) { + free_snake(state->snake); }