catanatron package#
Subpackages#
Submodules#
catanatron.game module#
Contains Game class which is a thin-wrapper around the State class.
- class catanatron.game.Game(players: List[Player], seed: Optional[int] = None, discard_limit: int = 7, vps_to_win: int = 10, catan_map: Optional[CatanMap] = None, initialize: bool = True)#
Bases:
object
Initializes a map, decides player seating order, and exposes two main methods for executing the game (play and play_tick; to advance until completion or just by one decision by a player respectively).
- copy() Game #
Creates a copy of this Game, that can be modified without repercusions on this one (useful for simulations).
- Returns
Game copy.
- Return type
- execute(action: Action, validate_action: bool = True) Action #
Internal call that carries out decided action by player
- play(accumulators=[], decide_fn=None)#
Executes game until a player wins or exceeded TURNS_LIMIT.
- Parameters
accumulators (list[Accumulator], optional) – list of Accumulator classes to use. Their .consume method will be called with every action, and their .finalize method will be called when the game ends (if it ends) Defaults to [].
decide_fn (function, optional) – Function to overwrite current player’s decision with. Defaults to None.
- Returns
winning color or None if game exceeded TURNS_LIMIT
- Return type
- play_tick(decide_fn=None, accumulators=[])#
Advances game by one ply (player decision).
- Parameters
decide_fn (function, optional) – Function to overwrite current player’s decision with. Defaults to None.
- Returns
Final action (modified to be used as Log)
- Return type
- class catanatron.game.GameAccumulator(**kwargs)#
Bases:
object
Interface to hook into different game lifecycle events.
Useful to compute aggregate statistics, log information, etc…
- after(game)#
Called when the game is finished.
Check game.winning_color() to see if the game actually finished or exceeded turn limit (is None).
- before(game)#
Called when the game is created, no actions have been taken by players yet, but the board is decided.
- step(game_before_action, action)#
Called after each action taken by a player. Game should be right before action is taken.
- catanatron.game.is_valid_action(state, action)#
True if its a valid action right now. An action is valid if its in playable_actions or if its a OFFER_TRADE in the right time.
- catanatron.game.is_valid_trade(action_value)#
Checks the value of a OFFER_TRADE does not give away resources or trade matching resources.
catanatron.json module#
Classes to encode/decode catanatron classes to JSON format.
- class catanatron.json.GameEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)#
Bases:
JSONEncoder
- default(obj)#
Implement this method in a subclass such that it returns a serializable object for
o
, or calls the base implementation (to raise aTypeError
).For example, to support arbitrary iterators, you could implement default like this:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return JSONEncoder.default(self, o)
- catanatron.json.action_from_json(data)#
- catanatron.json.longest_roads_by_player(state)#
catanatron.state module#
Module with main State class and main apply_action call (game controller).
- class catanatron.state.State(players: List[Player], catan_map=None, discard_limit=7, initialize=True)#
Bases:
object
Collection of variables representing state
- players#
DEPRECATED. Reference to list of players. Use .colors instead, and move this reference to the Game class. Deprecated because we want this class to only contain state information that can be easily copiable.
- Type
List[Player]
- player_state#
See PLAYER_INITIAL_STATE. It will contain one of each key in PLAYER_INITIAL_STATE but prefixed with “P<index_of_player>”. Example: { P0_HAS_ROAD: False, P1_SETTLEMENTS_AVAILABLE: 18, … }
- Type
Dict[str, Any]
- resource_freqdeck#
Represents resource cards in the bank. Each element is the amount of [WOOD, BRICK, SHEEP, WHEAT, ORE].
- Type
List[int]
- development_listdeck#
Represents development cards in the bank. Already shuffled.
- Type
List[FastDevCard]
- buildings_by_color#
Cache of buildings. Can be used like: buildings_by_color[Color.RED][SETTLEMENT] to get a list of all node ids where RED has settlements.
- Type
Dict[Color, Dict[FastBuildingType, List]]
- num_turns#
number of turns thus far
- Type
int
- current_player_index#
index per colors array of player that should be making a decision now. Not necesarilly the same as current_turn_index because there are out-of-turn decisions like discarding.
- Type
int
- current_turn_index#
index per colors array of player whose turn is it.
- Type
int
- current_prompt#
DEPRECATED. Not needed; use is_initial_build_phase, is_moving_knight, etc… instead.
- Type
- is_discarding#
If current player needs to discard.
- Type
bool
- is_moving_knight#
If current player needs to move robber.
- Type
bool
- is_road_building#
If current player needs to build free roads per Road Building dev card.
- Type
bool
- free_roads_available#
Number of roads available left in Road Building phase.
- Type
int
- copy()#
Creates a copy of this State class that can be modified without repercusions to this one. Immutable values are just copied over.
- Returns
State copy.
- Return type
- current_color()#
Helper for accessing color (player) who should decide next
- current_player()#
Helper for accessing Player instance who should decide next
- catanatron.state.advance_turn(state, direction=1)#
Sets .current_player_index
- catanatron.state.apply_action(state: State, action: Action)#
Main controller call. Follows redux-like pattern and routes the given action to the appropiate state-changing calls.
- Responsible for maintaining:
.current_player_index, .current_turn_index, .current_prompt (and similars), .playable_actions.
Appends given action to the list of actions, as fully-specified action.
- catanatron.state.next_player_index(state, direction=1)#
- catanatron.state.reset_trading_state(state)#
- catanatron.state.roll_dice()#
Yields two random numbers
- Returns
2-tuple of random numbers from 1 to 6 inclusive.
- Return type
tuple[int, int]
- catanatron.state.yield_resources(board: Board, resource_freqdeck, number)#
Computes resource payouts for given board and dice roll number.
- Parameters
board (Board) – Board state
resource_freqdeck (List[int]) – Bank’s resource freqdeck
number (int) – Sum of dice roll
- Returns
- 2-tuple.
First element is color => freqdeck mapping. e.g. {Color.RED: [0,0,0,3,0]}. Second is an array of resources that couldn’t be yieleded because they depleted.
- Return type
(dict, List[int])
catanatron.state_functions module#
Functions that mutate the given state accordingly. Core of game logic. Some are helpers to _read_ information from state and keep the rest of the code decoupled from state representation.
- catanatron.state_functions.build_city(state, color, node_id)#
- catanatron.state_functions.build_road(state, color, edge, is_free)#
- catanatron.state_functions.build_settlement(state, color, node_id, is_free)#
- catanatron.state_functions.buy_dev_card(state, color, dev_card)#
- catanatron.state_functions.get_actual_victory_points(state, color)#
- catanatron.state_functions.get_dev_cards_in_hand(state, color, dev_card=None)#
- catanatron.state_functions.get_enemy_colors(colors, player_color)#
- catanatron.state_functions.get_largest_army(state)#
- catanatron.state_functions.get_longest_road_color(state)#
- catanatron.state_functions.get_longest_road_length(state, color)#
- catanatron.state_functions.get_played_dev_cards(state, color, dev_card=None)#
- catanatron.state_functions.get_player_buildings(state, color_param, building_type_param)#
- catanatron.state_functions.get_player_freqdeck(state, color)#
Returns a ‘freqdeck’ of a player’s resource hand.
- catanatron.state_functions.get_visible_victory_points(state, color)#
- catanatron.state_functions.maintain_largest_army(state, color, previous_army_color, previous_army_size)#
- catanatron.state_functions.maintain_longest_road(state, previous_road_color, road_color, road_lengths)#
- catanatron.state_functions.play_dev_card(state, color, dev_card)#
- catanatron.state_functions.player_can_afford_dev_card(state, color)#
- catanatron.state_functions.player_can_play_dev(state, color, dev_card)#
- catanatron.state_functions.player_clean_turn(state, color)#
- catanatron.state_functions.player_deck_draw(state, color, card, amount=1)#
- catanatron.state_functions.player_deck_random_draw(state, color)#
- catanatron.state_functions.player_deck_replenish(state, color, resource, amount=1)#
- catanatron.state_functions.player_deck_to_array(state, color)#
- catanatron.state_functions.player_freqdeck_add(state, color, freqdeck)#
- catanatron.state_functions.player_freqdeck_subtract(state, color, freqdeck)#
- catanatron.state_functions.player_has_rolled(state, color)#
- catanatron.state_functions.player_key(state, color)#
- catanatron.state_functions.player_num_dev_cards(state, color)#
- catanatron.state_functions.player_num_resource_cards(state, color, card: Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']] = None)#
- catanatron.state_functions.player_resource_freqdeck_contains(state, color, freqdeck)#
Module contents#
This is to allow an API like:
from catanatron import Game, Player, Color, Accumulator