catanatron.models package#

Submodules#

catanatron.models.actions module#

Move-generation functions (these return a list of actions that can be taken by current player). Main function is generate_playable_actions.

catanatron.models.actions.city_possibilities(state, color) List[Action]#
catanatron.models.actions.discard_possibilities(color) List[Action]#
catanatron.models.actions.generate_playable_actions(state) List[Action]#
catanatron.models.actions.initial_road_possibilities(state, color) List[Action]#
catanatron.models.actions.inner_maritime_trade_possibilities(hand_freqdeck, bank_freqdeck, port_resources)#

This inner function is to make this logic more shareable

catanatron.models.actions.maritime_trade_possibilities(state, color) List[Action]#
catanatron.models.actions.monopoly_possibilities(color) List[Action]#
catanatron.models.actions.ncr(n, r)#

n choose r. helper for discard_possibilities

catanatron.models.actions.road_building_possibilities(state, color, check_money=True) List[Action]#
catanatron.models.actions.robber_possibilities(state, color) List[Action]#
catanatron.models.actions.settlement_possibilities(state, color, initial_build_phase=False) List[Action]#
catanatron.models.actions.year_of_plenty_possibilities(color, freqdeck: List[int]) List[Action]#

catanatron.models.board module#

class catanatron.models.board.Board(catan_map=None, initialize=True)#

Bases: object

Encapsulates all state information regarding the board.

buildings#

Mapping from node id to building (if there is a building there).

Type

Dict[NodeId, Tuple[Color, FastBuildingType]]

roads#

Mapping from edge to Color (if there is a road there). Contains inverted edges as well for ease of querying.

Type

Dict[EdgeId, Color]

connected_components#

Cache datastructure to speed up maintaining longest road computation. To be queried by Color. Value is a list of node sets.

Type

Dict[Color, List[Set[NodeId]]]

board_buildable_ids#

Cache of buildable node ids in board.

Type

Set[NodeId]

road_color#

Color of player with longest road.

Type

Color

road_length#

Number of roads of longest road

Type

int

robber_coordinate#

Coordinate where robber is.

Type

Coordinate

build_city(color, node_id)#
build_road(color, edge)#
build_settlement(color, node_id, initial_build_phase=False)#

Adds a settlement, and ensures is a valid place to build.

Parameters
  • color (Color) – player’s color

  • node_id (int) – where to build

  • initial_build_phase (bool, optional) – Whether this is part of initial building phase, so as to skip connectedness validation. Defaults to True.

buildable_edges(color: Color)#

List of (n1,n2) tuples. Edges are in n1 < n2 order.

buildable_node_ids(color: Color, initial_build_phase=False)#
continuous_roads_by_player(color: Color)#
copy()#
dfs_walk(node_id, color)#

Generates set of nodes that are “connected” to given node.

Parameters
  • node_id (int) – Where to start search/walk.

  • color (Color) – Player color asking

Returns

Nodes that are “connected” to this one

by roads of the color player.

Return type

Set[int]

find_connected_components(color: Color)#
Returns

connected subgraphs. subgraphs

might include nodes that color doesnt own (on the way and on ends), just to make it is “closed” and easier for buildable_nodes to operate.

Return type

nx.Graph[]

get_edge_color(edge)#
get_node_color(node_id)#
get_player_port_resources(color)#

Yields resources (None for 3:1) of ports owned by color

is_enemy_node(node_id, color)#
is_enemy_road(edge, color)#
is_friendly_node(node_id, color)#
is_friendly_road(edge, color)#
catanatron.models.board.get_edges(land_nodes=None)#
catanatron.models.board.get_node_distances()#
catanatron.models.board.longest_acyclic_path(board: Board, node_set: Set[int], color: Color)#

catanatron.models.coordinate_system module#

class catanatron.models.coordinate_system.Direction(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

EAST = 'EAST'#
NORTHEAST = 'NORTHEAST'#
NORTHWEST = 'NORTHWEST'#
SOUTHEAST = 'SOUTHEAST'#
SOUTHWEST = 'SOUTHWEST'#
WEST = 'WEST'#
catanatron.models.coordinate_system.add(acoord, bcoord)#
catanatron.models.coordinate_system.cube_to_axial(cube)#
catanatron.models.coordinate_system.cube_to_offset(cube)#
catanatron.models.coordinate_system.generate_coordinate_system(num_layers)#

Generates a set of coordinates by expanding outward from a center tile on (0,0,0) with the given number of layers (as in an onion :)). Follows BFS.

catanatron.models.coordinate_system.num_tiles_for(layer)#

Including inner-layer tiles

catanatron.models.coordinate_system.offset_to_cube(offset)#

catanatron.models.decks module#

Providers helper functions to deal with representations of decks of cards

We use a histogram / ‘frequency list’ to represent decks (aliased ‘freqdeck’). This representation is concise, easy to copy, access and fast to compare.

catanatron.models.decks.draw_from_listdeck(list1: List, amount: int, card: int)#
catanatron.models.decks.freqdeck_add(list1, list2)#
catanatron.models.decks.freqdeck_can_draw(freqdeck, amount: int, card: Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE'])#
catanatron.models.decks.freqdeck_contains(list1, list2)#

True if list1 >= list2 element-wise

catanatron.models.decks.freqdeck_count(freqdeck, card: Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE'])#
catanatron.models.decks.freqdeck_draw(freqdeck, amount: int, card: Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE'])#
catanatron.models.decks.freqdeck_from_listdeck(listdeck: Iterable[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']])#
catanatron.models.decks.freqdeck_replenish(freqdeck, amount: int, card: Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE'])#
catanatron.models.decks.freqdeck_subtract(list1, list2)#
catanatron.models.decks.starting_devcard_bank()#

Returns listdeck of devcards

catanatron.models.decks.starting_devcard_proba(card: Literal['KNIGHT', 'YEAR_OF_PLENTY', 'MONOPOLY', 'ROAD_BUILDING', 'VICTORY_POINT'])#
catanatron.models.decks.starting_resource_bank()#

Returns freqdeck of resource cards

catanatron.models.enums module#

class catanatron.models.enums.Action(color, action_type, value)#

Bases: tuple

Main class to represent action. Should be immutable.

The “value” is a polymorphic field that acts as the “parameters” for the “action_type”. e.g. where to ActionType.BUILD_SETTLEMENT or who to steal from in a ActionType.MOVE_ROBBER action.

We use this class to represent both the _intent_ of say “moving a robber to Tile (0,0,0) and stealing from Blue” as well as the final result of such a move. In moves like these where the intent is not enough to be used to reproduce the game identically, we use “None”s in the “value” container as placeholders for that information needed for fully reproducing a game. (e.g. card stolen, dev card bought, etc…)

See more on ActionType.

action_type#

Alias for field number 1

color#

Alias for field number 0

value#

Alias for field number 2

class catanatron.models.enums.ActionPrompt(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

BUILD_INITIAL_ROAD = 'BUILD_INITIAL_ROAD'#
BUILD_INITIAL_SETTLEMENT = 'BUILD_INITIAL_SETTLEMENT'#
DECIDE_ACCEPTEES = 'DECIDE_ACCEPTEES'#
DECIDE_TRADE = 'DECIDE_TRADE'#
DISCARD = 'DISCARD'#
MOVE_ROBBER = 'MOVE_ROBBER'#
PLAY_TURN = 'PLAY_TURN'#
class catanatron.models.enums.ActionType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

Type of action taken by a player.

See comments next to each ActionType for the shape of the corresponding .value field in Actions of that type.

ACCEPT_TRADE = 'ACCEPT_TRADE'#
BUILD_CITY = 'BUILD_CITY'#
BUILD_ROAD = 'BUILD_ROAD'#
BUILD_SETTLEMENT = 'BUILD_SETTLEMENT'#
BUY_DEVELOPMENT_CARD = 'BUY_DEVELOPMENT_CARD'#
CANCEL_TRADE = 'CANCEL_TRADE'#
CONFIRM_TRADE = 'CONFIRM_TRADE'#
DISCARD = 'DISCARD'#
END_TURN = 'END_TURN'#
MARITIME_TRADE = 'MARITIME_TRADE'#
MOVE_ROBBER = 'MOVE_ROBBER'#
OFFER_TRADE = 'OFFER_TRADE'#
PLAY_KNIGHT_CARD = 'PLAY_KNIGHT_CARD'#
PLAY_MONOPOLY = 'PLAY_MONOPOLY'#
PLAY_ROAD_BUILDING = 'PLAY_ROAD_BUILDING'#
PLAY_YEAR_OF_PLENTY = 'PLAY_YEAR_OF_PLENTY'#
REJECT_TRADE = 'REJECT_TRADE'#
ROLL = 'ROLL'#
class catanatron.models.enums.EdgeRef(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

EAST = 'EAST'#
NORTHEAST = 'NORTHEAST'#
NORTHWEST = 'NORTHWEST'#
SOUTHEAST = 'SOUTHEAST'#
SOUTHWEST = 'SOUTHWEST'#
WEST = 'WEST'#
class catanatron.models.enums.NodeRef(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

NORTH = 'NORTH'#
NORTHEAST = 'NORTHEAST'#
NORTHWEST = 'NORTHWEST'#
SOUTH = 'SOUTH'#
SOUTHEAST = 'SOUTHEAST'#
SOUTHWEST = 'SOUTHWEST'#

catanatron.models.map module#

class catanatron.models.map.CatanMap(tiles: Dict[Tuple[int, int, int], Union[LandTile, Port, Water]] = {}, land_tiles: Dict[Tuple[int, int, int], LandTile] = {}, port_nodes: Dict[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']], Set[int]] = {}, land_nodes: FrozenSet[int] = frozenset({}), adjacent_tiles: Dict[int, List[LandTile]] = {}, node_production: Dict[int, Counter] = {}, tiles_by_id: Dict[int, LandTile] = {}, ports_by_id: Dict[int, Port] = {})#

Bases: object

Represents a randomly initialized map.

static from_template(map_template: MapTemplate)#
static from_tiles(tiles: Dict[Tuple[int, int, int], Union[LandTile, Port, Water]])#
class catanatron.models.map.LandTile(id: int, resource: Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']], number: Optional[int], nodes: Dict[catanatron.models.enums.NodeRef, int], edges: Dict[catanatron.models.enums.EdgeRef, Tuple[int, int]])#

Bases: object

edges: Dict[EdgeRef, Tuple[int, int]]#
id: int#
nodes: Dict[NodeRef, int]#
number: Optional[int]#
resource: Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]#
catanatron.models.map.MINI_MAP_TEMPLATE = MapTemplate(numbers=[3, 4, 5, 6, 8, 9, 10], port_resources=[], tile_resources=['WOOD', None, 'BRICK', 'SHEEP', 'WHEAT', 'WHEAT', 'ORE'], topology={(0, 0, 0): <class 'catanatron.models.map.LandTile'>, (1, -1, 0): <class 'catanatron.models.map.LandTile'>, (0, -1, 1): <class 'catanatron.models.map.LandTile'>, (-1, 0, 1): <class 'catanatron.models.map.LandTile'>, (-1, 1, 0): <class 'catanatron.models.map.LandTile'>, (0, 1, -1): <class 'catanatron.models.map.LandTile'>, (1, 0, -1): <class 'catanatron.models.map.LandTile'>, (2, -2, 0): <class 'catanatron.models.map.Water'>, (1, -2, 1): <class 'catanatron.models.map.Water'>, (0, -2, 2): <class 'catanatron.models.map.Water'>, (-1, -1, 2): <class 'catanatron.models.map.Water'>, (-2, 0, 2): <class 'catanatron.models.map.Water'>, (-2, 1, 1): <class 'catanatron.models.map.Water'>, (-2, 2, 0): <class 'catanatron.models.map.Water'>, (-1, 2, -1): <class 'catanatron.models.map.Water'>, (0, 2, -2): <class 'catanatron.models.map.Water'>, (1, 1, -2): <class 'catanatron.models.map.Water'>, (2, 0, -2): <class 'catanatron.models.map.Water'>, (2, -1, -1): <class 'catanatron.models.map.Water'>})#

Standard 4-player map

class catanatron.models.map.MapTemplate(numbers: List[int], port_resources: List[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]], tile_resources: List[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]], topology: Mapping[Tuple[int, int, int], Union[Type[catanatron.models.map.LandTile], Type[catanatron.models.map.Water], Tuple[Type[catanatron.models.map.Port], catanatron.models.coordinate_system.Direction]]])#

Bases: object

numbers: List[int]#
port_resources: List[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]]#
tile_resources: List[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]]#
topology: Mapping[Tuple[int, int, int], Union[Type[LandTile], Type[Water], Tuple[Type[Port], Direction]]]#
class catanatron.models.map.Port(id: int, resource: Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']], direction: catanatron.models.coordinate_system.Direction, nodes: Dict[catanatron.models.enums.NodeRef, int], edges: Dict[catanatron.models.enums.EdgeRef, Tuple[int, int]])#

Bases: object

direction: Direction#
edges: Dict[EdgeRef, Tuple[int, int]]#
id: int#
nodes: Dict[NodeRef, int]#
resource: Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']]#
class catanatron.models.map.Water(nodes: Dict[catanatron.models.enums.NodeRef, int], edges: Dict[catanatron.models.enums.EdgeRef, Tuple[int, int]])#

Bases: object

edges: Dict[EdgeRef, Tuple[int, int]]#
nodes: Dict[NodeRef, int]#
catanatron.models.map.build_dice_probas()#
catanatron.models.map.build_map(map_type: Literal['BASE', 'TOURNAMENT', 'MINI'])#
catanatron.models.map.get_edge_nodes(edge_ref)#

returns pair of nodes at the “ends” of a given edge

catanatron.models.map.get_node_counter_production(adjacent_tiles: Dict[int, List[LandTile]], node_id: int)#
catanatron.models.map.get_nodes_and_edges(tiles, coordinate: Tuple[int, int, int], node_autoinc)#

Get pre-existing nodes and edges in board for given tile coordinate

catanatron.models.map.init_adjacent_tiles(land_tiles: Dict[Tuple[int, int, int], LandTile]) Dict[int, List[LandTile]]#
catanatron.models.map.init_node_production(adjacent_tiles: Dict[int, List[LandTile]]) Dict[int, Counter]#

Returns node_id => Counter({WHEAT: 0.123, …})

catanatron.models.map.init_port_nodes_cache(tiles: Dict[Tuple[int, int, int], Union[LandTile, Port, Water]]) Dict[Optional[Literal['WOOD', 'BRICK', 'SHEEP', 'WHEAT', 'ORE']], Set[int]]#

Initializes board.port_nodes cache.

Parameters

tiles (Dict[Coordinate, Tile]) – initialized tiles datastructure

Returns

Mapping from FastResource to node_ids that

enable port trading. None key represents 3:1 port.

Return type

Dict[Union[FastResource, None], Set[int]]

catanatron.models.map.initialize_tiles(map_template: MapTemplate, shuffled_numbers_param=None, shuffled_port_resources_param=None, shuffled_tile_resources_param=None) Dict[Tuple[int, int, int], Union[LandTile, Port, Water]]#

Initializes a new random board, based on the MapTemplate.

It first shuffles tiles, ports, and numbers. Then goes satisfying the topology (i.e. placing tiles on coordinates); ensuring to “attach” these to neighbor tiles (so as to not repeat nodes or edges objects).

Parameters

map_template (MapTemplate) – Template to initialize.

Raises

ValueError – Invalid tile in topology

Returns

Coordinate to initialized Tile mapping.

Return type

Dict[Coordinate, Tile]

catanatron.models.map.number_probability(number)#

catanatron.models.player module#

class catanatron.models.player.Color(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Bases: Enum

Enum to represent the colors in the game

BLUE = 'BLUE'#
ORANGE = 'ORANGE'#
RED = 'RED'#
WHITE = 'WHITE'#
class catanatron.models.player.HumanPlayer(color, is_bot=True)#

Bases: Player

Human player that selects which action to take using standard input

decide(game, playable_actions)#

Should return one of the playable_actions or an OFFER_TRADE action if its your turn and you have already rolled.

Parameters
  • game (Game) – complete game state. read-only.

  • playable_actions (Iterable[Action]) – options right now

class catanatron.models.player.Player(color, is_bot=True)#

Bases: object

Interface to represent a player’s decision logic.

Formulated as a class (instead of a function) so that players can have an initialization that can later be serialized to the database via pickle.

decide(game, playable_actions)#

Should return one of the playable_actions or an OFFER_TRADE action if its your turn and you have already rolled.

Parameters
  • game (Game) – complete game state. read-only.

  • playable_actions (Iterable[Action]) – options right now

reset_state()#

Hook for resetting state between games

class catanatron.models.player.RandomPlayer(color, is_bot=True)#

Bases: Player

Random AI player that selects an action randomly from the list of playable_actions

decide(game, playable_actions)#

Should return one of the playable_actions or an OFFER_TRADE action if its your turn and you have already rolled.

Parameters
  • game (Game) – complete game state. read-only.

  • playable_actions (Iterable[Action]) – options right now

class catanatron.models.player.SimplePlayer(color, is_bot=True)#

Bases: Player

Simple AI player that always takes the first action in the list of playable_actions

decide(game, playable_actions)#

Should return one of the playable_actions or an OFFER_TRADE action if its your turn and you have already rolled.

Parameters
  • game (Game) – complete game state. read-only.

  • playable_actions (Iterable[Action]) – options right now

Module contents#