Selected work
CountLab
A training and analysis suite for advantage blackjack play, where the numbers the interface reports are generated by simulation engines rather than typed in by hand.
The problem
Counting cards is a drilling problem, not a reading problem. You can learn Hi-Lo in an afternoon and still be useless at a table, because the actual skill is holding an accurate running count across a full six deck shoe while making correct playing decisions at speed, with a dealer waiting on you.
Most training tools quiz you on isolated hands. That is the one thing a real shoe never gives you. Cards are dealt without replacement, so every hand depends on the ones before it, and that dependence is the entire mechanism the count exploits. A trainer built on independently generated hands feels like practice and teaches nothing.
The second problem is the one I cared about more. Any tool that reports your expected value at a given true count is making a quantitative claim. If that number is a guess in a nice interface, the tool is worse than useless: it teaches confident wrong answers to people who are about to bet on them.
What I built
CountLab is a monorepo. The deployed part is a statically exported Next.js app; behind it sit separate Python engines that produce the figures it shows.
The training side runs full shoe drills against a configurable table: deck count, penetration, the dealer rule on soft 17, double and resplit rules, and surrender. Running count, true count, decks remaining and coach accuracy are tracked live as you play, with focused drills for running count, true count, basic strategy and index deviations alongside.
The analysis side is a set of tools rather than one calculator: a game and bankroll lab reporting expected value per hour, standard deviation, risk of ruin and required bankroll for a specific game and bet ramp; a bet spread recommender; a session simulator; and a scenario comparison view.
Three casino games have their own solvers. Ultimate Texas Hold'em conditions every legal decision on exactly one exposed dealer card and checks your raise, check and fold decisions against an exact solver as you play. Chase the Flush has a staged solver for its 3x, 2x and 1x rounds. Double Down Madness pairs exact combinatorial evaluation with Monte Carlo to answer whether the variant is countable at all.
Decisions
Deal a real shoe, not independent hands.
The count only means anything because cards are removed without replacement. Generating each hand independently would have been far simpler and would have produced a trainer that feels correct while teaching the wrong instincts. The drill deals from a persistent shoe through to the cut card, which is also what makes decks remaining, true count conversion and penetration meaningful rather than decorative.
Compute the numbers offline, ship the results.
The per true count expected value figures come out of a Python simulation run ahead of time and ship as data. The browser does presentation only. That keeps the front end fast, but the real reason is auditability: when a rule changes, the numbers are regenerated and the diff is reviewable, instead of the logic sitting buried in a component.
Check the strategy against a published source, not against itself.
A solver that agrees with itself proves nothing. The Ultimate Texas Hold'em work is validated against published rules figures, and the interface links that source directly rather than asking you to take the output on faith. Where a figure has been audited, the interface says so rather than leaving you to assume it.