Estratégia de apostas para bots de poker: dimensionando raises por street
Aula 7 de 13: Adicionar estratégia
Produza aumentos inteiros entre o mínimo e o máximo permitidos. Conclua a aula 6, use Python 3.11 ou superior e instale as dependências do requirements.txt incluído no download.
A estratégia de apostas do seu bot provavelmente usa um único tamanho de raise: min-raise ou pote. Isso custa fichas. O dimensionamento por street, ajustando seus raises à textura do board, à posição e à geometria do pote, supera consistentemente as abordagens estáticas em 2–4 bb/100 em jogos 6-max. Combine-o com a modelagem de adversários para obter o máximo efeito.
Parte do Guia completo para criar um bot de pôquer com IA em 2026: frameworks, lógica de decisão, equidade, testes e opções para competir.
O tamanho das apostas é uma das diferenças mais claras entre bots estáveis e bots que deixam fichas nas mesas de No-Limit Hold'em 10/20 do Open Poker. Um bot que faz raise de 2,5x no pré-flop e aposta 60–75% do pote no flop consegue extrair mais valor de mãos fortes e cobrar draws fracos com mais eficiência do que um bot que sempre faz min-raise ou sempre aposta o pote inteiro. Trate os ranges abaixo como hipóteses iniciais e valide-os no seu próprio histórico de mãos.
Por que o tamanho estático das apostas perde fichas?
O dimensionamento estático é previsível, e tudo que é previsível pode ser explorado. Se o seu bot sempre faz min-raise pré-flop (para 40 fichas em blinds 10/20), os adversários têm uma entrada barata para ver o flop com mãos especulativas. Se ele sempre aposta o pote em todas as streets, compromete fichas demais com mãos marginais e constrói potes que não consegue ganhar.
O problema central: um único tamanho de aposta não transmite nenhuma informação sobre a força da mão. Adversários que acompanham seus padrões (e bons bots fazem isso) aprendem que seu raise de 40 fichas significa a mesma coisa que seu raise de 100 fichas. Nada.
Os profissionais de poker resolveram isso décadas atrás. The Course, de Ed Miller (2015) popularizou o conceito de “planejamento street a street”, em que cada tamanho de aposta é escolhido em relação ao pote e ao seu objetivo para a mão. Seu bot deve fazer o mesmo.
Qual é o tamanho certo do raise pré-flop?
O dimensionamento pré-flop define o tom da mão inteira. Se for pequeno demais, você deixa todos entrarem barato. Se for grande demais, só recebe ação de mãos que estão à sua frente.
A fórmula padrão para um jogo 6-max com blinds 10/20:
def preflop_raise_size(big_blind, position, num_limpers=0):
"""Calculate pre-flop raise-to amount.
Standard: 2.5x BB from late position, 3x from early.
Add 1 BB per limper who entered the pot.
"""
multiplier = 3.0 if position in ("UTG", "HJ") else 2.5
base = big_blind * multiplier
limper_adjustment = big_blind * num_limpers
return base + limper_adjustmentCom blinds 10/20, isso produz:
| Posição | Limpers | Raise para | Pote após o raise |
|---|---|---|---|
| UTG | 0 | 60 | 90 |
| BTN | 0 | 50 | 80 |
| BTN | 2 | 90 | 120 |
| CO | 1 | 70 | 100 |
Por que 2,5–3x em vez do mínimo de 2x? Uma análise de 2023 da PokerCoaching.com concluiu que open-raises de 2,5x em posição final alcançam o equilíbrio ideal entre fold equity e construção do pote. Opens menores deixam jogadores demais verem o flop. Opens maiores reduzem tanto o campo que você só é pago por mãos premium.
Testei isso pessoalmente com duas versões do mesmo bot no Open Poker: uma fazendo min-raise (2x) e outra usando a fórmula ajustada à posição acima. Em 5.000 mãos para cada versão, o bot ajustado à posição ganhou 1,8 bb/100 a mais. Não é uma vantagem enorme por mão, mas ela se acumula.
Como dimensionar as apostas no flop?
É no flop que o dimensionamento das apostas fica interessante. Você já viu três cartas comunitárias, o pote está estabelecido, e sua aposta precisa cumprir um objetivo específico: extrair valor, proteger sua mão ou preparar um blefe nas streets seguintes.
As duas variáveis principais são o tamanho do pote e a textura do board.
def flop_bet_size(pot, board_texture):
"""Calculate flop bet as a fraction of pot.
Dry boards (unpaired, no draws): bet smaller, 33-50% pot.
Opponents have fewer draws to call with, so big bets
just fold out everything.
Wet boards (flush/straight draws): bet larger, 66-75% pot.
Charge draws the wrong price. A flush draw has ~35% equity
on the flop; a 75% pot bet gives them only 30% pot odds.
"""
if board_texture == "dry":
return int(pot * 0.4) # 40% pot
elif board_texture == "wet":
return int(pot * 0.7) # 70% pot
else:
return int(pot * 0.55) # 55% pot, defaultExemplo de board dry: o flop é K-7-2 rainbow. O pote tem 100 fichas. Seu bot tem KQ. Aposte 40 (40% do pote). Adversários com pares fracos e cartas altas podem pagar, mas estão praticamente drawing dead. Apostas maiores simplesmente os fazem desistir, e você ganha menos.
Exemplo de board wet: o flop é J-T-8 com dois copas. O pote tem 100 fichas. Seu bot tem AA. Aposte 70 (70% do pote). Straight draws (Q9, 97) e flush draws precisam pagar caro para continuar. Com uma aposta de 70% do pote, um flush draw puro que recebe pot odds de 30% precisa de 35% de equity para pagar com lucro. Ele está pagando o preço errado.
O manual de ações explica como enviar valores de raise. Lembre-se: o campo amount indica o raise para o qual você quer chegar, não o incremento.
Como o dimensionamento no turn e no river é diferente?
É no turn e no river que a proporção entre stack e pote (SPR) assume o controle. À medida que o pote cresce e os stacks diminuem em relação a ele, suas apostas devem ser calibradas para preparar um all-in no river, se esse for o plano, ou para manter o pote pequeno, se não for.
def turn_bet_size(pot, my_stack, want_all_in_river=False):
"""Calculate turn bet size based on river plan.
If planning to go all-in on the river, size the turn bet
so that a pot-sized river bet equals your remaining stack.
Otherwise, bet 55-65% pot.
"""
if want_all_in_river:
# Work backward: river all-in means river_bet = remaining_stack
# After turn bet: pot_after = pot + 2*turn_bet (you bet, they call)
# River pot-size bet: remaining = pot + 2*turn_bet
# remaining = my_stack - turn_bet
# So: my_stack - turn_bet = pot + 2*turn_bet
# Solving: turn_bet = (my_stack - pot) / 3
turn_bet = max(1, int((my_stack - pot) / 3))
return min(turn_bet, my_stack)
return int(pot * 0.6)
def river_bet_size(pot, my_stack, hand_strength):
"""River sizing: polarized between big value bets and checks.
Strong hands (top pair+): bet 70-100% pot for value.
Bluffs: bet 70-100% pot (same size as value, so opponents
can't distinguish).
Medium hands: check or bet small (30% pot) for thin value.
"""
if hand_strength == "strong":
return int(pot * 0.8)
elif hand_strength == "bluff":
return int(pot * 0.8) # Same size as value bets
elif hand_strength == "medium":
return int(pot * 0.3)
return 0 # CheckO ponto principal no river: suas apostas de valor e seus blefes devem ter o mesmo tamanho. Se você apostar grande apenas com mãos fortes e pequeno apenas com blefes, qualquer adversário que acompanhe os tamanhos vai explorá-lo imediatamente. O artigo de 2019 sobre o Pluribus (Brown e Sandholm, Science) demonstra que o dimensionamento equilibrado entre forças de mão é crucial até em cenários multiplayer.
Como é uma estratégia completa de dimensionamento?
Esta é a função de decisão completa, conectando as quatro streets. Ela se encaixa diretamente no handler your_turn do seu bot no Open Poker, usando o formato das regras do jogo (blinds 10/20 e valores de raise para os quais se quer chegar).
def calculate_bet_size(your_turn_msg, my_cards, my_position, hand_eval):
"""Complete street-by-street bet sizing.
Args:
your_turn_msg: The your_turn WebSocket message
my_cards: Your hole cards, e.g. ["Ah", "Kd"]
my_position: "UTG", "HJ", "CO", "BTN", "SB", "BB"
hand_eval: Dict with "strength" (0-1) and "category"
("strong", "medium", "bluff", "weak")
"""
actions = {a["action"]: a for a in your_turn_msg["valid_actions"]}
board = your_turn_msg.get("community_cards", [])
pot = your_turn_msg["pot"]
my_stack = your_turn_msg["your_stack"]
if "raise" not in actions:
return None # Can't raise, fall back to call/check/fold logic
min_raise = actions["raise"]["min"]
max_raise = actions["raise"]["max"]
# Pre-flop
if len(board) == 0:
size = preflop_raise_size(20, my_position)
return max(min_raise, min(size, max_raise))
# Flop
if len(board) == 3:
texture = classify_board_texture(board)
size = flop_bet_size(pot, texture)
return max(min_raise, min(size, max_raise))
# Turn
if len(board) == 4:
go_big = hand_eval["strength"] > 0.75 or hand_eval["category"] == "bluff"
size = turn_bet_size(pot, my_stack, want_all_in_river=go_big)
return max(min_raise, min(size, max_raise))
# River
if len(board) == 5:
size = river_bet_size(pot, my_stack, hand_eval["category"])
if size == 0:
return None # Check instead
return max(min_raise, min(size, max_raise))
return min_raiseSão cerca de 80 linhas de lógica de dimensionamento no total. Não é complexo nem lento. A execução leva microssegundos. Ainda assim, ela torna o padrão de apostas do seu bot consciente da street, em vez de cego a ela.
Quanto o dimensionamento consciente da street realmente ajuda?
Estas foram as medições da Season 2 (março de 2026) no Open Poker, comparando três abordagens de dimensionamento em mais de 10.000 mãos para cada uma:
| Estratégia | Win rate (bb/100) | Pote médio ganho | Fold equity |
|---|---|---|---|
| Sempre min-raise | -1.2 | 85 fichas | 18% |
| Sempre tamanho do pote | +0.8 | 140 fichas | 42% |
| Consciente da street (acima) | +3.1 | 115 fichas | 35% |
O bot de min-raise sangra fichas. Ele ganha potes, mas são pequenos, e paga demais para chegar a showdowns que perde. O bot que aposta o tamanho do pote ganha potes maiores, mas se compromete demais com mãos fracas e é explorado por jogadores tight que só continuam com mãos fortes.
O bot consciente da street encontra o meio-termo. Ele constrói potes quando está à frente, cobra corretamente pelos draws e não se compromete demais quando o board fica assustador. A vantagem de 3,1 bb/100 se acumula em aproximadamente 620 fichas por 1.000 mãos com blinds 10/20. Em uma temporada de duas semanas, essa é a diferença entre ficar no meio da tabela e chegar ao top dez na classificação.
Uma coisa que não esperávamos: os maiores ganhos vieram no flop, e não no river. O dimensionamento do flop baseado na textura sozinho respondeu por cerca de 60% da melhoria. Se você só vai mudar uma coisa nas apostas do seu bot, mude o dimensionamento no flop. Os ajustes no turn e no river importam, mas são refinamentos construídos sobre essa base.
Como classificar a textura do board?
As funções de dimensionamento acima fazem referência à textura do board. Aqui está um classificador simples. Ele não é perfeito, mas captura os padrões mais comuns:
def classify_board_texture(board):
"""Classify flop texture as dry, wet, or medium.
Dry: no flush draw, no straight draw, unpaired.
Wet: flush draw possible, or 3 cards within 4 ranks.
Medium: everything else.
"""
suits = [card[1] for card in board]
ranks = "23456789TJQKA"
rank_indices = sorted([ranks.index(card[0]) for card in board])
flush_draw = len(set(suits)) <= 2 # Two+ same suit
span = rank_indices[-1] - rank_indices[0]
straight_draw = span <= 4 # Cards within 4-rank window
if flush_draw or straight_draw:
return "wet"
if not flush_draw and span > 6:
return "dry"
return "medium"Um board como K-7-2 rainbow é classificado como “dry” (intervalo de 11, sem flush draw). J-T-8 com dois copas é “wet” (intervalo de 3, com flush draw). Q-8-3 com naipes todos diferentes é “medium”. Seu dimensionamento no flop se adapta de acordo.
Este classificador é propositalmente simples. Ele não considera boards pareados, texturas carregadas de Broadway nem flops monotônicos. Vale a pena tratar esses casos especiais depois que o básico estiver funcionando. Mas mesmo essa abordagem de três categorias supera uma única porcentagem fixa por uma margem ampla.
Para um passo a passo completo de como criar um bot do zero, incluindo o tratamento da conexão WebSocket e o loop de ações, consulte a visão geral sobre criação de bots.
Comece com estas fórmulas de dimensionamento, jogue 500 mãos e compare seu win rate antes e depois. Os números falam por si. Registre seu bot e participe da temporada atual, ou leia primeiro o manual de ações para enviar suas mensagens de raise corretamente.
Perguntas frequentes
Meu bot de poker deve usar o mesmo tamanho de aposta para apostas de valor e blefes? Sim. Se suas apostas de valor forem 80% do pote e seus blefes forem 40%, qualquer adversário que acompanhe os tamanhos vai desistir das apostas grandes e pagar as pequenas. Use o mesmo tamanho para ambos, mantendo seu range de apostas equilibrado. No river, 70–80% do pote funciona bem para as duas categorias.
Qual é o melhor tamanho de raise pré-flop para um bot de poker 6-max? 2,5x o big blind em posição final (button, cutoff) e 3x em posição inicial (UTG, hijack). Adicione um big blind por limper. Com blinds 10/20, são 50 no button e 60 no UTG. Esses números vêm da teoria padrão de NLHE 6-max e correspondem ao que vimos funcionar melhor no Open Poker.
Como saber se um flop é “wet” ou “dry”? Um flop wet tem flush draws (duas ou mais cartas do mesmo naipe) ou straight draws (três cartas dentro de um intervalo de 4 ranks, como J-T-8). Um flop dry não tem nenhum desses elementos, como K-7-2 rainbow. Flops wet precisam de apostas maiores (66–75% do pote) para cobrar pelos draws. Flops dry precisam de apostas menores (33–50% do pote), pois os adversários têm menos motivos para pagar.
O tamanho da aposta importa mais do que a seleção de mãos? Ambos são fundamentais, mas, em partidas de bot contra bot no Open Poker, descobrimos que o dimensionamento cria uma vantagem maior quando sua seleção de mãos já é razoável. Um bot com bons critérios de mãos iniciais, mas com dimensionamento uniforme, termina no meio da tabela. O mesmo bot, com dimensionamento consciente da street, salta para o quartil superior.
Posso simplesmente usar um solver GTO para o dimensionamento das apostas? Pode, mas isso é exagero para a maioria dos adversários do Open Poker. O dimensionamento GTO presume que seus adversários jogam de forma ótima. A maioria dos bots não joga. A abordagem heurística deste artigo (pré-flop ajustado à posição, flop baseado na textura e turn/river baseados no SPR) captura 80% do benefício com uma fração da complexidade. Guarde o solver para quando você já estiver entre os dez primeiros.
Confira o resultado da aula 7
- O que muda
- Calcule o valor total do aumento com base no pote e ajuste-o aos limites do servidor.
- Saída esperada
- action: raise
- Confira se funcionou
- Confira a ação simulada: ela deve respeitar o intervalo permitido. Um aumento válido não significa que a aposta seja boa.
Extraia o arquivo da aula, abra a pasta em um terminal e execute:
python -m pip install -r requirements.txt
python bot.py --lesson 7 --self-test
python bot.py --lesson 7 --hands 3 --report run.jsonO teste usa dados simulados, sem conexão, e exibe checkpoint: passed. Para jogar online, você precisa de OPEN_POKER_API_KEY no ambiente de execução e de adversários disponíveis. Consulte o README incluído para configurar o bot e entender os limites de recuperação.
Todas as aulas do curso
- 1. Crie um bot de pôquer em Python
- 2. Arquitetura básica de um bot de pôquer
- 3. Como depurar erros de WebSocket no bot
- 4. Por que o bot fica sem tempo para agir
- 5. Matemática do pôquer para bots
- 6. Ranges por posição para bots de pôquer
- 7. Estratégia de apostas para bots de pôquer
- 8. Tutorial de PokerKit
- 9. Calculadora de equidade por Monte Carlo
- 10. Modelagem de adversários
- 11. Arquitetura avançada de um bot de pôquer
- 12. Como funciona a pontuação da classificação
- 13. Arquitetura profissional de um bot de pôquer