Poker Bot Rings ๐ŸŽฐ How Card-Sharing Networks Extract $300k/Month From Your Tables

:slot_machine: Poker Bot Rings: When Machines Share Cards and Humans Bleed

:world_map: One-Line Flow: Multiple bots at your table share hole cards in real time โ€” they never fight each other, they only attack when youโ€™re mathematically doomed.


Why this matters (zero skills required):
Youโ€™re not playing against 3 strangers. Youโ€™re playing against a hive mind that sees 3x the cards you do. They know what you canโ€™t have. They never waste chips on each other. And theyโ€™re extracting more money than the casino takes in rake. Understanding this is the difference between โ€œbad luckโ€ and โ€œbeing farmed.โ€


:brain: The 30-Second Explanation

Normal poker:
You see 2 cards. Your opponent sees 2 cards. Equal information.

Bot ring poker:
3 bots at your table. Each shares their 2 cards with a central server.
The server now sees 6 cards instead of 2.
They calculate your odds using a 46-card deck while you use 52.

The math advantage:

  • Normal player: 3.8% of the deck known
  • 3-bot ring: 11.5% of the deck known
  • Result: 15-25% permanent edge over humans, every hand

:money_with_wings: Why Bot Farms Out-Earn The House

The Math That Should Scare You

The house takes:

  • 3-5% rake from every pot
  • Maybe $5 cap per hand
  • At $1/$2 stakes: ~$30-50/hour from a full table

A 3-bot ring takes:

  • 10-15% EV edge over humans at the table
  • Never loses chips to each other (internal recycling)
  • Estimated $100-300k/month at mid-stakes alone

Real numbers:

โ€œFrom these 14 accounts, they are probably playing at least 1 million hands a month and crushing the games by at least 10bb/100 with rakeback. My guess is theyโ€™re making anywhere from $100-300k per month.โ€
โ€” FernandoCosta, 2+2 forums investigating GGPoker bots (October 2025)

The PokerStars PLO scandal:
The most infamous episode of 2015 saw PokerStars rocked by a PLO bot ring, which took a reputed $1.5 million from regular players at the mid-stakes tables.

And the kicker:
PokerStars collected nearly $2.5 million in rake from the probably-banned accounts during the time they were active โ€“ a million more than the profit earned by the cheaters themselves.

The house still profited while players got robbed.


:bullseye: How The Scam Works (Step by Step)

Step 1: Multiple Accounts, One Brain

The setup:

Your Table (6-9 players)
โ”œโ”€โ”€ Seat 1: You (human)
โ”œโ”€โ”€ Seat 3: Bot A โ†’ reports Ah Kh to server
โ”œโ”€โ”€ Seat 5: Human  
โ”œโ”€โ”€ Seat 7: Bot B โ†’ reports Qc Jc to server
โ”œโ”€โ”€ Seat 9: Bot C โ†’ reports 7d 7s to server
โ””โ”€โ”€ Coordination Server (sees all 6 bot cards)

Each bot runs from:

  • Separate virtual machine
  • Unique IP address
  • Different โ€œidentityโ€ (email, payment method)

To the poker site, they look like strangers from different cities.

Step 2: Cards Shared in Real Time

The moment cards are dealt, every bot phones home.

What the server instantly knows:

  • Bot A: Ah Kh
  • Bot B: Qc Jc
  • Bot C: 7d 7s
  • Dead cards: Ah, Kh, Qc, Jc, 7d, 7s

Why this matters:
If you somehow knew that another player held something like ten-three offsuit then you would know your odds of winning the hand to be cut by something in the neighborhood of 40%.

Now multiply that by knowing 3 opponentsโ€™ cards, not just one.

Step 3: They Never Bluff Each Other

The golden rule: Bots donโ€™t extract value from teammates.

Soft play, that is, failing to bet or raise in a situation that would normally merit it, because you donโ€™t want to cost your partner money.

What this looks like:

  • Bot A flops a set
  • Bot B has top pair
  • Normal play: Bot A bets big, extracts maximum
  • Bot ring play: Bot A checks, lets it go cheap

Chips stay in the ring. Only humans bleed.

Step 4: The Squeeze โ€” Trapping Humans

Whipsawing, where partners raise and reraise each other to trap players in between.

How it works:

Preflop:
Bot A (early position): Raises to $10
You (middle): Call with QQ (solid hand!)
Bot B (late position): Re-raises to $35 โ† COORDINATED

Now you're stuck between two "strong" hands.
Pay $25 more or fold your queens.

What you donโ€™t know:

  • Bot A will fold if you call (they KNOW Bot Bโ€™s cards are weak)
  • Bot B is squeezing with garbage
  • Youโ€™re being tax-farmed by math

A player raises a bet before the flop and waits for the victim to re-raise. After that, another player raises again, preventing the victim from being able to continue betting.

Step 5: Only Attack When You're Behind

The decisive edge:

When bots share cards, they calculate your range against a reduced deck.

Board: Ks 7c 2d

Player Hand What Bots Know
Bot A Ah Kh Top pair, ace kicker
Bot B Kd Qd Top pair, weaker kicker
Bot C 7h 7s Set of sevens
You ?? ?? Your range is narrower

Bot calculations:

  • 3 Kings accounted for โ†’ You canโ€™t have KK
  • Both 7s accounted for โ†’ You canโ€™t have 77
  • Your actual holdings are now predictable

The result:
They bet when youโ€™re behind. They fold when youโ€™re ahead.
Over thousands of hands, you get crushed.


:bar_chart: The Numbers From Real Investigations

Documented Bot Ring Busts
Platform Year Bots/Accounts Money Stolen Source
ACR Poker 2024 51 bots $116,415 JNandez investigation
PokerStars 2015 36+ accounts ~$1.5M PokerTube
GGPoker 2025 14+ accounts $100-300k/month GipsyTeam
PartyPoker 2024 291 accounts $71,771 refunded partypoker blog

The ACR numbers:
51 suspected bots identified at $1/$2 PLO in 2023 โ€“ $116,415 stolen from legitimate players / customers of ACR โ€“ Bots held a 4.5 EV bb/100 winrate before rakeback.

The Russian Bot Factory (Bloomberg 2024)

Welcome to 2024, a time when artificial intelligence is on the rise. Letโ€™s move to the chilly Russian city of Omsk, home to the Bot Farm Corporation.

The scale:
The company looks like a classic company, with different departments, employees and company parties. Supposedly, many employees have never encountered poker or cards at all.

Their product:
The group behind the bots even said that they were able to make amateur players so frustrated that 80 percent of them didnโ€™t even play 1,000 hands and quit poker.

The customer base:
They have more than 10,000 customers and among them are said to be various professional players.

This isnโ€™t bedroom hackers. Itโ€™s industrialized extraction.


:wrench: Coordination Server Example (Card Sharing Protocol)

Complete WebSocket Coordination Server (Python)
# coordination_server.py
# FastAPI + WebSocket for real-time card sharing

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from typing import Dict, List, Set
import json
import asyncio

app = FastAPI()

class TableCoordinator:
    def __init__(self):
        self.tables: Dict[str, dict] = {}
        self.connections: Dict[str, List[WebSocket]] = {}
    
    def get_or_create_table(self, table_id: str) -> dict:
        if table_id not in self.tables:
            self.tables[table_id] = {
                "cards": {},      # seat -> [card1, card2]
                "board": [],
                "pot": 0,
                "bots": set()
            }
            self.connections[table_id] = []
        return self.tables[table_id]
    
    def report_hole_cards(self, table_id: str, seat: int, cards: List[str]):
        """Bot reports its hole cards to the coordinator."""
        table = self.get_or_create_table(table_id)
        table["cards"][seat] = cards
        table["bots"].add(seat)
    
    def get_all_known_cards(self, table_id: str) -> List[str]:
        """Returns all cards known to the team (for dead card calculation)."""
        table = self.tables.get(table_id, {})
        known = []
        for seat, cards in table.get("cards", {}).items():
            known.extend(cards)
        known.extend(table.get("board", []))
        return known
    
    def calculate_team_recommendation(self, table_id: str, requesting_seat: int) -> dict:
        """Calculates optimal action considering all teammate cards."""
        table = self.tables.get(table_id)
        if not table:
            return {"action": "FOLD", "reason": "no_table_data"}
        
        my_cards = table["cards"].get(requesting_seat, [])
        dead_cards = self.get_all_known_cards(table_id)
        
        # Calculate equity with dead cards removed
        # (In production, use OMPEval or pbots_calc)
        teammate_equities = []
        for seat, cards in table["cards"].items():
            if seat != requesting_seat:
                teammate_equities.append({
                    "seat": seat,
                    "cards": cards,
                    # equity calculation would go here
                })
        
        return {
            "my_cards": my_cards,
            "dead_cards": dead_cards,
            "teammates": teammate_equities,
            "action": "CALL",  # placeholder for actual logic
            "reason": "coordinated_play"
        }

coordinator = TableCoordinator()

@app.websocket("/ws/{table_id}/{seat}")
async def websocket_endpoint(websocket: WebSocket, table_id: str, seat: int):
    await websocket.accept()
    coordinator.connections.setdefault(table_id, []).append(websocket)
    
    try:
        while True:
            data = await websocket.receive_text()
            message = json.loads(data)
            
            if message["type"] == "HOLE_CARDS":
                # Bot reports its cards
                coordinator.report_hole_cards(
                    table_id, 
                    seat, 
                    message["cards"]
                )
                # Broadcast to all bots at table
                for conn in coordinator.connections[table_id]:
                    await conn.send_json({
                        "type": "CARDS_UPDATE",
                        "all_known": coordinator.get_all_known_cards(table_id)
                    })
            
            elif message["type"] == "REQUEST_ACTION":
                # Bot asks what to do
                recommendation = coordinator.calculate_team_recommendation(
                    table_id, 
                    seat
                )
                await websocket.send_json({
                    "type": "ACTION_RECOMMENDATION",
                    **recommendation
                })
            
            elif message["type"] == "BOARD_UPDATE":
                coordinator.tables[table_id]["board"] = message["cards"]
                
    except WebSocketDisconnect:
        coordinator.connections[table_id].remove(websocket)

# Run with: uvicorn coordination_server:app --host 0.0.0.0 --port 8443
Bot Client Example (Connects to Coordinator)
# bot_client.py
import asyncio
import websockets
import json

class CoordinatedBot:
    def __init__(self, table_id: str, seat: int, server_url: str):
        self.table_id = table_id
        self.seat = seat
        self.server_url = f"{server_url}/ws/{table_id}/{seat}"
        self.ws = None
        self.known_cards = []
    
    async def connect(self):
        self.ws = await websockets.connect(self.server_url)
        asyncio.create_task(self.listen())
    
    async def listen(self):
        async for message in self.ws:
            data = json.loads(message)
            if data["type"] == "CARDS_UPDATE":
                self.known_cards = data["all_known"]
                print(f"[Seat {self.seat}] Team knows: {self.known_cards}")
            elif data["type"] == "ACTION_RECOMMENDATION":
                print(f"[Seat {self.seat}] Recommended: {data['action']}")
    
    async def report_cards(self, cards: list):
        """Call when dealt hole cards."""
        await self.ws.send(json.dumps({
            "type": "HOLE_CARDS",
            "cards": cards
        }))
    
    async def request_action(self):
        """Call when it's your turn."""
        await self.ws.send(json.dumps({
            "type": "REQUEST_ACTION"
        }))

# Usage:
async def main():
    bot1 = CoordinatedBot("pokerstars_12345", seat=3, server_url="ws://localhost:8443")
    bot2 = CoordinatedBot("pokerstars_12345", seat=7, server_url="ws://localhost:8443")
    
    await bot1.connect()
    await bot2.connect()
    
    # When dealt cards:
    await bot1.report_cards(["Ah", "Kh"])
    await bot2.report_cards(["Qc", "Jc"])
    
    # Now both bots know 4 cards total
    # Dead card equity calculation uses 48-card deck instead of 52
    
    await asyncio.sleep(1)
    await bot1.request_action()  # Gets coordinated recommendation

asyncio.run(main())

Statistical Red Flags

AI Algorithms can identify the following patterns: Players who consistently play together at the same tables. This may include joining together, leaving tables together, and making suspicious gameplay decisions.

What investigators look for:

  • Identical preflop frequencies
  • Same WTSD (Went To ShowDown) percentages
  • Never betting against each other
  • Folding strong hands to small bets from โ€œpartnersโ€
  • Simultaneous login/logout

Collusion can often be detected by finding any of several detectable patterns (such as folding good hands to a small bet, as it is known that another player has a better hand).

The 2+2 forum method:
Players track statistical anomalies across thousands of hands, looking for accounts that behave identically or show impossible patterns (like always knowing when to fold the second-best hand).

How Sites Are Fighting Back

PokerStarsโ€™ new anti-cheating technology uses machine learning models trained on millions of hands to detect statistical anomalies. These audits have already identified and banned over 3,000 suspicious accounts since January 2025.

Multi-layer detection:
The new anti-cheating system uses a multi-layered approach to security. At its core is a behavior analysis algorithm that tracks unusual playing patterns that might indicate collusion or bot usage. This system monitors thousands of data points per second across all tables.

Adaptive algorithms:
When the system encounters an unfamiliar pattern, it doesnโ€™t simply flag itโ€”it incorporates this new information into its knowledge base. This means cheaters canโ€™t simply make minor adjustments to bypass detection.

But hereโ€™s the problem:
Detection remains challenging, with sites employing secret anti-bot measures while players develop their own methods for identifying automated opponents. The financial incentives are substantial enough that sophisticated operations continue despite the risks.


:hammer_and_wrench: Creator-Tier Resources: Build It Yourself


:robot: Ready-to-Run Bot Frameworks

dickreuter/Poker โ€” The Gold Standard (2.3k โญ)

The most complete open-source poker bot.
Works on: PartyPoker, PokerStars, GGPoker

git clone https://github.com/dickreuter/Poker.git
cd Poker
pip install -r requirements.txt

Whatโ€™s inside:

  • OpenCV screen scraping (GUI mapper included)
  • Neural network card recognition
  • Monte Carlo equity calculation
  • Genetic algorithm decision making
  • Auto mouse movement
  • Strategy editor GUI

Key files:

  • poker/main.py โ€” Entry point
  • poker/decisionmaker/ โ€” Strategy logic
  • poker/scraper/ โ€” Table reading

Pro tip: Run poker client in VirtualBox, bot controls from outside. Avoids mouse conflicts.

:link: github.com/dickreuter/Poker
:link: deepermind-pokerbot.com (binaries)

PokerGPT โ€” GPT-4 Powered Bot

Uses GPT-4 for real-time decisions on PokerStars.

git clone https://github.com/HarperJonesGPT/PokerGPT.git

Why it matters: LLM-powered bots are harder to pattern-detect than rule-based systems.

:link: github.com/HarperJonesGPT/PokerGPT

PyPokerBot โ€” Simple OpenCV + Tesseract

Lightweight bot using computer vision.

git clone https://github.com/gbencke/PyPokerBot.git
pip install opencv-python pytesseract

Best for: Learning how screen scraping works.

:link: github.com/gbencke/PyPokerBot

MIT Pokerbots โ€” Academic Framework (2026 updated)

Official MIT competition framework. Updated January 2026.

git clone https://github.com/mitpokerbots/engine-2026.git

Includes:

  • Game engine
  • Bot templates
  • Scrimmage server
  • Class resources

:link: github.com/mitpokerbots


:abacus: Equity Calculators (Dead Card Support)

OMPEval โ€” Fastest C++ Calculator

Board cards and dead cards can be customized. Max 6 players. Uses multithreading automatically.

#include <omp/EquityCalculator.h>
using namespace omp;

EquityCalculator eq;
vector<CardRange> ranges{"QQ+,AKs", "A2s+", "random"};
uint64_t board = CardRange::getCardMask("2c4c5h");
uint64_t dead = CardRange::getCardMask("Jc");  // DEAD CARDS HERE

eq.start(ranges, board, dead, false);
eq.wait();
auto r = eq.getResults();

Speed: 2-10x faster than Equilab per thread.

:link: github.com/zekyll/OMPEval

pbots_calc โ€” MIT's Dead Card Calculator

Built for collusion scenarios.

# With dead cards (teammate has QcJc)
./calculator.sh AhKh:random --dead QcJc

Supports common range syntax. The --dead flag is what makes card-sharing coordination work.

:link: github.com/mitpokerbots/pbots_calc

eval7 โ€” Python Cython Speed
pip install eval7
import eval7

# Create deck, remove dead cards
deck = eval7.Deck()
dead_cards = [eval7.Card("Qc"), eval7.Card("Jc")]
for card in dead_cards:
    deck.cards.remove(card)  # Now calculating from 50-card deck

hand = [eval7.Card("Ah"), eval7.Card("Kh")]
board = deck.sample(5)

:link: github.com/julianandrews/pyeval7

poker-odds-calc โ€” Node.js with Dead Cards
npm install poker-odds-calc
poker-odds-calc -p AdKh -p AcKh -b 5sTd9c -d 2s2d  # -d = dead cards

:link: github.com/siavashg87/poker-odds-calc

holdem-eval โ€” CLI with Dead Cards
./holdem-eval -b Ks5h2h -d 7d6d TT+,AJs+ random
# -d 7d6d = teammate's cards removed from calculations

Wrapper around OMPEval with full range support.

:link: github.com/apometta/holdem-eval

deuces โ€” Pure Python, 235k evals/sec
pip install deuces
from deuces import Card, Deck, Evaluator

evaluator = Evaluator()
deck = Deck()

# Remove dead cards before sampling
dead = [Card.new('Qc'), Card.new('Jc')]
deck.cards = [c for c in deck.cards if c not in dead]

board = deck.draw(5)
hand = deck.draw(2)
score = evaluator.evaluate(board, hand)

:link: github.com/worldveil/deuces


:satellite_antenna: Coordination Servers (Real-Time Card Sharing)

casino-server โ€” Node.js + Redis + Socket.io

The backbone for multi-bot coordination.

git clone https://github.com/floatinghotpot/casino-server.git
cd casino-server
npm install

Features:

  • WebSocket protocol with JS client API
  • Redis pub/sub for scaling
  • PM2 clustering for load balancing
  • Event logging

Architecture:

Bot A โ”€โ”€โ”€โ”€โ”€โ”
Bot B โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ Redis โ”€โ”€โ–บ Coordination Logic โ”€โ”€โ–บ Action Commands
Bot C โ”€โ”€โ”€โ”€โ”€โ”˜

:link: github.com/floatinghotpot/casino-server

node-poker-stack โ€” Complete Poker Engine
git clone https://github.com/vampserv/node-poker-stack.git
npm install

Features:

  • 10-player Texas Holdโ€™em engine
  • WebSocket real-time communication
  • Backbone.js web client
  • Pluggable architecture

:link: github.com/vampserv/node-poker-stack

pypoker โ€” Python Redis Queue Architecture
git clone https://github.com/epifab/pypoker.git

Key insight: Frontend clients communicate via WebSockets. Backend game services communicate via Redis queue. Completely decoupled โ€” can be deployed on different servers.

{
  "message_type": "connect",
  "server_id": "vegas123",
  "player": {"id": "bot_001", "name": "Bot1", "money": 1000.0}
}

:link: github.com/epifab/pypoker

Derek Ries Botfarm โ€” Complete Network Client

A full async network client for poker with botfarm administration CLI.

โ€œI developed a taskrunner that continuously ran tasks scheduled every x minutes, which basically amounted to automatically collecting free chips on a huge number of accounts in the botfarm. As well as a CLI that provided me an administrative route to control all those bots.โ€

Stack: Python / AsyncIO / aiohttp / WebSockets / Protocol Buffers / Redis

Why network client > screen scraping:

โ€œA screen scraping method would be far too limited. Limited in the sense that I could only run a few bots at any one time because Iโ€™m limited by what fits on the screen.โ€

:link: derekries.github.io/projects/pokerclient.html


:eye: Screen Scraping & Card Recognition

OpenCV Playing Card Detector
git clone https://github.com/EdjeElectronics/OpenCV-Playing-Card-Detector.git

Uses Raspberry Pi camera to identify playing cards. Adaptable to screen captures.

:link: github.com/EdjeElectronics/OpenCV-Playing-Card-Detector

poker-vision โ€” Computer Vision for Cards
git clone https://github.com/MemDbg/poker-vision.git
pip install opencv-python

Uses image recognition + OCR to identify cards at a table.

:link: github.com/MemDbg/poker-vision

poker-hand-recognition โ€” ML Card Classification
git clone https://github.com/predrag-njegovanovic/poker-hand-recognition.git
pip install opencv-python keras tensorflow

Uses neural networks for card recognition. More robust than template matching.

:link: github.com/predrag-njegovanovic/poker-hand-recognition


:brain: AI Training Frameworks (CFR & Deep RL)

Deep-CFR โ€” Scalable Deep Counterfactual Regret

Used by researchers to train superhuman poker AI.

git clone https://github.com/EricSteinberger/Deep-CFR.git
cd Deep-CFR
pip install -r requirements.txt
python DeepCFR/leduc_example.py

What it does: Trains Nash equilibrium strategies without expert knowledge. The bot learns to bluff.

:link: github.com/EricSteinberger/Deep-CFR

pycfr โ€” Pure Python CFR
git clone https://github.com/tansey/pycfr.git
from pokercfr import CounterfactualRegretMinimizer
cfr = CounterfactualRegretMinimizer(kuhn_rules)
cfr.run(iterations=10000)
nash_strategies = cfr.profile

Supports vanilla CFR, Chance Sampling, Outcome Sampling, and Public Chance Sampling.

:link: github.com/tansey/pycfr

HDCFR โ€” Hierarchical Deep CFR

Skill-based poker AI with transfer learning.

git clone https://github.com/LucasCJYSDL/HDCFR.git

:link: github.com/LucasCJYSDL/HDCFR

cfrx โ€” JAX-Accelerated CFR

GPU-accelerated CFR using JAX.

pip install cfrx

:link: github.com/topics/counterfactual-regret-minimization

poker_ai (Fedden) โ€” Open Source Pluribus

Pluribus implementation with WebSocket visualization.

git clone https://github.com/fedden/poker_ai.git

:link: github.com/fedden/poker_ai


:performing_arts: Anti-Detection & Stealth

puppeteer-extra-plugin-stealth โ€” Browser Fingerprint Evasion
npm install puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

const browser = await puppeteer.launch({ headless: true });

What it patches:

  • Removes navigator.webdriver flag
  • Fixes HeadlessChrome in User-Agent
  • Adds chrome.runtime, chrome.app, chrome.csi
  • Fixes outer dimensions
  • Normalizes canvas fingerprint

:link: github.com/berstend/puppeteer-extra

browser-fingerprinting โ€” Evasion Research Bible

Comprehensive analysis of bot protection systems with countermeasures.

git clone https://github.com/niespodd/browser-fingerprinting.git

Covers: FingerprintJS bypass, WebGL spoofing, AudioContext manipulation, native extension detection, and more.

:link: github.com/niespodd/browser-fingerprinting

rebrowser-patches โ€” Cloudflare/DataDome Bypass

Collection of patches for Puppeteer/Playwright to avoid detection.

git clone https://github.com/nicholasgriffintn/rebrowser-patches.git

:link: github.com/topics/puppeteer-extra

Human-like Timing Randomization
import random
import time

def human_delay():
    """Bots that act instantly get caught."""
    base = random.uniform(1.5, 4.0)
    # 15% chance of "thinking harder"
    if random.random() < 0.15:
        base += random.uniform(2.0, 8.0)
    # 5% chance of distraction
    if random.random() < 0.05:
        base += random.uniform(10.0, 30.0)
    time.sleep(base)

def randomize_bet(optimal_bet):
    """Perfect bet sizes are suspicious."""
    variance = random.uniform(0.85, 1.15)
    return round(optimal_bet * variance, -1)

:bar_chart: Hand History Parsing & Analysis

hhp โ€” Multi-Room Parser (JS)

Parses PokerStars, Ignition, PartyPoker, Pacific (888).

npm install hhp
const { parse } = require('hhp');
const hand = parse(handHistoryText);
console.log(hand.players, hand.actions, hand.board);

:link: github.com/thlorenz/hhp

poker-log-parser โ€” Rust/Python Speed
pip install poker-log-parser

Blazingly fast Rust core with Python bindings.

:link: pypi.org/project/poker-log-parser

poker Python Library โ€” PokerStars Parser
from poker.room.pokerstars import PokerStarsHandHistory

hh = PokerStarsHandHistory(hand_text)
hh.parse()

print(hh.players)  # Player names, stacks, seats
print(hh.hero)     # Your cards
print(hh.board)    # Community cards

:link: poker.readthedocs.io


:hammer_and_wrench: The Creatorโ€™s Toolkit: Build It Yourself

โ€œWhere curiosity meets creation โ€” and every idea finds its hack.โ€

This is where 1Hackers become creators. These arenโ€™t just reading materials โ€” theyโ€™re building blocks. Open-source code you can fork, modify, and run.


:fire: Core Bot Frameworks (Open Source)

Working Poker Bot Implementations
Repository What It Does Stars Language
dickreuter/Poker Production-ready bot for PokerStars, PartyPoker, GGPoker. Screen scraping (OpenCV), genetic algorithms, Monte Carlo equity. Works today. 2.3k+ Python
OpenHoldem/openholdembot Mature, full-featured open source bot framework. Includes OpenScrape for table reading. Active community. 200+ C++
fedden/poker_ai MCCFR implementation for Texas Holdโ€™em. CLI interface, trained models, lookup tables. 1k+ Python
gbencke/PyPokerBot Simple bot with server/client architecture. Tesseract OCR + Flask API + Monte Carlo. Good starter project. 100+ Python

Why these matter:
These arenโ€™t tutorials โ€” theyโ€™re working code that plays on real platforms. Study the screen scraping, decision engines, and anti-detection timing.

Multi-Player AI Frameworks (The Science)
Repository What It Does Why It Matters
google-deepmind/open_spiel DeepMindโ€™s framework for multi-agent RL in games. Supports poker variants, CFR, MCCFR. The gold standard for research
datamllab/rlcard RL toolkit for card games. Blackjack, Leduc, Texas Holdโ€™em, Dou Dizhu. Easy interfaces. Plug-and-play environments
EricSteinberger/PokerRL Framework for multi-agent deep RL in poker specifically. Designed for multi-bot training

Installation:

pip install open_spiel  # DeepMind's framework
pip install rlcard      # Rice/Texas A&M toolkit

:high_voltage: GTO Solvers (Free & Open Source)

Solve Poker Like the Pros โ€” For Free
Tool Description Link
TexasSolver Open-source, matches PioSolver results, free for personal use. GUI + Console. github.com/bupticybee/TexasSolver
WASM Postflop Browser-based GTO solver. Discounted CFR algorithm. No installation needed. wasm-postflop.pages.dev
Desktop Postflop Native port of WASM Postflop. Faster than browser version. github.com/b-inary/desktop-postflop
TexasHoldemSolverJava Java-based solver with Python API. Turn/river faster than PioSolver. github.com/bupticybee/TexasHoldemSolverJava

Why solvers matter for bot rings:
GTO solutions tell each bot what the โ€œperfectโ€ play is. When combined with dead card knowledge, they compute exactly when the human is behind.


:abacus: Hand Evaluation Libraries

Fast Equity Calculation Code
Library Speed Language Link
Treys 235k evals/sec (5 card) Python 3 github.com/ihendley/treys
Deuces Same engine, legacy Python 2/3 github.com/worldveil/deuces
PokerStove 10M+ evals/sec C++ github.com/andrewprock/pokerstove
SKPokerEval 142k evals/sec (7 card) C++ github.com/kennethshackleton/SKPokerEval
PokerKit Most hand types supported Python arxiv.org/pdf/2308.07327

Quick start (Python):

pip install treys

from treys import Card, Evaluator, Deck
evaluator = Evaluator()
board = [Card.new('Ah'), Card.new('Kd'), Card.new('Jc')]
hand = [Card.new('Qs'), Card.new('Th')]
print(evaluator.evaluate(board, hand))  # 1600 = straight

Dead card calculation:
When you know opponent cards, simply remove them from the deck before running Monte Carlo simulations. This is the mathematical core of card-sharing advantage.


:bullseye: CFR Implementations (The Algorithm That Solved Poker)

Counterfactual Regret Minimization Code
Repository Description Link
pycfr Clean Python CFR for Kuhn/Leduc poker. Great for learning. github.com/tansey/pycfr
CFR-Explained Annotated implementations with explanations. Best learning resource. github.com/brianberns/CFR-Explained
simple-poker-cfr Minimal CFR for simplified Holdโ€™em github.com/ArmanMielke/simple-poker-cfr
HDCFR Hierarchical Deep CFR (skill-based). Academic paper implementation. github.com/LucasCJYSDL/HDCFR

Original papers:

Pluribus Open-Source Attempts

The Facebook Pluribus paper sparked many implementation attempts:

Fork Notes
fedden/poker_ai Most complete, actively maintained
whatsdis/pluribus Chrome extension approach for Bodog
keithlee96/pluribus-poker-AI MCCFR + game engine integration

Key insight:
Pluribus uses โ€œdepth-limited searchโ€ during play โ€” it doesnโ€™t solve the entire game, just the next few moves in real-time. This is how bots stay responsive.


:books: Academic Resources

Research Papers (Detection & Collusion)
Paper Authors Key Contribution
Information-Theoretic Collusion Detection Bonjour et al. (2022) Mutual information between agent actions detects collusion
Automating Collusion Detection U Alberta CPRG (2013) โ€œCollusion tablesโ€ capture advantage without assuming behavior
Can We Prevent Collusion? Smed et al. (2006) Foundational collusion taxonomy
Multi-Agent RL Collusion Survey OpenReview (2024) Comprehensive survey of LLM multi-agent collusion risks

University Alberta Computer Poker Research Group:
poker.cs.ualberta.ca โ€” Created Cepheus, Polaris, DeepStack. All publications available.

Landmark AI Papers
AI Paper What It Did
Cepheus Bowling et al. (2015) โ€œEssentially solvedโ€ heads-up limit Holdโ€™em
DeepStack Moravฤรญk et al. (2017) First AI to beat pros at heads-up no-limit
Libratus Brown & Sandholm (2017) Beat 4 pros over 120k hands
Pluribus Brown & Sandholm (2019) First AI to beat 6-player poker

:link: Curated Resource Lists

Awesome Lists & Community Hubs
Resource Description
awesome-poker :star: Start here โ€” Curated list of poker tools, bots, research, competitions
GitHub poker topic All poker-tagged repos, sorted by activity
GitHub poker-bot topic Bot-specific repositories
TwoPlusTwo Forums Active community, bot-hunting threads
GipsyTeam News Russian poker news, regular bot exposรฉs

Competitions (for training/testing):

  • ACPC โ€” Annual Computer Poker Competition
  • MIT Pokerbots โ€” MITโ€™s annual bot competition
  • PokerWars.io โ€” Online bot testing platform

:bar_chart: Industry Analysis

Platform Security Reports

PartyPoker Game Integrity (Official)

Bot Ring Investigations (Community)

Bloomberg Coverage (2024)

  • Bot Farm Corporation / Deeplay exposรฉ
  • Industrial-scale operations in Omsk, Russia
  • 10,000+ customers including professional players

:brain: Quick Start Path

For a 1Hacker who wants to understand this space:

Week 1: Theory
โ”œโ”€โ”€ Read awesome-poker README
โ”œโ”€โ”€ Watch Pluribus paper summary videos
โ””โ”€โ”€ Run WASM Postflop in browser

Week 2: Code
โ”œโ”€โ”€ pip install treys
โ”œโ”€โ”€ Build equity calculator script
โ”œโ”€โ”€ pip install rlcard && run tutorials

Week 3: Build
โ”œโ”€โ”€ Clone dickreuter/Poker
โ”œโ”€โ”€ Study OpenCV screen scraping
โ”œโ”€โ”€ Modify decision engine

Week 4: Research
โ”œโ”€โ”€ Read CFR-Explained repo
โ”œโ”€โ”€ Run pycfr on Kuhn poker
โ””โ”€โ”€ Study DeepStack paper

These are the building blocks. What you create with them is up to you.


:warning: What This Means For You

If You Play Online Poker

Signs you might be at a bot ring table:

  • Same players always at your tables
  • Never see them bet into each other
  • Unusual fold patterns (strong hands folding to small bets)
  • All join/leave within minutes of each other
  • Robotic timing (no variance in decision speed)

What you can do:

  • Report suspicious accounts to the site
  • Track patterns in your HUD
  • Avoid tables where the same 3+ players always appear
  • Play on sites with strong KYC (geofenced US sites have fewer bots)

In the United States, geofenced sites operating within individual states like Michigan appear to have fewer bot problems, likely due to stricter KYC (Know Your Customer) requirements and smaller player pools.

The Uncomfortable Truth

Perhaps more concerning than individual bots are coordinated bot networks where multiple AI players share information at the same table. This form of collusion creates an insurmountable advantage, as the bots effectively see each otherโ€™s cards while competing against human opponents.

The cat-and-mouse never ends:
When bot accounts get banned, operators simply create new identities and continue operations. This cat-and-mouse game has become a permanent feature of the online poker ecosystem.

Youโ€™re not paranoid. Theyโ€™re out there. And theyโ€™re organized.


:graduation_cap: The Bottom Line

A coordinated bot ring sharing cards in real time creates an information asymmetry that humans cannot overcome through skill.

The simple version:

  • You see 2 cards
  • They see 6+ cards
  • They never waste chips fighting each other
  • They only attack when math says you lose

The result:
They extract more than the house takes in rake โ€” from a game designed to give the house its edge.

Thatโ€™s not poker. Thatโ€™s farming.


Now you know how the machine works. What you do with that is your hack.

6 Likes

Very detailed analysis, thank you.

1 Like

I like your Job @SRZ Keep everyday giving us new

Really Amazing

1 Like