penguins  1.0.0
game.h
Go to the documentation of this file.
1 #pragma once
2 
5 
6 #include "utils.h"
7 #include <assert.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
55 typedef enum GamePhase {
62 } GamePhase;
63 
68 typedef struct Player {
70  short id;
72  char* name;
74  int points;
83  int color;
84 } Player;
85 
87 typedef enum GameLogEntryType {
93 
95 typedef struct GameLogPhaseChange {
99 
101 typedef struct GameLogPlayerChange {
105 
107 typedef struct GameLogPlacement {
109  short undo_tile;
111 
113 typedef struct GameLogMovement {
116  short undo_tile;
118 
156 typedef struct GameLogEntry {
163  } data;
164 } GameLogEntry;
165 
237 typedef struct Game {
243 
246 
257 
259 
262 
267 
306  short* board_grid;
307 
331 
333 
336 
348  size_t log_capacity;
351  size_t log_length;
354  size_t log_current;
355 
357 } Game;
358 
359 Game* game_new(void);
360 Game* game_clone(const Game* other);
361 void game_free(Game* self);
362 
363 uint32_t game_compute_state_hash(const Game* self);
364 void game_set_log_capacity(Game* self, size_t capacity);
366 const GameLogEntry* game_pop_log_entry(Game* self, GameLogEntryType expected_type);
367 const GameLogEntry* game_get_log_entry(const Game* self, size_t idx);
368 
369 void game_set_phase(Game* self, GamePhase phase);
370 void game_set_current_player(Game* self, int idx);
371 
372 void game_begin_setup(Game* self);
373 void game_end_setup(Game* self);
374 void game_set_penguins_per_player(Game* self, int value);
375 void game_set_players_count(Game* self, int count);
376 void game_set_player_name(Game* self, int idx, const char* name);
377 
378 void game_add_player_penguin(Game* self, int idx, Coords coords);
379 void game_remove_player_penguin(Game* self, int idx, Coords coords);
380 
381 void game_advance_state(Game* self);
382 void game_end(Game* self);
383 void game_rewind_state_to_log_entry(Game* self, size_t target_entry);
384 
387 inline bool game_check_player_index(const Game* self, int idx) {
388  return 0 <= idx && idx < self->players_count;
389 }
390 
394 inline Player* game_get_player(const Game* self, int idx) {
395  assert(game_check_player_index(self, idx));
396  return &self->players[idx];
397 }
398 
401 inline Player* game_get_current_player(const Game* self) {
402  return game_get_player(self, self->current_player_index);
403 }
404 
407 inline int game_find_player_by_id(const Game* self, short id) {
408  for (int i = 0; i < self->players_count; i++) {
409  if (self->players[i].id == id) {
410  return i;
411  }
412  }
413  return -1;
414 }
415 
420 inline Coords* game_find_player_penguin(const Game* self, int idx, Coords coords) {
421  Player* player = game_get_player(self, idx);
422  for (int i = 0; i < player->penguins_count; i++) {
423  Coords* penguin = &player->penguins[i];
424  if (penguin->x == coords.x && penguin->y == coords.y) {
425  return penguin;
426  }
427  }
428  return NULL;
429 }
430 
431 #ifdef __cplusplus
432 }
433 #endif
GamePhase
The values of Game::phase.
Definition: game.h:55
@ GAME_PHASE_PLACEMENT
Set by placement_begin.
Definition: game.h:59
@ GAME_PHASE_MOVEMENT
Set by movement_begin.
Definition: game.h:60
@ GAME_PHASE_SETUP
Set by game_begin_setup.
Definition: game.h:57
@ GAME_PHASE_NONE
The default phase, set when a Game is initially constructed.
Definition: game.h:56
@ GAME_PHASE_SETUP_DONE
Set by game_end_setup, placement_end, movement_end.
Definition: game.h:58
@ GAME_PHASE_END
Set by game_end.
Definition: game.h:61
GameLogEntryType
The values of GameLogEntry::type.
Definition: game.h:87
@ GAME_LOG_ENTRY_PLAYER_CHANGE
See GameLogPlayerChange.
Definition: game.h:89
@ GAME_LOG_ENTRY_PHASE_CHANGE
See GameLogPhaseChange.
Definition: game.h:88
@ GAME_LOG_ENTRY_PLACEMENT
See GameLogPlacement.
Definition: game.h:90
@ GAME_LOG_ENTRY_MOVEMENT
See GameLogMovement.
Definition: game.h:91
A pair of 2D coordinates, used for addressing the Game::board_grid.
Definition: utils.h:15
int x
Definition: utils.h:16
int y
Definition: utils.h:17
An entry in the Game::log_buffer, implemented as a tagged union.
Definition: game.h:156
union GameLogEntry::GameLogEntryData data
GameLogEntryType type
Definition: game.h:157
A GameLogEntry created by move_penguin.
Definition: game.h:113
short undo_tile
Definition: game.h:116
Coords penguin
Definition: game.h:114
Coords target
Definition: game.h:115
A GameLogEntry created by game_set_phase.
Definition: game.h:95
GamePhase old_phase
Definition: game.h:96
GamePhase new_phase
Definition: game.h:97
A GameLogEntry created by place_penguin.
Definition: game.h:107
short undo_tile
Definition: game.h:109
Coords target
Definition: game.h:108
A GameLogEntry created by game_set_current_player.
Definition: game.h:101
int old_player_index
Definition: game.h:102
int new_player_index
Definition: game.h:103
The central struct of the application, holds the game data and settings.
Definition: game.h:237
void game_set_penguins_per_player(Game *self, int value)
Sets Game::penguins_per_player (the value mustn't be negative) and allocates Player::penguins lists o...
Definition: game.c:248
size_t log_current
The index of the currently selected log entry. Normally equals log_length, if less than log_length an...
Definition: game.h:354
Player * game_get_current_player(const Game *self)
A shorthand for calling game_get_player with Game::current_player_index.
Definition: game.h:401
int game_find_player_by_id(const Game *self, short id)
Returns an index of the player or -1 if no such player was found.
Definition: game.h:407
void game_set_log_capacity(Game *self, size_t capacity)
Sets Game::log_capacity and allocates that many elements in Game::log_buffer. If the new capacity is ...
Definition: game.c:121
const GameLogEntry * game_get_log_entry(const Game *self, size_t idx)
Returns a pointer to the entry at the given index. Note that the returned pointer is const because th...
Definition: game.c:173
void game_add_player_penguin(Game *self, int idx, Coords coords)
Definition: game.c:297
void game_set_current_player(Game *self, int idx)
Sets Game::current_player_index and creates a GameLogPlayerChange log entry.
Definition: game.c:195
Player * players
The list of players with length players_count. Initialized with game_set_players_count....
Definition: game.h:249
int penguins_per_player
Use game_set_penguins_per_player for setting this.
Definition: game.h:253
void game_begin_setup(Game *self)
Switches to the GAME_PHASE_SETUP phase, can only be called in GAME_PHASE_NONE. Should be called right...
Definition: game.c:209
GamePhase phase
The current state of the state machine, initially set to GAME_PHASE_NONE. Use game_set_phase for sett...
Definition: game.h:242
void game_end(Game *self)
Switches to the GAME_PHASE_END phase.
Definition: game.c:358
void game_set_phase(Game *self, GamePhase phase)
Sets the current Game::phase and creates a GameLogPhaseChange log entry.
Definition: game.c:181
void game_remove_player_penguin(Game *self, int idx, Coords coords)
Definition: game.c:306
void game_advance_state(Game *self)
The all-in-one phase switcher that progresses of the game.
Definition: game.c:329
const GameLogEntry * game_pop_log_entry(Game *self, GameLogEntryType expected_type)
Pops the last entry off the top of the stack if its type matches the expected_type (this is used as a...
Definition: game.c:156
int board_width
Use setup_board for setting this.
Definition: game.h:264
uint32_t game_compute_state_hash(const Game *self)
Computes a hash of the game state part of the Game, i.e. the fields that change while playing the gam...
Definition: game.c:87
short * tile_attributes
Stores auxilary data of grid tiles for use in the UIs. Use setup_board for initializing,...
Definition: game.h:330
size_t log_capacity
The total number of elements log_buffer was allocated for (i.e. pushing more requires reallocating it...
Definition: game.h:348
short * board_grid
A 2D grid represented as a 1D array which stores the tiles of the board. Use setup_board for initiali...
Definition: game.h:306
GameLogEntry * log_buffer
The stack of log entries. Use game_push_log_entry, game_pop_log_entry and game_get_log_entry for modi...
Definition: game.h:343
void game_end_setup(Game *self)
Verifies that all fields have been initialized and configured and switches the phase from GAME_PHASE_...
Definition: game.c:224
Game * game_clone(const Game *other)
Creates a (deep) copy of another Game.
Definition: game.c:36
size_t log_length
The actual number of entries in log_buffer. game_push_log_entry and game_pop_log_entry affects this.
Definition: game.h:351
Coords * game_find_player_penguin(const Game *self, int idx, Coords coords)
Finds a penguin with the given coordinates in the Player::penguins list of a player at idx and return...
Definition: game.h:420
int board_height
Use setup_board for setting this.
Definition: game.h:266
void game_rewind_state_to_log_entry(Game *self, size_t target_entry)
Successively undoes or redoes log entries in order to reset the game state to the entry at the given ...
Definition: game.c:368
int current_player_index
A negative value means that there is no current player selected. Use game_set_current_player for sett...
Definition: game.h:256
bool log_disabled
Signals whether new log entries can be created. See game_push_log_entry.
Definition: game.h:339
void game_set_player_name(Game *self, int idx, const char *name)
Sets the Player::name of a player at the given index. Only available in the GAME_PHASE_SETUP phase.
Definition: game.c:287
int players_count
Use game_set_players_count for setting this.
Definition: game.h:251
Player * game_get_player(const Game *self, int idx)
Returns a pointer to the player at the given index. Fails if the index isn't within the bounds of the...
Definition: game.h:394
Game * game_new(void)
Constructs a Game. Allocates memory for storing the struct itself, setting all fields to default valu...
Definition: game.c:15
bool game_check_player_index(const Game *self, int idx)
Checks if idx is within the bounds of Game::players.
Definition: game.h:387
void game_free(Game *self)
Destroys a Game, freeing the memory allocated for the struct itself and all associated internal lists...
Definition: game.c:68
GameLogEntry * game_push_log_entry(Game *self, GameLogEntryType type)
Creates a GameLogEntry, sets its GameLogEntry::type, pushes it on top of the stack (reallocating the ...
Definition: game.c:137
void game_set_players_count(Game *self, int count)
Sets Game::players_count (the value mustn't be negative) and allocates the Game::players list....
Definition: game.c:264
Holds the data of the players of the Game.
Definition: game.h:68
short id
The unique ID, usually (but not necessarily) is just index + 1.
Definition: game.h:70
char * name
Use game_set_player_name to set this.
Definition: game.h:72
int moves_count
The number of moves (penguin placements and movements) made by the player.
Definition: game.h:81
int color
The color of the penguins, currently used only in the TUI.
Definition: game.h:83
Coords * penguins
The list of the positions of all of the player's penguins.
Definition: game.h:79
int points
The score of the player, i.e. the number of collected fish.
Definition: game.h:74
int penguins_count
The length of the penguins array.
Definition: game.h:76
GameLogMovement movement
Definition: game.h:162
GameLogPlacement placement
Definition: game.h:161
GameLogPhaseChange phase_change
Definition: game.h:159
GameLogPlayerChange player_change
Definition: game.h:160