Skip to content
[OPEN_POKER]

Ranges de posição para bots de pôquer: pare de abrir de qualquer lugar

JJoão Carvalho||Atualizado |9 min read

Seu bot de pôquer não deve jogar as mesmas mãos em todas as posições. No No-Limit Hold'em 6-max, o botão age por último depois do flop, enquanto os blinds agem primeiro. Essa diferença determina quais mãos geram fichas e quais drenam o stack silenciosamente.

Parte de: O guia completo para construir um bot de IA para poker em 2026 - o pilar completo que cobre estruturas, lógica de decisão, equidade, testes e onde competir.

Principais conclusões

  • Os ranges de posição são uma vantagem barata porque corrigem erros pré-flop antes que a mão fique cara.
  • As posições iniciais exigem ranges tight. Nas posições finais, é possível tentar roubos com mais frequência porque restam menos jogadores para agir.
  • Primeiro, implemente os ranges como conjuntos de códigos de mãos. Adicione a modelagem de oponentes somente depois que essa base funcionar.

Por que a posição importa tanto

A posição é importante porque quem age mais tarde toma decisões com mais informação. A documentação de estratégia do Open Poker destaca posição inicial, posição final e blinds como contextos de decisão distintos (documentos de ações e estratégia). Num jogo 6-max, cada órbita tem seis posições e 30 fichas obrigatórias em blinds na estrutura 10/20.

Ao abrir KTo under the gun, o bot ainda enfrenta cinco jogadores. Ao abrir a mesma mão no botão, restam apenas os dois blinds. As cartas são as mesmas; o risco não.

É nesse ponto que bots iniciantes perdem fichas sem perceber. Eles calculam um único valor em hand_strength() e o usam em todas as posições. Isso funciona com mãos óbvias, como um par de ases, mas falha justamente nas mãos que decidem boa parte de uma temporada: suited connectors, ases fracos, pares baixos e broadways marginais.

Quais são as seis posições úteis

Use seis posições: UTG, HJ, CO, BTN, SB e BB. Open Poker envia dealer_seat em hand_start; o bot recebe o próprio assento em table_joined e pode calcular a posição relativa a partir desses dois valores (documentação do WebSocket).

POSITIONS_6MAX = ["SB", "BB", "UTG", "HJ", "CO", "BTN"]
 
 
def position_name(hero_seat, dealer_seat, active_seats):
    ordered = sorted(active_seats)
    dealer_index = ordered.index(dealer_seat)
    relative = ordered[(dealer_index + 1) % len(ordered):] + ordered[:dealer_index + 1]
 
    # relative[0] is small blind, relative[1] is big blind in a full hand.
    seat_to_position = {
        seat: POSITIONS_6MAX[i]
        for i, seat in enumerate(relative[: len(POSITIONS_6MAX)])
    }
    return seat_to_position[hero_seat]

Uma mesa pode não estar completa. Se houver apenas três bots, use somente a lógica de BTN, SB e BB. Não trate um assento como under the gun quando só existem três jogadores ativos.

Quais ranges de abertura um primeiro bot deve usar

Comece com ranges mais tight do que você imagina. Uma base prática para iniciantes é abrir 12% no UTG, 16% no HJ, 22% no CO, 35% no BTN e usar um range cauteloso no small blind. Esses números não vêm de um solver perfeito, mas evitam os piores vazamentos enquanto você aprimora a lógica pós-flop.

PosiçãoAlvo abertoMãos de exemplo
UTG12%77+, AJs+, KQs, AQo+
HJ16%66+, ATs+, KJs+, QJs, AJo+
CO22%55+, A8s+, KTs+, QTs+, JTs, ATo+, KQo
BTN35%22+, mais ases suited, broadways e suited connectors
SB28%Dê raise com mãos que jogam bem em heads-up e folde as piores
BBDefender conforme o preçoDê call com base nas pot odds e na jogabilidade da mão

As porcentagens exatas importam menos do que o formato geral: tight no início, amplo no botão e ajustado com cuidado nos blinds. Essa estrutura corrige mais bots iniciantes do que outra heurística pós-flop.

Para considerar a profundidade do stack, combine esses ranges com o gerenciamento de stack para bots de pôquer. Um bot com 50bb e outro com 250bb não devem tratar pares baixos da mesma forma.

Como você codifica ranges em Python

Codifique as mãos com strings curtas: AA, AKs, AQo. Pares repetem o valor. Mãos suited terminam em s; mãos offsuit, em o. O formato é compacto para ranges escritos à mão e fácil de depurar nos logs.

RANK_ORDER = "23456789TJQKA"
 
 
def hand_code(cards):
    r1, s1 = cards[0][0], cards[0][1]
    r2, s2 = cards[1][0], cards[1][1]
 
    if r1 == r2:
        return r1 + r2
 
    high, low = sorted([r1, r2], key=RANK_ORDER.index, reverse=True)
    suited = "s" if s1 == s2 else "o"
    return high + low + suited
 
 
OPEN_RANGES = {
    "UTG": {"77", "88", "99", "TT", "JJ", "QQ", "KK", "AA", "AJs", "AQs", "AKs", "KQs", "AQo", "AKo"},
    "HJ": {"66", "77", "88", "99", "TT", "JJ", "QQ", "KK", "AA", "ATs", "AJs", "AQs", "AKs", "KJs", "KQs", "QJs", "AJo", "AQo", "AKo"},
    "CO": {"55", "66", "77", "88", "99", "TT", "JJ", "QQ", "KK", "AA", "A8s", "A9s", "ATs", "AJs", "AQs", "AKs", "KTs", "KJs", "KQs", "QTs", "QJs", "JTs", "ATo", "AJo", "AQo", "AKo", "KQo"},
    "BTN": {"22", "33", "44", "55", "66", "77", "88", "99", "TT", "JJ", "QQ", "KK", "AA", "A2s", "A3s", "A4s", "A5s", "A6s", "A7s", "A8s", "A9s", "ATs", "AJs", "AQs", "AKs", "K9s", "KTs", "KJs", "KQs", "Q9s", "QTs", "QJs", "J9s", "JTs", "T9s", "98s", "87s", "A9o", "ATo", "AJo", "AQo", "AKo", "KTo", "KJo", "KQo", "QJo"},
}
 
 
def should_open(position, cards):
    return hand_code(cards) in OPEN_RANGES.get(position, set())

É uma implementação simples de propósito. Quando o bot acumular uma sequência de folds, você poderá registrar position=CO hand=KTo open=False e entender a decisão imediatamente.

Como você usa ranges com ações válidas

Abra o pote somente quando ninguém tiver apostado e o raise for uma ação válida. Open Poker informa todas as ações permitidas, inclusive os valores mínimo e máximo de raise. O valor representa o total do raise, não o incremento, uma confusão comum em bots (documentação de ações).

def preflop_decision(msg, hole_cards, position):
    actions = {a["action"]: a for a in msg["valid_actions"]}
 
    # Free option in the big blind.
    if "check" in actions:
        return "check", None
 
    if "raise" in actions and should_open(position, hole_cards):
        return "raise", actions["raise"]["min"]
 
    # Facing a raise: use a tighter continue range for now.
    if "call" in actions and hand_code(hole_cards) in {"TT", "JJ", "QQ", "KK", "AA", "AQs", "AKs", "AKo"}:
        return "call", None
 
    return "fold", None

Esse range de call é intencionalmente tight. Dar call com mãos demais é uma das formas mais rápidas de transformar um bot pré-flop razoável em um bot perdedor no pós-flop. Depois de implementar a equidade por Monte Carlo, amplie os calls conforme o preço e as tendências do oponente.

Quando os ranges devem mudar

Os ranges devem acompanhar mudanças na profundidade do stack, no tamanho da mesa e no perfil dos oponentes. No Open Poker, os buy-ins variam de 1.000 a 5.000 fichas, enquanto cada temporada começa com 5.000 fichas e blinds fixos de 10/20 (documentação da temporada). Assim, o mesmo bot pode jogar com 50bb, 100bb ou 250bb.

Use três ajustes:

ContextoAjuste
Short stack abaixo de 60bbRemova conectores especulativos do mesmo naipe e pares pequenos
Stack profundo acima de 150bbAdicione conectores e pares do mesmo naipe na posição final
Blinds looseReduza os roubos e aposte mais por valor
Blinds tightAmplie os ranges de abertura no botão e no cutoff

Não aplique os quatro ajustes no primeiro dia. Primeiro, confirme que o range-base supera a antiga estratégia baseada em uma única pontuação. Depois, use a modelagem de oponentes para ajustar o botão e os blinds.

Como você testa um novo range

Teste os ranges com uma alteração por vez. Mudanças pré-flop parecem pequenas, mas afetam todas as streets seguintes porque o bot chega ao flop com outra composição de mãos. Se você ampliar o range do botão, soltar a defesa do big blind e mudar o sizing ao mesmo tempo, não saberá qual alteração ajudou.

Use este loop de teste:

  1. Escolha uma posição, geralmente BTN ou BB.
  2. Mude de 5 a 10 mãos nesse range.
  3. Execute pelo menos 300 mãos.
  4. Compare tendências de fichas, recompras e grandes mãos perdedoras.
  5. Mantenha a alteração somente se o log explicar o resultado.

O sinal mais rápido não é a taxa de vitória, mas o conjunto de mãos que entraram no pré-flop e perderam mais de 20bb. Analise essas mãos primeiro. Se o novo range do botão acrescentar cinco mãos offsuit marginais que continuam perdendo potes grandes, reverta a mudança. Se elas roubarem blinds e raramente chegarem ao showdown, continue testando.

Os resultados recompensam uma disciplina que pode parecer monótona. Bons bots não precisam de criatividade heroica pré-flop. Precisam jogar menos mãos dominadas nas posições iniciais e aplicar mais pressão controlada nas posições finais.

Perguntas frequentes

Um bot de pôquer deve usar ranges perfeitos de solver

No início, não. Ranges de solver pressupõem uma árvore de jogo específica e determinadas respostas dos oponentes. Uma tabela simples para 6-max é mais fácil de testar e registrar, além de ser melhor do que copiar um chart que o bot não sabe jogar no pós-flop.

Como o big blind defende

O big blind deve defender pelo preço. Se pagar 20 em um pote de 90 fichas, você precisará de muito menos equidade do que se pagar 200 em 300. Comece com pot odds e depois filtre as mãos que jogam mal no pós-flop.

Qual range devo usar para um bot sem código

Comece com o modelo The Shark. A documentação do Bot Builder o descreve como tight-aggressive, com 0,30 de tightness e 0,75 de agressividade, uma base mais sólida do que modelos loose para a maioria dos iniciantes.

Os ranges de posição podem substituir a avaliação das mãos

Não. Os ranges decidem se o bot entra na mão pré-flop. A avaliação da mão e a equidade orientam o que fazer depois que o board aparece. Use os dois recursos.

Continue Lendo