Editorial illustration: What the Hokm bot remembers

What the Hokm bot remembers

The problem I needed to solve

A bot should not inspect opponents’ hidden cards to guess play. I needed memory of played cards and public evidence that a seat could no longer follow a suit.

Implementation in this snapshot

HokmBotMemoryModel.RecordCardPlayed records each instance ID once. When a player fails to follow lead suit, voidSuitsBySeat marks that seat as void in that suit.

The design decision and its cost

ResetForNewHand clears observations, IDs and void flags, and sets the new trump. RemainingTrumpCountEstimate subtracts observed trump cards from thirteen.

Current boundaries

An estimate of remaining trump does not reveal their exact locations. Absence of evidence is not proof that a seat holds a suit; public knowledge and strategic inference must stay distinct.

Observing a void suit rather than reading a hidden hand

Suppose a trick starts with Spades and a seat plays another suit. In valid Hokm, that is public evidence that the seat is void in Spades. RecordCardPlayed uses FailedToFollowLeadSuit to store this in voidSuitsBySeat. The inference depends on prior rule enforcement: recording an illegal move can corrupt strategic knowledge. Memory should receive accepted gameplay actions rather than raw card touches. It does not rerun move validation or establish input trust.

Recording checks readiness, seat validity, standard-card attributes and lead suit. playedInstanceIds prevents recording the same instance twice, while playedCards stores observation details. HasCardInstanceBeenPlayed asks about a particular object; HasCardBeenPlayed searches by suit and rank. Those observations support higher-card estimation in a standard Hokm deck. Extending the model to decks with repeated suit-rank combinations would require reconsidering its counting assumptions.

Remaining trump is estimated as thirteen minus observed trump cards, clamped at zero. It includes every unplayed trump, including the bot’s own unplayed cards; consumers must subtract their own known holdings when appropriate. ResetForNewHand clears IDs, observations and void flags and sets the new trump. Clear also marks IsReady false. These distinct lifecycle operations prevent one hand’s observations from being mistaken for evidence about the next.

What this stage taught me

For me, memory means converting observable actions into usable information. That is more explainable than a bot that mysteriously finds the right card by reading hidden state.

Explore Dalo

Latest devlogs

Editorial illustration: Pasur launch and telemetry in the shared structure

Pasur launch and telemetry in the shared structure

Adding Pasur needs both a correct mode handoff and valid public telemetry.

Read article
Editorial illustration: Presenting selection and captures in Pasur

Presenting selection and captures in Pasur

Pasur motion should explain which hand card was played and which table cards were captured.

Read article
Editorial illustration: Pasur bot decisions from capture options

Pasur bot decisions from capture options

My teammate’s Pasur bot chooses among legal options without inspecting hidden opposing cards.

Read article
Dalo