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.inner_maritime_trade_possibilities(hand_freqdeck, bank_freqdeck, port_resources)#
This inner function is to make this logic more shareable
- catanatron.models.actions.ncr(n, r)#
n choose r. helper for discard_possibilities
catanatron.models.board module#
- class catanatron.models.board.Board(catan_map=None, initialize=True)#
Bases:
objectEncapsulates 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_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.
- 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.coordinate_system module#
- class catanatron.models.coordinate_system.Direction(value, names=<not given>, *values, 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:
tupleMain class to represent action. Should be immutable, and so the choice of a namedtuple.
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 the _intent_ of say “moving a robber to Tile (0,0,0) and stealing from Blue”.
- 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=<not given>, *values, 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.ActionRecord(action, result)#
Bases:
tupleRecords an Action along with the result of that action. Useful for showing an “action log” in a UI, fully replaying a game, or undoing actions to a State.
The “result” field is polymorphic depending on the action_type. - ROLL: result is (int, int) 2 dice rolled - DISCARD: result is List[Resource] discarded - MOVE_ROBBER: result is card stolen (Resource|None) - BUY_DEVELOPMENT_CARD: result is card - …for the rest, result is None since they are deterministic actions
- action#
Alias for field number 0
- result#
Alias for field number 1
- class catanatron.models.enums.ActionType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#
Bases:
EnumType 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'#
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:
objectRepresents a randomly initialized map.
- static from_template(map_template: MapTemplate, number_placement: Literal['official_spiral', 'random'] = 'official_spiral')#
- static from_tiles(tiles: Dict[Tuple[int, int, int], Union[LandTile, Port, Water]])#
- 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.tiles.LandTile'>, (1, -1, 0): <class 'catanatron.models.tiles.LandTile'>, (0, -1, 1): <class 'catanatron.models.tiles.LandTile'>, (-1, 0, 1): <class 'catanatron.models.tiles.LandTile'>, (-1, 1, 0): <class 'catanatron.models.tiles.LandTile'>, (0, 1, -1): <class 'catanatron.models.tiles.LandTile'>, (1, 0, -1): <class 'catanatron.models.tiles.LandTile'>, (2, -2, 0): <class 'catanatron.models.tiles.Water'>, (1, -2, 1): <class 'catanatron.models.tiles.Water'>, (0, -2, 2): <class 'catanatron.models.tiles.Water'>, (-1, -1, 2): <class 'catanatron.models.tiles.Water'>, (-2, 0, 2): <class 'catanatron.models.tiles.Water'>, (-2, 1, 1): <class 'catanatron.models.tiles.Water'>, (-2, 2, 0): <class 'catanatron.models.tiles.Water'>, (-1, 2, -1): <class 'catanatron.models.tiles.Water'>, (0, 2, -2): <class 'catanatron.models.tiles.Water'>, (1, 1, -2): <class 'catanatron.models.tiles.Water'>, (2, 0, -2): <class 'catanatron.models.tiles.Water'>, (2, -1, -1): <class 'catanatron.models.tiles.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.tiles.LandTile], Type[catanatron.models.tiles.Water], Tuple[Type[catanatron.models.tiles.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']]]#
- catanatron.models.map.build_dice_probas()#
- catanatron.models.map.build_map(map_type: Literal['TOURNAMENT', 'MINI', 'BASE'], number_placement: Literal['official_spiral', 'random'] = 'official_spiral')#
- 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, number_placement: Literal['official_spiral', 'random'] = 'official_spiral') 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=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#
Bases:
EnumEnum to represent the colors in the game
- BLUE = 'BLUE'#
- ORANGE = 'ORANGE'#
- RED = 'RED'#
- WHITE = 'WHITE'#
- class catanatron.models.player.HumanPlayer(color, is_bot=False, input_fn=<built-in function input>)#
Bases:
PlayerHuman player that selects which action to take using standard input
- class catanatron.models.player.Player(color, is_bot=True)#
Bases:
objectInterface 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.
- reset_state()#
Hook for resetting state between games
- class catanatron.models.player.RandomPlayer(color, is_bot=True)#
Bases:
PlayerRandom AI player that selects an action randomly from the list of playable_actions