Explainable game AI · Egyptian Basra

KotchAIna

A playable card engine where every move can unfold into its legal captures, strategic utility, hidden-card assumptions, and exact endgame. I built the rules, solver, opponent model, AI policy, telemetry, and browser interface.

Combinatorial searchOpponent inferenceExplainable telemetryPython · React 19
A move you can inspectKotchAIna live game with AI telemetry
legal capture → utility → belief-aware move → explanation
52cards tracked as one state partition
271automated tests in the project suite
576maximum four-versus-four play orders
7♦Chameleon capture and bonus solver

01 · Rules as code

Search the floor
before scoring.

A numeric play can take an exact match, a subset whose capture values sum to the played value, or several disjoint legal groups. The solver enumerates candidates, removes duplicates, combines non-overlapping groups, and only then lets the policy compare moves. Jacks, kings, queens, and the 7♦ enter through explicit special rules.

7♦
{9}sum = 9
{3, 6}sum = 9

The 7♦ always captures the floor. The Chameleon solver searches target values 1–10; here, two disjoint groups share target 9, so the clear also qualifies for the special bonus.

Rule correctness stays separate from strategy. The capture engine returns legal, deduplicated groups and whether the floor is cleared. This makes the difficult combinatorial step testable without embedding preferences inside it.

State stays accountable. Hands, floor, deck, captured piles, turn, and last capturer partition the full deck. Every transition can be checked against that invariant.

\[G(v, F) = \left\{\, S \subseteq F \;:\; \sum_{x \in S}\mathrm{capture\_value}(x) = v \,\right\}\]The engine enumerates legal groups with the capture-value function, then searches disjoint families so the same floor card cannot be captured twice.

02 · Policy

Explain why one
move wins.

The evaluator scores legal moves with distinct terms rather than a single opaque value. The interface can reveal which capture groups existed, which point cards were taken, whether a Basra was created, and which strategic pressure changed the selection.

BasraReward a qualifying table clear.
Capture valueScore the actual point value of captured cards.
Card countPrefer useful mass capture when values tie.
StrategyAdjust for denial, timing, risk, and power-card preservation.
\[U(\mathrm{move}) = w_B\cdot\mathrm{Basra} + w_V\cdot\mathrm{captured\_value} + w_C\cdot\mathrm{captured\_count} + \mathrm{strategic\_terms}\]The weights change preference, not legality. The rule engine produces the candidate set before this utility function is allowed to rank it.
Open the decision order

Candidate captures are ordered lexicographically by captured-card count and capture value before strategic evaluation. Difficulty modes alter how strictly the interface follows the highest-scoring choice. This preserves one inspectable evaluator while allowing easier play to introduce controlled variation.

03 · Hidden information

Learn from what
did not happen.

The tracker begins with unseen cards, then updates relative plausibility from public play. If an opponent discards without taking a capture that a candidate hand card would have enabled, that candidate can be removed or downweighted. This is a heuristic probabilistic model under behavioral assumptions, designed to expose its reasoning rather than present calibrated hand probabilities.

One observed non-capture changes the field

Candidate 4.76
Candidate 7.18
Candidate J.48
Candidate 7♦.09

This panel explains the update mechanism. The displayed weights are relative scores, not a claim that the opponent holds a card with a calibrated probability.

04 · Inspection surface

The AI shows
its working state.

The gameplay interface turns internal decisions into a readable layer: move preview, utility terms, estimated win pressure, entropy, deck potency, surprisal, momentum, and turning points. The goal is to let a player question a move without reading the engine source.

05 · Exact search

When uncertainty
disappears.

After the deck is empty and both hands are known, the engine can replace heuristic opponent modeling with exact minimax. A four-card hand on each side has at most \(4! \times 4! = 576\) interleaved play orders before memoization and pruning reuse equivalent states.

Small enough to solve exactly

Stateknown hands + floor
Branchlegal card plays
Recurseopponent response
Memoizereuse state value

06 · Engine map

The whole engine,
without leaving.

The formal architecture is rendered as the page itself: deterministic rules produce moves, the information model estimates what remains unseen, strategy scores candidates, exact search takes over when possible, and telemetry keeps each decision visible.

StatePartition 52 cards

Hands, floor, deck, captures, turn, and last capturer.

RulesEnumerate captures

Exact matches, value subsets, disjoint groups, and special cards.

InferenceUpdate plausibility

Public observations eliminate or downweight unseen candidates.

PolicyRank legal moves

Capture value, Basra, denial, timing, and risk.

ExplainEmit telemetry

Candidates, utility terms, belief changes, and turning points.

Previous project← M.A.C.E.Next projectMoaLLM →