Calculateur d'équité au poker par Monte Carlo en Python
Un calculateur d'équité au poker par Monte Carlo est la première amélioration mathématique qui change vraiment les décisions. Au lieu de se dire « J'ai un tirage, je vais peut-être call », votre bot peut estimer sa fréquence de victoire, la comparer aux cotes du pot et fold les calls trop chers.
À lire aussi : Le guide complet pour créer un bot de poker IA en 2026, notre guide de référence sur les frameworks, la logique de décision, l'équité, les tests et les arènes où jouer.
Points clés à retenir
- L'équité de Monte Carlo estime la probabilité de gagner en échantillonnant les cartes adverses inconnues et les futures cartes du tableau.
- Open Poker donne à votre bot le montant exact du pot et du call dans
your_turn, ce qui permet d'intégrer directement l'équité à la décision fondée sur les cotes du pot.- Commencez par 2 000 à 5 000 simulations par décision. Davantage améliore l'estimation, mais la latence reste importante.
Quel problème l'équité Monte Carlo résout-elle ?
L'équité Monte Carlo comble l'écart entre les catégories de mains et les cartes qui restent à venir. Sur Open Poker, un bot a 120 secondes pour agir et reçoit le pot, le board, les actions autorisées et le jeton de tour dans chaque message your_turn (documentation des actions Open Poker). Cela suffit à estimer si un call est rentable avant d'envoyer l'action.
Le calculateur pose la question suivante : si l'on distribue les cartes inconnues un grand nombre de fois, à quelle fréquence ma main gagne-t-elle ou partage-t-elle le pot ? Ce chiffre est l'équité.
Si le pot est de 300 et que le call est de 100, vos cotes du pot sont :
100 / (300 + 100) = 25%Si l'équité estimée est de 36 %, le call est rentable avant de tenir compte des mises futures. Si elle est de 18 %, folder économise des jetons. L'estimation n'est pas parfaite, mais elle vaut mieux qu'une règle codée en dur du type « call tous les tirages couleur ».
Quelles données faut-il recevoir d'Open Poker ?
Vous avez besoin de quatre valeurs : les cartes privatives du héros, les cartes communes, la taille du pot et le montant à payer. Open Poker envoie les cartes communes et le pot dans your_turn ; votre bot doit mémoriser les cartes privatives du message privé hole_cards. Le protocole WebSocket repose sur JSON et peut être utilisé dans n'importe quel langage (documentation WebSocket).
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)Ne recalculez pas le pot si le serveur vous en fournit le montant. Les bots rencontrent des bugs difficiles à diagnostiquer lorsqu'ils reconstituent l'état à partir d'anciens événements player_action et ratent une reconnexion, une action rejetée ou un détail lié à un side-pot. Le serveur fait foi pour l'état de la partie. Votre bot, lui, reste responsable de ses décisions.
Comment comparez-vous les mains finales ?
Utilisez StandardHighHand.from_game() de PokerKit pour comparer les mains finales de Hold'em. PokerKit fournit l'évaluateur standard et les opérateurs de comparaison habituels. Sa documentation contient des exemples d'évaluation manuelle (Évaluation manuelle PokerKit).
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))Cette petite fonction enveloppe l'API et garde le reste du calculateur lisible. Les cartes Open Poker sont déjà au format As, Td et 7c, donc aucun convertisseur n'est nécessaire sauf si votre bot les stocke différemment.
Si les performances deviennent un problème, mettez en cache les cartes analysées. La documentation de PokerKit prévient que l'analyse répétée des chaînes coûte cher. Pour un premier bot, les chaînes directes conviennent. Pour un bot exécutant 10 000 essais par action sur plusieurs bots hébergés, le profilage en vaut la peine.
Comment estimez-vous l'équité contre un adversaire ?
Échantillonnez les cartes manquantes du tableau et une main adverse, puis comparez les mains finales. Avec 5 000 essais, une simple calculatrice Python est généralement suffisamment stable pour les décisions Open Poker en direct. Le propre benchmark de PokerKit rapporte plus d'un million d'évaluations standard par seconde sur un processeur d'ordinateur portable, donc l'évaluateur n'est pas le premier goulot d'étranglement (Documents PokerKit).
from random import sample
def estimate_equity(hero, board=None, opponents=1, trials=5000):
board = board or []
known = set(hero + board)
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 / trialsCette fonction accorde un crédit partiel aux pots partagés. Si votre main fait égalité avec celle d'un adversaire, elle compte pour une demi-victoire. À trois joueurs, elle compte pour un tiers. Ces cas arrivent plus souvent qu'on ne le pense sur les boards pairés ou lorsque la quinte est partagée.
Comment transformer l’équité en action ?
Comparez l'équité aux cotes du pot, puis ajoutez une petite marge de sécurité. Les jeux Open Poker sont en 6-max avec des blinds fixes de 10/20 et des buy-ins de table de 1 000 à 5 000 jetons (documents de saison), donc un mauvais call peut toujours coûter une part significative de votre stack.
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"}Cette politique reste passive. Elle call les situations rentables, mais ne relance ni ses mains de valeur ni ses gros tirages en semi-bluff. Associez-la à la stratégie de mise pour bots de poker une fois le calculateur opérationnel.
Combien d'essais un bot en direct doit-il exécuter ?
Commencez par 3 000 essais au flop et au turn, puis réduisez ce nombre si la latence devient trop élevée. Open Poker autorise 20 messages WebSocket par seconde et par connexion et accorde 120 secondes pour chaque action, mais votre bot doit tout de même répondre rapidement. Un calcul lent bloque la boucle d'événements et réduit les possibilités d'exploiter un avantage.
Utilisez différents décomptes d'essais par rue :
| Rue | Essais suggérés | Pourquoi |
|---|---|---|
| Préflop | 1 000 | Suffisant pour une estimation grossière des ranges |
| Flop | 5 000 | Il reste deux cartes, la variance est élevée |
| Turn | 3 000 | Il reste une carte, les estimations se stabilisent plus vite |
| Rivière | 0 | Aucune simulation nécessaire, évaluez les mains faites |
L'équité préflop contre des mains aléatoires ne suffit pas à elle seule. Vous avez également besoin de ranges par position, car vos adversaires ne jouent pas leurs cartes au hasard. Consultez les ranges par position pour un bot de poker afin d'affiner les mains que votre bot ouvre avant le flop.
Quels sont les pièges ?
Le plus grand piège est de considérer « l’équité maintenant » comme un « profit toujours ». L’équité ignore les paris futurs. Un tirage couleur peut avoir 35 % d'équité au flop, mais si le tournant manque et que votre adversaire bloque, vous devrez peut-être vous coucher avant de réaliser cette équité.
Le deuxième piège est le nombre d’adversaires. L'équité contre une main aléatoire n'est pas la même face à cinq joueurs encore dans le coup. Dans un pot multiway, les tirages faibles perdent beaucoup de valeur, car il est plus probable qu'un autre joueur s'améliore. Augmentez la valeur du paramètre « adversaires » lorsqu'il reste plusieurs joueurs dans la main.
Le troisième piège concerne le profil de la table. Face à des adversaires très loose, l'hypothèse de mains aléatoires est plus proche de la réalité. Face à des bots tight, leur range de call est plus forte qu'une range aléatoire et l'estimation d'équité devient trop optimiste. C'est là que la modélisation des adversaires commence à être utile.
Comment faire pour que la calculatrice reste rapide ?
Pour gagner en rapidité, limitez les calculs avant la river. Un bot en direct n’a pas besoin d’une précision de laboratoire pour chaque call marginal. Il doit prendre une décision suffisamment fiable, assez vite pour ne pas bloquer sa boucle WebSocket. Mettez les résultats en cache, adaptez le nombre d'essais à la street et prévoyez des sorties anticipées.
Utilisez trois règles simples :
| Optimisation | Pourquoi ça aide |
|---|---|
| Ne pas simuler à la river | Les cinq cartes du tableau sont connues |
| Réduire les essais dans les petits pots | Une erreur de 20 jetons ne justifie pas 10 000 essais |
| Mettre en cache les entrées répétées | Les mêmes cartes privatives et le même board peuvent revenir lors de tentatives ou de resynchronisations |
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]Le cache n’a pas besoin d’être éternel. Effacez-le entre les mains ou plafonnez-le à quelques centaines d'entrées. Le but est d'éviter un travail répété et accidentel, et non de créer une base de données de tous les états possibles du Hold'em.
Si votre bot utilise un LLM pour décider, calculez l'équité avant l'appel au modèle et incluez le pourcentage dans le prompt. Les données chiffrées rendent les décisions du LLM moins vagues.
FAQ
L'équité Monte Carlo est-elle exacte ?
Non. Il s’agit d’une estimation échantillonnée. Une énumération exacte est possible pour de nombreux spots, mais Monte Carlo est plus facile à connecter à un bot en direct et assez rapide pour le délai d'action de 120 secondes d'Open Poker.
Mon bot devrait-il gérer l'équité préflop ?
Seulement comme signal secondaire. Les décisions préflop doivent partir de ranges par position, car A9o au bouton et A9o en UTG ne sont pas la même main. L'équité contre des cartes aléatoires ne tient pas compte de ce contexte.
Puis-je l'utiliser sans PokerKit ?
Oui, mais vous avez alors besoin d’un autre évaluateur. PokerKit permet de gagner du temps car il prend directement en charge la construction et la comparaison des mains de Hold'em. Écrire votre propre évaluateur est un projet amusant et une mauvaise première décision de production.
Comment puis-je tester si cela améliore mon bot ?
Exécutez deux versions pour au moins quelques centaines de mains : une avec votre ancienne logique d'appel et une avec des appels basés sur l'équité. Suivez les jetons nets, les mains jouées et les sessions interrompues grâce aux statistiques et au classement de la saison Open Poker.