penguins  1.0.0
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
placement.c
Go to the documentation of this file.
1 #include "placement.h"
2 #include "board.h"
3 #include "game.h"
4 #include "utils.h"
5 #include <assert.h>
6 #include <stddef.h>
7 
11 void placement_begin(Game* game) {
12  assert(game->phase == GAME_PHASE_SETUP_DONE);
13  game_set_current_player(game, -1);
15 }
16 
20 void placement_end(Game* game) {
21  assert(game->phase == GAME_PHASE_PLACEMENT);
23 }
24 
33  assert(game->phase == GAME_PHASE_PLACEMENT);
34  if (!any_valid_placement_exists(game)) {
36  }
37  int index = game->current_player_index;
38  int checked_players = 0;
39  while (checked_players < game->players_count) {
40  index = (index + 1) % game->players_count;
41  if (game_get_player(game, index)->penguins_count < game->penguins_per_player) {
42  game_set_current_player(game, index);
43  return index;
44  }
45  checked_players++;
46  }
48 }
49 
51 bool any_valid_placement_exists(const Game* game) {
52  for (int y = 0; y < game->board_height; y++) {
53  for (int x = 0; x < game->board_width; x++) {
54  Coords coords = { x, y };
55  if (validate_placement_simple(game, coords)) {
56  return true;
57  }
58  }
59  }
60  return false;
61 }
62 
64 bool validate_placement_simple(const Game* game, Coords target) {
65  short tile = get_tile(game, target);
66  return get_tile_fish(tile) == 1;
67 }
68 
71  if (!is_tile_in_bounds(game, target)) {
73  }
74  short tile = get_tile(game, target);
75  if (is_water_tile(tile)) {
76  return PLACEMENT_EMPTY_TILE;
77  } else if (is_penguin_tile(tile)) {
78  if (get_tile_player_id(tile) == game_get_current_player(game)->id) {
79  return PLACEMENT_OWN_PENGUIN;
80  } else {
82  }
83  } else if (is_fish_tile(tile)) {
84  if (get_tile_fish(tile) > 1) {
86  }
87  }
88  return PLACEMENT_VALID;
89 }
90 
93 void place_penguin(Game* game, Coords target) {
94  assert(game->phase == GAME_PHASE_PLACEMENT);
95  assert(validate_placement(game, target) == PLACEMENT_VALID);
96  Player* player = game_get_current_player(game);
97  short tile = get_tile(game, target);
98  assert(is_fish_tile(tile));
99 
100  GameLogEntry* entry;
101  if ((entry = game_push_log_entry(game, GAME_LOG_ENTRY_PLACEMENT)) != NULL) {
102  GameLogPlacement* entry_data = &entry->data.placement;
103  entry_data->target = target;
104  entry_data->undo_tile = tile;
105  }
106 
107  game_add_player_penguin(game, game->current_player_index, target);
108  set_tile(game, target, PENGUIN_TILE(player->id));
109  player->points += get_tile_fish(tile);
110  player->moves_count += 1;
111 }
112 
116  assert(game->phase == GAME_PHASE_PLACEMENT);
117  const GameLogPlacement* entry =
119 
120  Player* player = game_get_current_player(game);
122  set_tile(game, entry->target, entry->undo_tile);
123  player->points -= get_tile_fish(entry->undo_tile);
124  player->moves_count -= 1;
125 }
Functions for working with the game board (and the specifics of its encoding)
#define is_fish_tile(tile)
Definition: board.h:25
#define is_penguin_tile(tile)
Definition: board.h:26
#define PENGUIN_TILE(player_id)
Definition: board.h:23
#define is_water_tile(tile)
Definition: board.h:24
#define get_tile_player_id(tile)
Definition: board.h:28
#define get_tile_fish(tile)
Definition: board.h:27
The core of the unified game logic library, contains the Game struct.
@ GAME_PHASE_PLACEMENT
Set by placement_begin.
Definition: game.h:59
@ GAME_PHASE_SETUP_DONE
Set by game_end_setup, placement_end, movement_end.
Definition: game.h:58
@ GAME_LOG_ENTRY_PLACEMENT
See GameLogPlacement.
Definition: game.h:90
Placement phase functions.
@ PLACEMENT_ALL_PENGUINS_PLACED
Definition: placement.h:25
@ PLACEMENT_NO_MORE_FREE_TILES
Definition: placement.h:26
PlacementError
Definition: placement.h:14
@ PLACEMENT_VALID
Definition: placement.h:15
@ PLACEMENT_OWN_PENGUIN
Definition: placement.h:19
@ PLACEMENT_MULTIPLE_FISH
Definition: placement.h:20
@ PLACEMENT_ENEMY_PENGUIN
Definition: placement.h:18
@ PLACEMENT_EMPTY_TILE
Definition: placement.h:17
@ PLACEMENT_OUT_OF_BOUNDS
Definition: placement.h:16
A pair of 2D coordinates, used for addressing the Game::board_grid.
Definition: utils.h:15
An entry in the Game::log_buffer, implemented as a tagged union.
Definition: game.h:156
union GameLogEntry::GameLogEntryData data
A GameLogEntry created by place_penguin.
Definition: game.h:107
short undo_tile
Definition: game.h:109
Coords target
Definition: game.h:108
The central struct of the application, holds the game data and settings.
Definition: game.h:237
ALWAYS_INLINE bool is_tile_in_bounds(const Game *game, Coords coords)
Checks if the given coords are within the bounds of the board.
Definition: board.h:70
void undo_place_penguin(Game *game)
Removes a GameLogPlacement entry from the log and undoes it.
Definition: placement.c:115
Player * game_get_current_player(const Game *self)
A shorthand for calling game_get_player with Game::current_player_index.
Definition: game.h:401
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...
Definition: board.h:117
bool validate_placement_simple(const Game *game, Coords target)
Definition: placement.c:64
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.
Definition: board.h:108
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
int penguins_per_player
Use game_set_penguins_per_player for setting this.
Definition: game.h:253
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_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
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
bool any_valid_placement_exists(const Game *game)
Definition: placement.c:51
void placement_begin(Game *game)
Enters the GAME_PHASE_PLACEMENT phase, can only be called in GAME_PHASE_SETUP_DONE.
Definition: placement.c:11
int board_height
Use setup_board for setting this.
Definition: game.h:266
PlacementError validate_placement(const Game *game, Coords target)
Definition: placement.c:70
int placement_switch_player(Game *game)
Performs the player switching logic for the placement phase.
Definition: placement.c:32
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
int players_count
Use game_set_players_count for setting this.
Definition: game.h:251
void place_penguin(Game *game, Coords target)
Creates a GameLogPlacement entry. The requested placement must be valid.
Definition: placement.c:93
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
void placement_end(Game *game)
Exits the GAME_PHASE_PLACEMENT phase and switches to GAME_PHASE_SETUP_DONE.
Definition: placement.c:20
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
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
int moves_count
The number of moves (penguin placements and movements) made by the player.
Definition: game.h:81
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
GameLogPlacement placement
Definition: game.h:161