Overview
Project summary
- What it is
- Rust Ashton Tablut player for the University of Bologna AI Fundamentals Tablut Challenge.
- My role
- I built the protocol adapter, local rule engine, compact state model, deadline-aware search and final guard.
- Core stack
- Rust, framed JSON over TCP, u128 occupancy masks, packed moves, alpha-beta, transposition table.
- Repository
- The repository includes protocol handling, legal move generation, search, timeout control and tests.
Engine flow
I built Kyndill to play Ashton Tablut under a strict referee protocol and response deadline. Each turn arrives as JSON over TCP, framed by a 4-byte big-endian length prefix. The protocol adapter decodes that payload into typed local state, which the engine then searches.
I kept the Ashton Tablut rules in a local engine for the 9 x 9 board. It generates moves, checks captures and king escape conditions, and produces legal child states, so the search code never needs to construct protocol actions.
Engine flow
From referee state to legal action
Referee framed JSON
TCP payload with a 4-byte big-endian length prefix.
Protocol adapter
The adapter decodes the role, board, turn and deadline.
Typed state
It converts the external state into checked local structures.
Local rule engine
The local engine generates only legal Ashton Tablut moves.
Compact search state
The search uses occupancy masks, packed moves and hashing.
Iterative deepening
The engine completes each depth with alpha-beta pruning.
Candidate move
The engine keeps the best fully completed legal result.
Final guard
The final guard checks legality and the remaining time before sending.
Framed JSON action
The adapter returns one validated move to the referee.
Compact board state
The search core uses a small checked state, so it does not need to interpret the referee payload again at every step.
- Board
- 9 x 9 Ashton Tablut state
- Masks
- u128 occupancy bitsets
- Moves
- Packed move representation
- Table
- Transposition table entries
Fallback before timeout
- Response window
Each turn starts with a fixed response window.
- Completed depth
The engine stores only completed legal results.
- Deadline check
The engine stops deeper work as the deadline approaches.
- Fallback
The player sends the last completed result or a deterministic prevalidated fallback.
Search under a deadline
The search is deterministic alpha-beta with iterative deepening. After completing a depth, the engine saves its best legal move before starting the next one. If the deadline interrupts a deeper search, the previous result is still available.
The search path uses compact u128 occupancy masks, packed moves, incremental hashing, a bounded transposition table, and killer and history ordering.
Safety guard
Before writing a response, Kyndill checks both legality and the remaining time. If deeper search cannot finish safely, it sends either the last completed iterative-deepening result or a deterministic fallback that has already been checked.
Safety boundary
- Decode
Read the framed JSON payload and convert it into typed local state.
protocol - Generate
Build legal Ashton Tablut moves from the local rule engine.
rules - Search
Run iterative-deepening alpha-beta search within the move budget.
engine - Guard
Send a legal move before the deadline, using the prevalidated deterministic fallback if needed.
deadline
Implementation notes
- V4 is the default runtime profile.
- White uses static installed weights tuned offline.
- Black stays frozen as a manually tuned asymmetric path.
- Runtime play uses installed static profiles only.