From b402dc177c696a59367e44dea49b4ec379fee2a8 Mon Sep 17 00:00:00 2001 From: Nakidai Date: Mon, 30 Oct 2023 01:55:20 +0300 Subject: [PATCH] Add gameplay - wasd - turn snake - q - leave --- include/food.h | 9 ++++++++ include/player.h | 5 ++++- include/screen.h | 1 + src/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++- src/player.c | 34 +++++++++++++++++++++++++------ src/screen.c | 5 +++++ 6 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 include/food.h diff --git a/include/food.h b/include/food.h new file mode 100644 index 0000000..b5f60bd --- /dev/null +++ b/include/food.h @@ -0,0 +1,9 @@ +#ifndef __FOOD_H__ +#define __FOOD_H__ + +typedef struct food_t +{ + int x, y; +} Food; + +#endif /* __FOOD_H__ */ diff --git a/include/player.h b/include/player.h index f9a8a00..33bc140 100644 --- a/include/player.h +++ b/include/player.h @@ -2,6 +2,7 @@ #define __PLAYER_H__ #include +#include "food.h" #define UP 0 #define RIGHT 1 @@ -28,6 +29,8 @@ struct player_t Player *playerCreate(Direction direction, int x, int y, int score); void playerFree(Player *player); -void playerDoTick(Player *player, bool food_collision); +bool playerCheckSelfCollision(Player *player); +bool playerCheckFoodCollision(Player *player, Food food); +bool playerDoTick(Player *player, Food food); #endif /* __PLAYER_H__ */ diff --git a/include/screen.h b/include/screen.h index d4be528..d8a59de 100644 --- a/include/screen.h +++ b/include/screen.h @@ -14,5 +14,6 @@ void screenFree(Screen *screen); Point *screenGetPoint(Screen *screen, int x, int y); void screenShow(Screen *screen); +void screenSet(Screen *screen, char fill_value); #endif /* __SCREEN_H__ */ diff --git a/src/main.c b/src/main.c index c276096..e8db39b 100644 --- a/src/main.c +++ b/src/main.c @@ -3,10 +3,12 @@ #include #include #include +#include #include "input.h" #include "screen.h" #include "player.h" +#include "food.h" void drawPlayer(Player *player, Screen *screen) { @@ -15,11 +17,25 @@ void drawPlayer(Player *player, Screen *screen) *screenGetPoint(screen, node->x, node->y) = '#'; } +Food generateFood(Player *player) +{ + Food food; + do + { + food = (Food){random() % 10, random() % 10}; + } while (playerCheckFoodCollision(player, food)); + return food; +} + int main(int argc, char **argv) { + srandom(time(NULL)); Player *player = playerCreate(DOWN, 0, 0, 0); Screen *screen = screenCreate(10, 10, ' '); + PlayerNode *node; pthread_t input_thread; + int head_x, head_y; + Food food = generateFood(player); bool *running = malloc(sizeof(bool)); *running = true; char *key = malloc(sizeof(char)); *key = 0; @@ -28,7 +44,42 @@ int main(int argc, char **argv) pthread_create(&input_thread, NULL, input, &input_args); while (*running) { - if (*key == 'q') *running = false; + switch (*key) + { + case 'q': + *running = false; return 0; + case 'w': + player->direction = UP; break; + case 'd': + player->direction = RIGHT; break; + case 's': + player->direction = DOWN; break; + case 'a': + player->direction = LEFT; break; + sleep(1); + } + + if (playerDoTick(player, food)) + food = generateFood(player); + if (playerCheckSelfCollision(player)) + { + *running = false; + break; + } + head_x = player->head->x; + head_y = player->head->y; + if (head_x >= 10 || head_x < 0 || head_y >= 10 || head_y < 0) + { + *running = false; + break; + } + + screenSet(screen, ' '); + drawPlayer(player, screen); + *screenGetPoint(screen, food.x, food.y) = '@'; + screenShow(screen); + + sleep(1); } return 0; } diff --git a/src/player.c b/src/player.c index 9be05d5..00f229f 100644 --- a/src/player.c +++ b/src/player.c @@ -1,6 +1,7 @@ -#include "player.h" #include +#include "player.h" + Player *playerCreate(Direction direction, int x, int y, int score) { Player *player = (Player *)malloc(sizeof(Player)); @@ -20,8 +21,27 @@ void playerFree(Player *player) { } -void playerDoTick(Player *player, bool food_collision) +bool playerCheckFoodCollision(Player *player, Food food) { + for (PlayerNode *node = player->tail; node != NULL; node = node->next) + if (node->x == food.x && node->y == food.y) + return true; + return false; +} + +bool playerCheckSelfCollision(Player *player) +{ + PlayerNode *nodei, *nodej; + for (nodei = player->tail; nodei != NULL; nodei = nodei->next) + for (nodej = nodei->next; nodej != NULL; nodej = nodej->next) + if (nodei->x == nodej->x && nodei->y == nodej->x) + return true; + return false; +} + +bool playerDoTick(Player *player, Food food) +{ + bool food_collision; PlayerNode *new_head = (PlayerNode *)malloc(sizeof(PlayerNode)); int head_x = player->head->x; int head_y = player->head->y; @@ -49,13 +69,15 @@ void playerDoTick(Player *player, bool food_collision) player->head->next = new_head; player->head = new_head; - if (!food_collision) + food_collision = (new_head->x == food.x && new_head->y == food.y); + if (food_collision) + { + ++player->score; + } else { PlayerNode *new_tail = player->tail->next; free(player->tail); player->tail = new_tail; - } else - { - ++player->score; } + return food_collision; } diff --git a/src/screen.c b/src/screen.c index ebd5726..861df19 100644 --- a/src/screen.c +++ b/src/screen.c @@ -43,3 +43,8 @@ void screenShow(Screen *screen) putchar('\n'); } } + +void screenSet(Screen *screen, char fill_value) +{ + memset(screen->screen, fill_value, screen->width * screen->height * sizeof(char)); +}