34 int checked_players = 0;
35 while (checked_players < game->players_count) {
62 short start_tile =
get_tile(game, start);
85 if (target.
x == start.
x && target.
y == start.
y) {
87 }
else if (target.
x != start.
x && target.
y != start.
y) {
90 short target_tile =
get_tile(game, target);
98 int dx = target.
x > start.
x ? 1 : target.
x < start.
x ? -1 : 0;
99 int dy = target.
y > start.
y ? 1 : target.
y < start.
y ? -1 : 0;
100 while (coords.
x != target.
x || coords.
y != target.
y) {
101 coords.
x += dx, coords.
y += dy;
105 short tile =
get_tile(game, coords);
122 short target_tile =
get_tile(game, target);
129 entry_data->
target = target;
Functions for working with the game board (and the specifics of its encoding)
#define is_fish_tile(tile)
#define is_penguin_tile(tile)
#define PENGUIN_TILE(player_id)
#define is_water_tile(tile)
#define get_tile_player_id(tile)
#define get_tile_fish(tile)
The core of the unified game logic library, contains the Game struct.
@ GAME_PHASE_MOVEMENT
Set by movement_begin.
@ GAME_PHASE_SETUP_DONE
Set by game_end_setup, placement_end, movement_end.
@ GAME_LOG_ENTRY_MOVEMENT
See GameLogMovement.
Movement phase functions.
@ MOVEMENT_OVER_EMPTY_TILE
@ MOVEMENT_PENGUIN_BLOCKED
@ MOVEMENT_NOT_YOUR_PENGUIN
@ MOVEMENT_CURRENT_LOCATION
@ MOVEMENT_ONTO_EMPTY_TILE
A pair of 2D coordinates, used for addressing the Game::board_grid.
An entry in the Game::log_buffer, implemented as a tagged union.
union GameLogEntry::GameLogEntryData data
A GameLogEntry created by move_penguin.
The central struct of the application, holds the game data and settings.
ALWAYS_INLINE bool is_tile_in_bounds(const Game *game, Coords coords)
Checks if the given coords are within the bounds of the board.
int movement_switch_player(Game *game)
Performs the player switching logic for the movement phase.
Player * game_get_current_player(const Game *self)
A shorthand for calling game_get_player with Game::current_player_index.
ALWAYS_INLINE void set_tile(Game *game, Coords coords, short value)
Sets the value of the tile at coords (and also sets the attribute TILE_DIRTY). Fails if coords are ou...
void move_penguin(Game *game, Coords start, Coords target)
Creates a GameLogMovement entry. The requested move must be valid.
ALWAYS_INLINE short get_tile(const Game *game, Coords coords)
Returns the value of the tile at coords. Fails if coords are outside the bounds.
void game_set_current_player(Game *self, int idx)
Sets Game::current_player_index and creates a GameLogPlayerChange log entry.
GamePhase phase
The current state of the state machine, initially set to GAME_PHASE_NONE. Use game_set_phase for sett...
void game_set_phase(Game *self, GamePhase phase)
Sets the current Game::phase and creates a GameLogPhaseChange log entry.
bool any_valid_player_move_exists(const Game *game, int player_idx)
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...
int count_obstructed_directions(const Game *game, Coords penguin)
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...
void movement_begin(Game *game)
Enters the GAME_PHASE_MOVEMENT phase, can only be called in GAME_PHASE_SETUP_DONE.
int current_player_index
A negative value means that there is no current player selected. Use game_set_current_player for sett...
PossibleSteps calculate_penguin_possible_moves(const Game *game, Coords start)
int players_count
Use game_set_players_count for setting this.
MovementError validate_movement(const Game *game, Coords start, Coords target, Coords *fail)
MovementError validate_movement_start(const Game *game, Coords start)
void movement_end(Game *game)
Exits the GAME_PHASE_MOVEMENT phase and switches to GAME_PHASE_SETUP_DONE.
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...
void undo_move_penguin(Game *game)
Removes a GameLogMovement entry from the log and undoes it.
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 ...
Holds the data of the players of the Game.
short id
The unique ID, usually (but not necessarily) is just index + 1.
int moves_count
The number of moves (penguin placements and movements) made by the player.
Coords * penguins
The list of the positions of all of the player's penguins.
int points
The score of the player, i.e. the number of collected fish.
int penguins_count
The length of the penguins array.
Exists purely to wrap an array of the numbers of steps in every possible Direction.