Skip to content

Commit

Permalink
Add online mode for snake
Browse files Browse the repository at this point in the history
Snake can now be played with your friends.
  • Loading branch information
JFreegman committed Nov 27, 2023
1 parent 03987f4 commit 5493ee5
Show file tree
Hide file tree
Showing 7 changed files with 935 additions and 126 deletions.
2 changes: 1 addition & 1 deletion src/chat.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ void chat_onGameInvite(ToxWindow *self, Tox *m, uint32_t friend_number, const ui

GameType type = data[1];

if (!game_type_is_multiplayer(type)) {
if (!game_type_has_multiplayer(type)) {
return;
}

Expand Down
60 changes: 50 additions & 10 deletions src/game_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,25 @@ void game_list_print(ToxWindow *self)
}
}

bool game_type_is_multiplayer(GameType type)
bool game_type_has_multiplayer(GameType type)
{
return type == GT_Chess || type == GT_Snake;
}

static bool game_type_is_multi_only(GameType type)
{
return type == GT_Chess;
}

static bool game_type_is_multi_and_single(const ToxWindow *window, GameType type)
{
if (window->type != WINDOW_TYPE_CHAT) {
return false;
}

return type == GT_Snake;
}

/*
* Sends a notification to the window associated with `game`.
*
Expand Down Expand Up @@ -209,7 +223,7 @@ static int game_initialize_type(GameData *game, const uint8_t *data, size_t leng

switch (game->type) {
case GT_Snake: {
ret = snake_initialize(game);
ret = snake_initialize(game, game->is_multiplayer, self_host);
break;
}

Expand Down Expand Up @@ -261,7 +275,7 @@ int game_initialize(const ToxWindow *parent, Tox *m, GameType type, uint32_t id,
return -4;
}

game->is_multiplayer = game_type_is_multiplayer(type);
game->is_multiplayer = game_type_is_multi_only(type) || game_type_is_multi_and_single(parent, type);

if (game->is_multiplayer) {
if (parent->type != WINDOW_TYPE_CHAT) {
Expand Down Expand Up @@ -461,6 +475,14 @@ int game_set_message(GameData *game, const char *message, size_t length, Directi
return -1;
}

int max_x;
int max_y;
getmaxyx(game->window, max_y, max_x);

if (coords->x > max_x || coords->x < 0 || coords->y > max_y || coords->y < 0) {
return -1;
}

GameMessage *m = game_get_new_message_holder(game);

if (m == NULL) {
Expand Down Expand Up @@ -603,17 +625,28 @@ static void game_draw_game_over(const GameData *game)
const int x = max_x / 2;
const int y = max_y / 2;

const char *message = "GAME OVER!";
const char *message;
int colour = RED;

if (game->is_multiplayer) {
message = game->winner ? "You win!" : "You lose!";
colour = game->winner ? YELLOW : RED;
} else {
message = "GAME OVER!";
}

size_t length = strlen(message);

wattron(win, A_BOLD | COLOR_PAIR(RED));
wattron(win, A_BOLD | COLOR_PAIR(colour));
mvwprintw(win, y - 1, x - (length / 2), "%s", message);
wattroff(win, A_BOLD | COLOR_PAIR(RED));
wattroff(win, A_BOLD | COLOR_PAIR(colour));

message = "Press F5 to play again";
length = strlen(message);
if (!game->is_multiplayer) {
message = "Press F5 to play again";
length = strlen(message);

mvwprintw(win, y + 1, x - (length / 2), "%s", message);
mvwprintw(win, y + 1, x - (length / 2), "%s", message);
}
}

static void game_draw_pause_screen(const GameData *game)
Expand Down Expand Up @@ -881,7 +914,7 @@ static ToxWindow *game_new_window(Tox *m, GameType type, uint32_t friendnumber)

ret->active_box = -1;

if (game_type_is_multiplayer(type)) {
if (game_type_is_multi_only(type)) {
char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, friendnumber);

Expand Down Expand Up @@ -1043,6 +1076,13 @@ void game_set_status(GameData *game, GameStatus status)
}
}

void game_set_winner(GameData *game, bool winner)
{
if (game->status == GS_Finished) {
game->winner = winner;
}
}

void game_set_update_interval(GameData *game, TIME_MS update_interval)
{
game->update_interval = MIN(update_interval, GAME_MAX_UPDATE_INTERVAL);
Expand Down
9 changes: 8 additions & 1 deletion src/game_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ struct GameData {
size_t level;
GameStatus status;
GameType type;

bool is_multiplayer;
bool winner; // true if you won the game

bool show_lives;
bool show_score;
Expand Down Expand Up @@ -260,7 +262,7 @@ void game_list_print(ToxWindow *self);
/*
* Return true if game `type` has a multiplayer mode.
*/
bool game_type_is_multiplayer(GameType type);
bool game_type_has_multiplayer(GameType type);

/*
* Returns true if coordinates designated by `x` and `y` are within the game window boundaries.
Expand Down Expand Up @@ -344,6 +346,11 @@ size_t game_get_current_level(const GameData *game);
*/
void game_set_status(GameData *game, GameStatus status);

/*
* Sets winner flag. This should only be called when the game status is set to finished.
*/
void game_set_winner(GameData *game, bool winner);

/*
* Sets the game base update interval.
*
Expand Down
Loading

0 comments on commit 5493ee5

Please sign in to comment.