Skip to content

A high-performance, vectorized Poker River Solver in Python. Features interactive GTO visualization and a Play-vs-Bot training mode.

Notifications You must be signed in to change notification settings

Ojhaharsh/OpenRiver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Open Source River Solver

A high-performance, vectorized Poker River Solver built in Python.

This tool calculates Game Theory Optimal (GTO) strategies for No-Limit Texas Hold'em river scenarios. It was built to address common issues with LLM-generated solvers by ensuring mathematical correctness (handling blockers/pot odds), high performance (vectorized NumPy engine), and a clean, interactive visualization.

Features

  • Vectorized Engine: Uses NumPy memory arrays to solve full 52-card deck scenarios at ~7,000 iterations/second in pure Python (no C++ compilation required).
  • Dynamic Solving: Input any board texture (e.g., "Ah Ks Qh Jh Th") to rebuild the game tree and re-solve on the fly.
  • Interactive Analysis: A heatmap visualization (index.html) to study GTO ranges, bluffing frequencies, and value betting.
  • Play vs Bot: A real-time training mode (play.html) where you can play hands against the solution you just generated.
  • Correct Logic: Properly handles card removal (blockers), pot odds, and polarized betting ranges.

Installation

  1. Install Python 3.8+
  2. Install dependencies:
    pip install -r requirements.txt
    (Dependencies: numpy, fastapi, uvicorn, treys)

Quick Start

1. Start the Solver Engine

Run the backend server. This handles the heavy math and serves the API.

python main.py

You will see Uvicorn running on http://0.0.0.0:8000.

Note: The server will:

  • Auto-create logs/ directory for activity logs
  • Auto-create strategy_cache/ directory to cache solutions
  • Read configuration from config.json (optional, falls back to defaults)

To modify settings, edit config.json and restart the server.

Analyze Strategies (The Lab)

Open index.html in your web browser.

  • Input Board: Type a board like Ks Th 7s 4d 2s in the text box.
  • Click Solve: The engine will retrain for that specific board.
  • Study: View the 13x4 grid to see exactly which hands to Bet (Red), Check/Call (Green), or Fold (Blue).

Play Against the AI (The Arena)

Open play.html in your web browser.

  • The game automatically loads the board and strategy you solved in step 2.
  • Play: You will be dealt a hand (that doesn't conflict with the board).
  • Test: Try to bluff the bot or catch its bluffs. The bot plays according to the GTO probabilities calculated by the engine.

⚠️ Important: If you solve a NEW board in index.html, you must refresh play.html to load the new strategy and board cards.

  • Open index.html and solve a unique board, e.g., Ah Kh Qh Jh Th (All Hearts).
  • Open play.html.
  • Look at the Table: You should see A♥ K♥ Q♥ J♥ T♥ on the board.
  • Look at the Deck: You should never be dealt a Heart (since they are all on the board).

How It Works

The Solver (Backend)

  • Game Logic: The solver maps the 52-card deck into integer arrays. It pre-calculates a Payoff Matrix (52x52) using the treys evaluator to determine the winner of every possible showdown instantly.
  • Vectorized CFR: Instead of traversing a tree of objects (slow), the algorithm performs matrix operations on flat NumPy arrays (fast). This allows it to simulate millions of poker hands in seconds.
  • API: main.py uses FastAPI to expose endpoints. When you change the board, the server rebuilds the game object and retrains the model from scratch.
  • Input Validation: All board inputs are validated for correct format, duplicates, and valid card values before solving.
  • Error Handling: The API returns meaningful error messages with HTTP status codes for invalid inputs.
  • Logging: All activity is logged to logs/poker_solver_*.log for debugging and monitoring.
  • Configuration: Customizable settings via config.json (default iterations, pot sizes, API port, etc.).
  • Caching: Solved strategies are automatically saved to strategy_cache/ and reused on subsequent requests.

The Bot (Frontend)

The bot in play.html is not random. It is connected directly to the solver's brain:

  1. Fetch: On load, it downloads the exact strategy matrix generated by main.py.
  2. Lookup: When it's the bot's turn, it looks up its specific hand (e.g., Q♥) in the strategy matrix.
  3. Decision: It uses the calculated probabilities (e.g., "Call 20%, Fold 80%") to make a weighted random decision.

API Endpoints

Endpoint Method Description
/train GET Train solver on a board. Params: board, iters
/solution GET Get current solution and strategies
/cache/list GET List all cached board solutions
/cache/clear DELETE Clear the strategy cache
/docs GET Interactive API documentation (Swagger UI)

Configuration

Edit config.json to customize:

  • default_board - Starting board cards
  • default_iterations - Training iterations per solve
  • max_iterations - Safety limit (default: 1,000,000)
  • log_level - DEBUG, INFO, WARNING, ERROR, CRITICAL
  • api_port - Server port (default: 8000)
  • cors_origins - Allowed CORS origins
  • pot_sizes - Customizable pot values by game node

Debugging

Check logs:

tail -f logs/poker_solver_*.log

Invalid inputs will return clear error messages:

# Duplicate cards
curl "http://localhost:8000/train?board=As+As+2s+3s+4s"
# Returns: {"detail": "Invalid board: Duplicate card 'As' in board"}

# Too many iterations
curl "http://localhost:8000/train?iters=2000000"
# Returns: {"detail": "Invalid iterations: Iterations must not exceed 1,000,000"}

Verify caching is working:

# First call (trains)
curl "http://localhost:8000/train?board=Ks+Th+7s+4d+2s"
# Response includes: "cached": false

# Second call (loads from cache - should be instant)
curl "http://localhost:8000/train?board=Ks+Th+7s+4d+2s"
# Response includes: "cached": true

Production Notes

  • ✅ All inputs are validated before processing
  • ✅ Meaningful error messages for debugging
  • ✅ Comprehensive logging to file and console
  • ✅ Strategy caching for performance
  • ✅ Configuration-driven (no code changes needed for settings)
  • ✅ Type hints and documentation for all code
  • ✅ 100% backward compatible with existing applications

Credits

Built as an open-source improvement on existing lightweight river solvers, focusing on architectural modularity and vectorization speedups.

About

A high-performance, vectorized Poker River Solver in Python. Features interactive GTO visualization and a Play-vs-Bot training mode.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published