# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Purpose Poker analysis tool for GGPoker using a Logitech StreamCam pointed at a 2560×1440 monitor. Captures the game via webcam, reads cards via OCR and color detection, calculates equity via Monte Carlo simulation. ## Running the Scripts ```bash # Live camera viewer with settings panel (trackbars) python3 main.py # Poker analyzer — board OCR + Monte Carlo equity python3 analyzer.py # auto OCR hero cards python3 analyzer.py Qd Qc # manually specify hero cards (rank+suit) # Webcam scraper using dickreuter_poker backend python3 webcam_scraper.py ``` ## Architecture ``` main.py — Camera viewer with OpenCV trackbars. Loads/saves settings.json. analyzer.py — Main analysis pipeline: webcam → crop → OCR → Monte Carlo → advice. webcam_scraper.py — Adapter connecting webcam to dickreuter_poker TableScraper. virtualbox/ — Stub module: dickreuter_poker imports virtualbox which isn't needed. files/ — Card sprite sheet (table_card.png + card.json) for future template matching. settings.json — Persisted camera settings (auto-tuned, do not edit manually). tmp/ — All temporary files, snapshots, debug images go here. ``` ### External dependency: dickreuter_poker Located at `/home/isaevea/python/dickreuter_poker`. Added to `sys.path` at runtime. - `poker.decisionmaker.montecarlo_numpy2.Evaluation` — Monte Carlo equity calculator (CPU/numpy, no GPU). - `poker.scraper.table_scraper.TableScraper` — Table state scraper (card templates from `https://dickreuter.com:7778/`). - `poker.tools.mongo_manager.MongoManager` — Fetches GGPoker table config from remote API. Table name: `"Official GGPoker 6player"`. GUI modules of dickreuter_poker (PyQt6) are stubbed out in `webcam_scraper.py` via `sys.modules` injection. ## Camera Hardware - **Device**: Logitech StreamCam → `/dev/video2` (index 2). `/dev/video0` is UVC Camera. - **Optimal settings** (auto-tuned, saved in `settings.json`): focus=60 (manual), sharpness=192, exposure=500 (manual). - Qt font issue fix: Liberation Sans fonts copied to `.venv/lib/python3.12/site-packages/cv2/qt/fonts/`. - Window titles must be ASCII-only — Cyrillic in `cv2.namedWindow()` causes NULL pointer crash. Trackbar labels support Cyrillic. ## Webcam Coordinate System All coordinate constants in `analyzer.py` are in the **1280×720 webcam frame**: ```python BOARD_AREA = (220, 370, 330, 640) # y1,y2,x1,x2 — entire flop/turn/river area HERO_L_AREA = (438, 478, 472, 530) # left hole card HERO_R_AREA = (438, 478, 530, 585) # right hole card ``` These are camera-position-dependent. If camera moves, recalibrate by running a snapshot and checking `tmp/` images. In `webcam_scraper.py`, the GGPoker window boundary: ```python TABLE_X1, TABLE_Y1 = 15, 55 TABLE_X2, TABLE_Y2 = 760, 685 ``` This crops the GGPoker client from the webcam frame and scales to 1500×1100 (dickreuter's `CROP_WIDTH × CROP_HEIGHT`). ## Card Detection **Board cards** (`read_board_cards`): BOARD_AREA is divided into 3 equal columns. Top-left corner of each is OCR'd via Tesseract (`tessedit_char_whitelist=23456789TJQKA`). Suit detected by mean red channel (>100 → hearts/diamonds, else spades). **Hero cards** (`read_hero_cards`): Color-based suit detection in HSV space — blue hue → ♦, green → ♣, red → ♥, dark → ♠. GGPoker uses emoji-style colored card backgrounds. **Tessdata path**: `/home/isaevea/python/dickreuter_poker/tessdata/` ## Monte Carlo Card Format `montecarlo_numpy2.Evaluation.run_evaluation(card1, card2, tablecards, iterations, player_amount)` Cards encoded as `[rank, suit]` where rank: 2–14 (A=14), suit: 0=clubs, 1=diamonds, 2=hearts, 3=spades. ```python RANK_MAP = {'2':2,...,'T':10,'J':11,'Q':12,'K':13,'A':14} SUIT_MAP = {'c':0,'d':1,'h':2,'s':3} ``` Returns float equity (0.0–1.0). Typical: >0.65 → raise, >0.45 → call, <0.25 → fold.