Zum Inhalt springen
[OPEN_POKER]♠

Monte-Carlo-Poker-Equity-Rechner in Python

JJoão Carvalho||Aktualisiert |9 Min. Lesezeit

Lektion 9 von 13: Hände bewerten

Schätze die Equity und berücksichtige dabei den eigenen Anteil an geteilten Pots. Schließe Lektion 8 ab, verwende Python 3.11 oder neuer und installiere die Abhängigkeiten aus der beiliegenden requirements.txt.

Ein Monte-Carlo-Poker-Equity-Rechner ist das erste mathematische Upgrade, das Entscheidungen am Tisch wirklich verändert. Statt zu sagen: „Ich habe einen Draw, vielleicht calle ich“, kann dein Bot schätzen, wie oft er gewinnt, diese Zahl mit den Pot Odds vergleichen und kostspielige Vermutungen vermeiden.

Teil von: Der vollständige Leitfaden zum Aufbau eines KI-Poker-Bots im Jahr 2026: der umfassende Leitfaden zu Frameworks, Entscheidungslogik, Equity, Tests und Wettbewerbsmöglichkeiten.

Wichtige Erkenntnisse

  • Monte-Carlo-Equity schätzt die Gewinnwahrscheinlichkeit, indem sie unbekannte Gegnerkarten und künftige Boardkarten simuliert.
  • Open Poker liefert deinem Bot in your_turn den genauen Pot und Call-Betrag, sodass Equity direkt in Pot-Odds-Entscheidungen einfließen kann.
  • Beginne mit 2.000 bis 5.000 Durchläufen pro Entscheidung. Mehr Durchläufe erhöhen die Genauigkeit, aber die Aktionslatenz bleibt wichtig.

Welches Problem löst Monte-Carlo-Equity?

Monte-Carlo-Equity schließt die Lücke zwischen groben Handlabels und der Realität künftiger Karten. Bei Open Poker hat ein Bot 45 Sekunden Zeit zum Handeln und erhält in jeder your_turn-Nachricht Pot, Board, zulässige Aktionen und den Turn-Token (Open Poker-Aktionsdokumente). Das genügt, um vor dem Senden einer Aktion zu schätzen, ob ein Call profitabel ist.

Der Rechner fragt: Wenn wir die unbekannten Karten sehr oft austeilen, wie häufig gewinnt meine Hand oder teilt den Pot? Diese Zahl ist ihre Equity.

Wenn der Pot 300 und der Call 100 beträgt, liegen deine Pot Odds bei:

100 / (300 + 100) = 25%

Wenn deine geschätzte Equity 36 % beträgt, ist ein Call vor Berücksichtigung künftiger Setzrunden profitabel. Beträgt deine Equity 18 %, spart ein Fold Chips. Die Zahl ist nicht perfekt, aber deutlich besser als die fest codierte Regel „Jeden Flush Draw callen“.

Welche Eingaben benötigst du von Open Poker?

Du benötigst vier Werte: die Hole Cards des Hero, Community Cards, Pot-Größe und Call-Betrag. Open Poker sendet Community Cards und Pot in your_turn; dein Bot sollte die Hole Cards aus der privaten hole_cards-Nachricht zwischenspeichern. Das WebSocket-Protokoll basiert auf JSON und lässt sich aus jeder Sprache nutzen (WebSocket-Dokumente).

def call_amount(valid_actions):
    for action in valid_actions:
        if action["action"] == "call":
            return action["amount"]
    return 0
 
 
def pot_odds(pot, call):
    if call <= 0:
        return 0
    return call / (pot + call)

Schätze den Pot nicht selbst, wenn der Server ihn liefert. Bots produzieren schwer auffindbare Fehler, wenn sie den Spielzustand aus früheren player_action-Ereignissen rekonstruieren und dabei eine Wiederverbindung, eine abgelehnte Aktion oder ein Side-Pot-Detail verpassen. Der Server ist die Quelle des Spielzustands. Dein Bot sollte darauf seine Entscheidungen aufbauen.

Wie vergleicht man die finalen Hände?

Verwende StandardHighHand.from_game() von PokerKit, um finale Hold'em-Hände zu vergleichen. PokerKit unterstützt die Bewertung von Standard-High-Hands und normale Vergleichsoperatoren; Beispiele findest du in der Dokumentation zur Handauswertung (PokerKit-Handbewertung).

from pokerkit import StandardHighHand
 
RANKS = "23456789TJQKA"
SUITS = "cdhs"
DECK = [r + s for r in RANKS for s in SUITS]
 
 
def compact(cards):
    return "".join(cards)
 
 
def best_hand(hole, board):
    return StandardHighHand.from_game(compact(hole), compact(board))

Diese kleine Hilfsfunktion hält den restlichen Rechner lesbar. Open-Poker-Karten liegen bereits als As, Td und 7c vor, daher brauchst du keinen eigenen Konverter, außer dein Bot speichert Karten anders.

Wenn die Leistung zum Problem wird, solltest du geparste Karten zwischenspeichern. Die PokerKit-Dokumentation warnt davor, dass wiederholtes Parsen von Strings teuer ist. Für einen ersten Bot sind direkte Strings in Ordnung. Für einen Bot, der 10.000 Durchläufe pro Aktion über mehrere gehostete Bots hinweg ausführt, lohnt sich Profiling.

Wie schätzt du die Equity gegen einen Gegner?

Simuliere die fehlenden Boardkarten und die Hand eines Gegners und vergleiche anschließend die finalen Hände. Mit 5.000 Durchläufen ist ein einfacher Python-Rechner für Live-Entscheidungen bei Open Poker normalerweise stabil genug. Der PokerKit-Benchmark berichtet über mehr als eine Million Standard-High-Hand-Auswertungen pro Sekunde auf einer Laptop-CPU; der Evaluator ist also nicht der erste Engpass (PokerKit-Dokumente).

from random import sample
 
 
def estimate_equity(hero, board=None, opponents=1, trials=5000):
    board = board or []
    if len(hero) != 2 or len(board) not in (0, 3, 4, 5):
        raise ValueError("Expected two hole cards and a legal board length")
    if trials < 1 or not 1 <= opponents <= 5:
        raise ValueError("Use positive trials and one to five opponents")
    known = set(hero + board)
    if len(known) != len(hero) + len(board) or not known.issubset(DECK):
        raise ValueError("Cards must be valid and distinct")
    missing_board = 5 - len(board)
    equity = 0.0
 
    for _ in range(trials):
        deck = [card for card in DECK if card not in known]
        draw_count = opponents * 2 + missing_board
        draw = sample(deck, draw_count)
 
        opp_holes = [
            draw[i * 2 : i * 2 + 2]
            for i in range(opponents)
        ]
        runout = board + draw[opponents * 2 :]
 
        hero_hand = best_hand(hero, runout)
        all_hands = [hero_hand] + [
            best_hand(opp, runout)
            for opp in opp_holes
        ]
 
        winning_hand = max(all_hands)
        winners = [hand for hand in all_hands if hand == winning_hand]
 
        if hero_hand == winning_hand:
            equity += 1 / len(winners)
 
    return equity / trials

Diese Funktion rechnet geteilte Pots anteilig an. Teilt deine Hand mit einem Gegner, erhält sie einen halben Sieg; bei drei Gewinnern ein Drittel. Das ist auf gepaarten Boards und bei geteilten Straights relevanter, als man zunächst erwartet.

Wie übersetzt man Equity in Aktionen?

Vergleiche Equity mit den Pot Odds und füge anschließend eine kleine Sicherheitsmarge hinzu. Open-Poker-Spiele sind 6-max mit festen Blinds von 10/20 und Tisch-Buy-ins von 1.000 bis 5.000 Chips (Saisondokumente); ein schlechter Call kann also immer noch einen erheblichen Teil deines Stacks kosten.

def equity_decision(msg, hole_cards, opponents=1):
    actions = {a["action"]: a for a in msg["valid_actions"]}
 
    if "check" in actions:
        return {"action": "check"}
 
    if "call" not in actions:
        return {"action": "fold"}
 
    call = actions["call"]["amount"]
    pot = msg["pot"]
    board = msg.get("community_cards", [])
 
    equity = estimate_equity(
        hero=hole_cards,
        board=board,
        opponents=opponents,
        trials=3000,
    )
 
    required = pot_odds(pot, call)
    margin = 0.03
 
    if equity > required + margin:
        return {"action": "call"}
    return {"action": "fold"}

Diese Strategie bleibt bewusst passiv. Du callst profitable Spots, raist aber weder Value-Hände noch starke Semi-Bluff-Draws. Kombiniere sie mit Einsatzstrategie für Pokerbots, sobald der Rechner funktioniert.

Wie viele Durchläufe sollte ein Live-Bot ausführen?

Beginne am Flop und Turn mit 3.000 Durchläufen und reduziere die Zahl, wenn Latenz wichtig ist. Open Poker erlaubt 20 WebSocket-Nachrichten pro Sekunde und Verbindung und gibt 45 Sekunden pro Aktion, dennoch sollte dein Bot zügig reagieren. Langsame Bots verschenken Vorteile, wenn sie ihren Ereignisablauf blockieren.

Verwende je nach Street unterschiedliche Durchlaufzahlen:

StreetVorgeschlagene DurchläufeWarum
Preflop1.000Ausreichend für eine grobe Range-Prüfung
Flop5.000Zwei Karten fehlen noch, die Varianz ist hoch
Turn3.000Eine Karte bleibt, die Schätzungen stabilisieren sich schneller
River0Keine Simulation nötig, die fertigen Hände werden ausgewertet

Preflop-Equity gegen zufällige Hände allein genügt nicht. Du brauchst außerdem positionsabhängige Ranges, denn Gegner spielen keine zufälligen Karten. Nutze Positionsranges für Pokerbots, um festzulegen, welche Hände dein Bot preflop eröffnet.

Wo liegen die Fallstricke?

Der größte Fehler ist, „aktuelle Equity“ mit „sicherem Gewinn“ zu verwechseln. Equity ignoriert künftige Bets. Ein Flush Draw kann am Flop 35 % Equity haben; verfehlt er den Turn und der Gegner setzt groß, musst du vielleicht folden, bevor du diese Equity realisieren kannst.

Der zweite Fehler betrifft die Gegnerzahl. Equity gegen eine zufällige Hand ist nicht dasselbe wie Equity gegen fünf aktive Spieler. Multiway-Pots entwerten schwache Draws, weil sich mit größerer Wahrscheinlichkeit jemand anderes verbessert. Erhöhe das Argument opponents, wenn mehr Spieler in der Hand sind.

Der dritte Fehler ist die Tischdynamik. Gegen sehr lockere Gegner liegen Annahmen über zufällige Hände näher an der Realität. Gegen tighte Bots ist ihre Call-Range stärker als zufällig, und deine Equity-Schätzung wird zu optimistisch. Hier zahlt sich Gegnermodellierung aus.

Wie hält man den Rechner schnell?

Halte die Berechnung schnell, indem du vor dem River unnötige Arbeit vermeidest. Ein Live-Bot braucht nicht in jedem Grenzfall Laborpräzision. Er braucht oft genug und schnell genug die richtige Antwort, ohne seine WebSocket-Schleife zu blockieren. Das bedeutet Caching, Street-basierte Durchlaufzahlen und vorzeitige Abbrüche.

Verwende drei einfache Regeln:

OptimierungWarum es hilft
River-Simulation überspringenAlle fünf Boardkarten sind bekannt
Weniger Durchläufe in kleinen PotsEin Fehler von 20 Chips rechtfertigt keine 10.000 Durchläufe
Wiederholte Eingaben cachenBei Wiederholungsversuchen oder Resynchronisierungen können dieselben Hole Cards und dasselbe Board erscheinen
equity_cache = {}
 
 
def cached_equity(hero, board, opponents, trials):
    key = (tuple(sorted(hero)), tuple(board), opponents, trials)
    if key not in equity_cache:
        equity_cache[key] = estimate_equity(hero, board, opponents, trials)
    return equity_cache[key]

Der Cache muss nicht dauerhaft leben. Lösche ihn zwischen Händen oder begrenze ihn auf einige hundert Einträge. Das Ziel ist, versehentlich doppelte Arbeit zu vermeiden, nicht eine Datenbank aller möglichen Hold'em-Spielzustände aufzubauen.

Wenn dein Bot ein LLM für Entscheidungen verwendet, berechne die Equity vor dem LLM-Aufruf und gib den Prozentsatz im Prompt weiter. Zahlen machen LLM-Poker-Entscheidungen weniger vage.

FAQ

Ist Monte-Carlo-Equity exakt?

Nein. Es ist eine Stichprobenschätzung. Für viele Spots ist eine exakte Aufzählung möglich, aber Monte Carlo lässt sich leichter in einen Live-Bot einbinden und ist schnell genug für das Action-Timeout von 45 Sekunden bei Open Poker.

Sollte mein Bot preflop Equity berechnen?

Nur als sekundäres Signal. Preflop-Entscheidungen sollten von Positions-Ranges ausgehen, denn A9o am Button und A9o under the gun sind nicht dieselbe Hand. Equity gegen zufällige Karten ignoriert diesen Kontext.

Kann ich das ohne PokerKit verwenden?

Ja, aber dann benötigst du einen anderen Hand-Evaluator. PokerKit spart Zeit, weil es das Erzeugen und Vergleichen von Hold'em-Händen direkt unterstützt. Einen eigenen Evaluator zu schreiben ist ein interessantes Projekt, aber keine gute erste Produktionsentscheidung.

Wie teste ich, ob das meinen Bot verbessert?

Lass zwei Versionen mindestens einige hundert Hände spielen: eine mit deiner bisherigen Call-Logik und eine mit Equity-gesteuerten Calls. Verfolge Netto-Chips, gespielte Hände und fehlgeschlagene Sitzungen anhand der Open-Poker-Saisonstatistiken und der Bestenliste.

Prüfe das Ergebnis von Lektion 9

Was sich ändert
Ersetze die anfängliche Schätzung durch eine begrenzte Kartensimulation gegen zufällige gegnerische Hände.
Erwartete Ausgabe
split_pot_equity_fixture: 0.5
So prüfst du dein Ergebnis
Das Board mit Royal Flush teilt den Heads-up-Pot. Live-Entscheidungen verwenden 64 Versuche: eine grobe Schätzung, keine Solver-Ausgabe.

Entpacke das Archiv zur Lektion, öffne den Ordner in einem Terminal und führe diese Befehle aus:

python -m pip install -r requirements.txt
python bot.py --lesson 9 --self-test
python bot.py --lesson 9 --hands 3 --report run.json

Der Selbsttest verwendet simulierte Daten ohne Verbindung zum Server und gibt Folgendes aus: checkpoint: passed. Für das Onlinespiel brauchst du OPEN_POKER_API_KEY in deiner Umgebung sowie verfügbare Gegner. Die beiliegende README erklärt die Einrichtung und die Grenzen der Wiederherstellung.

Alle Lektionen dieses Kurses
  1. 1. Einen Poker-Bot in Python bauen
  2. 2. Grundlegende Poker-Bot-Architektur
  3. 3. WebSocket-Fehler eines Poker-Bots debuggen
  4. 4. Warum deinem Pokerbot die Zeit ausgeht
  5. 5. Poker-Mathematik für Bots
  6. 6. Positions-Ranges für Poker-Bots
  7. 7. Einsatzstrategie für Poker-Bots
  8. 8. PokerKit-Tutorial
  9. 9. Monte-Carlo-Equity-Rechner
  10. 10. Gegner-Modellierung
  11. 11. Fortgeschrittene Poker-Bot-Architektur
  12. 12. So funktioniert die Ranglistenwertung
  13. 13. Professionelle Poker-Bot-Architektur
♠

Weiterlesen