catanatron package

Submodules

catanatron.game module

Contains Game class which is a thin-wrapper around the State class.

class catanatron.game.Game(players: Iterable[catanatron.models.player.Player], seed: Optional[int] = None, discard_limit: int = 7, vps_to_win: int = 10, catan_map: Optional[catanatron.models.map.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()catanatron.game.Game

Creates a copy of this Game, that can be modified without repercusions on this one (useful for simulations).

Returns

Game copy.

Return type

Game

execute(action: catanatron.models.enums.Action, validate_action: bool = True)catanatron.models.enums.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

Color

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

Action

winning_color()Optional[catanatron.models.player.Color]

Gets winning color

Returns

Might be None if game truncated by TURNS_LIMIT

Return type

Union[Color, None]

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.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: json.encoder.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 a TypeError).

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[Any], 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]

board

Board state. Settlement locations, cities, roads, ect… See Board class.

Type

Board

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]

color_to_index

Color to seating location cache

Type

Dict[Color, int]

colors

Represents seating order.

Type

Tuple[Color]

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]]

actions

Log of all actions taken. Fully-specified actions.

Type

List[Action]

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

ActionPrompt

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

playable_actions

List of playable actions by current player.

Type

List[Action]

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

State

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: catanatron.state.State, action: catanatron.models.enums.Action)

Main controller call. Follows redux-like pattern and routes the given action to the appropiate state-changing calls.

Responsible for mantaining:

.current_player_index, .current_turn_index, .current_prompt (and similars), .playable_actions.

Appends given action to the list of actions, as fully-specified action.

Parameters
  • state (State) – State to mutate

  • action (Action) – Action to carry out

Raises

ValueError – If invalid action given

Returns

Fully-specified action

Return type

Action

catanatron.state.next_player_index(state, direction=1)
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: catanatron.models.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_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_visible_victory_points(state, color)
catanatron.state_functions.mantain_largets_army(state, color, previous_army_color, previous_army_size)
catanatron.state_functions.mantain_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_subtract(state, color, freqdeck)
catanatron.state_functions.player_deck_to_array(state, color)
catanatron.state_functions.player_freqdeck_add(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