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.




