Inspiration
The core idea came from Usogui — a manga built around high-stakes psychological gambling, where every bet is really a battle of reading your opponent. That tension between calculated logic and pure bluff is what made poker feel like the right game to build an AI opponent for, rather than something simpler.
The terminal came from a more practical (and slightly mischievous) place: playing poker on a website during a lecture is an easy way to get caught — a colorful browser tab stands out immediately. A plain black terminal window, on the other hand, looks exactly like every other coding assignment on the screen. Bluffbot was built to blend in.
What it does
Bluffbot is a terminal-based, heads-up (1v1) Texas Hold'em game against an AI opponent that isn't just running on fixed rules. Its betting behavior is shaped by a Random Forest model trained on 600,000+ real poker hands, layered on top of hand-strength logic, controlled randomness, and occasional bluffing — so it doesn't play "perfectly," it plays like something closer to a real, occasionally unpredictable opponent.
On top of that, Bluffbot talks — using an LLM (Groq) to generate live, in-character commentary as it thinks through decisions and reacts to hands, backed by a local fallback so the game never breaks even if the API is unavailable. A small ASCII mascot reflects its mood as it plays.
How we built it
Game engine: a full Texas Hold'em betting loop (pre-flop → flop → turn → river → showdown) with proper multi-raise betting rounds, all-in handling, and input validation, ported and adapted from an earlier C prototype of the same core logic.
Hand evaluator: ranks 5–7 card hands (including edge cases like Ace-low straights and board-paired ties) to determine winners.
AI opponent: rule-based decision-making (hand strength + pot odds + bluffing + randomness) as the foundation, with a trained Random Forest model layered in as an aggression/confidence modifier.
Training data: the Random Forest was trained on the IRC Poker Database, using hand records spanning 2021–2025, totaling 600,000+ rows of real played hands.
LLM commentary: Groq-powered, real-time table talk at key decision points, with a local templated fallback for reliability.
Mascot: lightweight ASCII art reflecting the AI's mood based on its last action.
Challenges we ran into
Betting logic bugs: the initial betting round only allowed a single exchange per street, meaning a raise couldn't actually be responded to. This was rewritten as a proper multi-exchange loop and stress-tested against 200+ simulated hands to catch infinite loops and chip-conservation bugs.
Model overfitting: our first trained Random Forest came out to 2.6GB — a clear sign of runaway tree depth. A RandomizedSearchCV hyperparameter search fixed this, bringing the model down to 6.8MB while closing the train/test MSE gap, confirming the fix actually worked rather than just hiding the problem.
LLM integration hiccups: shipped through several real-world API issues — deprecated model names, free-tier rate limits far tighter than expected, and empty responses from reasoning models silently eating their token budget on internal reasoning. Solved with a resilient design: real API calls with an instant, seamless local fallback, so the game never breaks even when the API does.
Accomplishments that we're proud of
Catching and fixing a genuine overfitting disaster. Our first trained model came out to 2.6GB — instead of shipping it and hoping for the best, we diagnosed the cause (unconstrained tree depth), ran a proper hyperparameter search, and verified the fix numerically by comparing train vs. test MSE, not just eyeballing a smaller file size.
Rewriting the core betting logic from scratch, correctly. The original betting loop only allowed a single exchange per street — a real bug that would've broken multi-raise hands entirely. We rebuilt it into a proper state machine and stress-tested it against 200+ simulated hands to confirm chip totals stayed conserved and no edge case caused an infinite loop or a crash.
Building an AI opponent with real signal behind it, not just randomness. Bluffbot's decisions are shaped by a Random Forest trained on 600,000+ real poker hands from the IRC Poker Database (2021–2025) — a genuine ML component driving gameplay, not window dressing.
Shipping resilient LLM integration despite real infrastructure hurdles. We worked through deprecated model names, unexpectedly tight free-tier rate limits, and empty responses from reasoning models silently consuming their token budget — and came out the other side with a design that gracefully falls back to local commentary the moment anything goes wrong, so the game never breaks mid-demo.
A hand evaluator that holds up under real scrutiny. We didn't just trust it — we deliberately played out and manually verified tricky edge cases (Ace-low straights, board-paired two-pair tiebreaks) during live testing, and it got every one of them right.
What we learned
A small file size doesn't automatically mean a healthy model. Only comparing train vs. test error actually confirmed our overfitting fix worked.
"Runs without crashing" and "is correct" are different bars. The original betting round never threw an error — it just silently produced wrong poker logic, which is why real stress-testing matters more than casual play-testing.
Silent failures are the most dangerous kind. Free-tier APIs shift fast (deprecated models, tight rate limits, empty responses from reasoning models) — we learned to always build a way to surface the real error instead of assuming a fallback means "no internet."
AI-assisted development still demands real understanding. The actual skill isn't writing code fast — it's explaining why something works and making deliberate scope calls, like choosing not to build multiplayer this cycle even though it was tempting.
What's next for Bluffbot
Multiplayer: room codes that let friends connect and play against each other over a network, not just against the AI.
Multiple AI opponents: extending from heads-up to full multi-way pots, with proper side-pot handling.
Deeper Random Forest feature tracking (live VPIP tracking per session rather than a fixed difficulty knob).
Built With
- claude
- claude-code
- git
- groq
- joblib
- llm
- machine-learning
- pandas
- python
- random-forest
- sckit-learn
Log in or sign up for Devpost to join the conversation.