AlphaSettler
From the AlphaSettler wiki
AlphaSettler is a Settlers of Catan bot project that simulates the board game in Rust and uses Information-set Monte Carlo tree search to find strong moves. It is designed for researchers and bot developers who want to benchmark Catan-playing strategies and compare them against other implementations. The project decomposes into a core game engine with complete rule enforcement, a tree search subsystem that samples hidden information, and a match system that evaluates bots across multiple games with common random numbers. Python bindings and a command-line interface expose these components to the research layer. AlphaSettler includes a subsystem for dice rolls and development cards, a rules engine tracking road and army awards, and integration with Catanatron for differential testing and cross-engine validation.
flowchart LR n1[["Action space"]] n2[["Bot arena"]] n3[["CLI interface"]] n4[["Game engine"]] n5[["Game outcomes"]] n6[["Game rules"]] n7[["Oracle translation"]] n8[["Performance testing"]] n9[["Project documentation"]] n10[["Python bindings"]] n11[["Random bot"]] n12[["Search algorithm"]] n5 -->|"26 calls, 17 imports"| n6 n4 -->|"14 calls, 7 imports"| n6 n10 -->|"13 calls, 6 imports"| n2 n6 -->|"1 call, 16 imports"| n4 n12 -->|"4 calls, 12 imports"| n4 n5 -->|"15 imports"| n4 n6 -->|"7 calls, 8 imports"| n1 n2 -->|"10 calls, 4 imports"| n6 n2 -->|"7 calls, 7 imports"| n12 n5 -->|"2 calls, 11 imports"| n1 n3 -->|"9 calls, 3 imports"| n7 n2 -->|"11 imports"| n4 n4 -->|"11 imports"| n1 n4 -->|"2 calls, 8 imports"| n5 n4 -->|"6 calls, 4 imports"| n12 n8 -->|"5 calls, 5 imports"| n12 n12 -->|"5 calls, 4 imports"| n5 n6 -->|"2 calls, 6 imports"| n5 n7 -->|"2 calls, 6 imports"| n3 n8 -->|"4 calls, 4 imports"| n5 n2 -->|"4 calls, 3 imports"| n5 n8 -->|"5 imports"| n4 n10 -->|"4 imports"| n4 n11 -->|"2 calls, 2 imports"| n5 n11 -->|"2 calls, 2 imports"| n12 n5 -->|"1 call, 2 imports"| n12 n6 -->|"2 calls, 1 import"| n12 n11 -->|"1 call, 2 imports"| n2 n11 -->|"3 imports"| n4 n12 -->|"2 calls, 1 import"| n6 n2 -->|"2 imports"| n1 n10 -->|"1 call, 1 import"| n5 n10 -->|"1 call, 1 import"| n12 n12 -->|"2 imports"| n1 n1 -->|"1 import"| n6 n2 -->|"1 import"| n10 n2 -->|"1 import"| n11 n4 -->|"1 import"| n8 n8 -->|"1 import"| n1 n10 -->|"1 import"| n6
Purpose and features
The action space encodes all 665 possible Catan moves as integer identifiers from 0 to 664, allowing moves to be passed to neural networks and stored compactly in game records.[1] (see Action space) Players can run matches between competing bots through the command-line interface, comparing their win rates and statistical differences in victory points and turn counts. (see CLI interface, Bot arena) Researchers can benchmark the throughput of the game engine and search algorithm against Catanatron and catan-rl to measure performance improvements. (see Performance testing)
Bot developers can implement custom strategies by defining a Bot trait in Rust, with examples including uniform random selection, a greedy heuristic, and an ISMCTS bot that reads observations redacted for its seat.[2] (see Bot arena, Random bot) The oracle translation layer allows AlphaSettler bots to play inside Catanatron and runs differential tests that classify rule divergences as expected or report mismatches.[3] (see Oracle translation) Game positions can be captured and resumed, imported from Catanatron snapshots for cross-engine play, and exported as JSONL records that track which moves were legal at each step. (see Game engine)
Layers
- The interface layer in
bindings/,alphasettler/andoracle/exposes the engine to research tools through PyO3 bindings, a command-line interface for running matches and training, and the oracle adapter for Catanatron integration.[4]
Request paths
- In the play-one-action path, the CLI calls the arena which calls a bot's
act()method with a redacted observation, receives a legal action, passes it to the engine'sapply()method which dispatches to rules and outcomes submodules that updateStateand emitEvents.[5][6] - In the search path, the arena calls the ISMCTS bot's
act()which invokes the search module's tree search, which creates aBeliefStatefrom a redacted observation, samples worlds consistent with opponent hands usingsample_cards()from roll.rs, and evaluates leaves with pluggableEvaluatortrait implementations.[7] - In the differential test path, the CLI imports a Catanatron snapshot via oracle translation, converts the Catanatron action to an AlphaSettler action, applies it to the AlphaSettler engine, and compares the resulting observations and rolled outcomes to detect divergences.[3]
- In the training path, the CLI runs many self-play games via the arena using the ISMCTS bot, collects game records with legal action sets, and fits heuristic weights by replaying games and computing log-likelihood gradients.[8]
- A single game turn in the arena loop calls
legal_actions()from the engine to fill a buffer of legal actions, asks the current bot'sact()method to choose one, passes it throughgame.apply()which calls outcomes and rules functions, and broadcasts the emittedEvents to all bots viaobserve().[2]
Feature dependencies
- Game outcomes depends on game rules to check legality and action space types to represent moves, and is called by the engine's apply logic to execute rolls, resource production, and development card effects.[5]
- Game rules depends on game engine state and action encoding to enumerate legal moves, and is used by outcomes to check trade legality and bots to evaluate settlement values.[9]
- Game engine depends on action space for move representation, rules for legality, and outcomes for applying chance events, and provides
StateandObservationtypes to bots and search.[10] - Search algorithm depends on game engine state and observation types, samples from outcomes like development card distributions, and returns strong actions to bots.[7]
- Bot arena depends on game engine state and events, calls rules to check legality, uses search for ISMCTS bots, and implements the
Bottrait for random and greedy strategies.[6] - Python bindings wraps game engine, arena, and search via PyO3, exposing
GameandBotclasses to Python and translating between Python dicts and Rust structures.[4] - CLI interface depends on Python bindings to access the engine and arena, calls oracle translation to run differential tests, and produces JSONL records.[11]
- Oracle translation depends on game engine and action space to translate Catanatron positions, and is used by the CLI for differential testing and cross-engine validation.[3]
- Performance testing imports engine, outcomes, rules, and search to benchmark throughput and profile time spent by phase and action type.[12]
- Random bot depends on game engine observation and action types, implements the
Bottrait, and is tested in the arena.[13]
References
-
^
engine/src/action.rs:L36@baf5f69(ACTION_SPACE_SIZE) -
^ a b
bots/src/arena.rs:L5@baf5f69 -
^ a b c
oracle/diff.py:L23@baf5f69 -
^ a b
bindings/src/lib.rs:L11@baf5f69(PyGame) -
^ a b
engine/src/apply.rs:L5@baf5f69 -
^ a b
bots/src/arena.rs:L7@baf5f69 -
^ a b
search/src/belief.rs:L11@baf5f69 -
^
bindings/src/lib.rs:L326@baf5f69(selfplay) -
^
engine/src/rules/awards.rs:L4@baf5f69 -
^
engine/src/board.rs:L4@baf5f69 -
^
alphasettler/cli.py:L151@baf5f69(_oracle_missing) -
^
engine/benches/engine.rs:L2@baf5f69 -
^
bots/src/random.rs:L4@baf5f69
This page was last edited on 2 October 2026, at commit baf5f69.