One-Shot Example: Gemini's Poker Bot
A worked example for The Benchmark That Fights Back: Gemini's full, unedited one-shot response to our poker-bot prompt - its requirements.txt and bot.py.
This is a companion to The Benchmark That Fights Back. To show what the prompt actually produces, here is one model's complete one-shot reply, unedited: Gemini's requirements.txt and bot.py, generated from the prompt in that post. Want to add your own model to the arena? Hand it the same prompt and upload the bot it writes.
requirements.txt
# No external dependencies required. Pure Python implementation for speed and stability.
bot.py
import random
import itertools
from chipzen import Bot, GameState, Action
# Mapping card ranks to integer values for mathematical comparisons
RANK_MAP = {
"2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
"T": 10, "J": 11, "Q": 12, "K": 13, "A": 14
}
class CardMock:
"""Lightweight card object used during Monte Carlo simulations."""
def __init__(self, rank: str, suit: str):
self.rank = rank
self.suit = suit
def eval_5_cards(cards) -> tuple:
"""
Evaluates exactly 5 cards and returns a scoring tuple: (hand_type, details).
Higher tuples natively beat lower tuples in Python comparisons.
"""
ranks = sorted([RANK_MAP[c.rank] for c in cards], reverse=True)
suits = [c.suit for c in cards]
is_flush = len(set(suits)) == 1
unique_ranks = sorted(list(set(ranks)), reverse=True)
is_straight = False
straight_high = 0
if len(unique_ranks) == 5:
if unique_ranks[0] - unique_ranks[4] == 4:
is_straight = True
straight_high = unique_ranks[0]
elif unique_ranks == [14, 5, 4, 3, 2]: # Ace-low straight
is_straight = True
straight_high = 5
if is_flush and is_straight:
return (8, straight_high)
counts = {}
for r in ranks:
counts[r] = counts.get(r, 0) + 1
freq = sorted([(cnt, r) for r, cnt in counts.items()], reverse=True)
if freq[0][0] == 4: # Four of a Kind
return (7, freq[0][1], freq[1][1])
if freq[0][0] == 3 and freq[1][0] == 2: # Full House
return (6, freq[0][1], freq[1][1])
if is_flush: # Flush
return (5, ranks)
if is_straight: # Straight
return (4, straight_high)
if freq[0][0] == 3: # Three of a Kind
return (3, freq[0][1], [f[1] for f in freq[1:]])
if freq[0][0] == 2 and freq[1][0] == 2: # Two Pair
return (2, freq[0][1], freq[1][1], freq[2][1])
if freq[0][0] == 2: # Pair
return (1, freq[0][1], [f[1] for f in freq[1:]])
return (0, ranks) # High Card
def eval_best_hand(cards) -> tuple:
"""Finds the strongest 5-card combination from 5, 6, or 7 available cards."""
if len(cards) < 5:
return (0, [])
best_score = None
for combo in itertools.combinations(cards, 5):
score = eval_5_cards(combo)
if best_score is None or score > best_score:
best_score = score
return best_score
class MyBot(Bot):
def __init__(self):
super().__init__()
# Seed the RNG for game theory mix-ins (bluffs)
random.seed()
def get_preflop_strength(self, c1, c2) -> float:
"""
Calculates a robust preflop equity heuristic based on card ranks,
pairs, connectivity, and suitedness. Returns a score between 0.0 and 1.0.
"""
r1, r2 = RANK_MAP[c1.rank], RANK_MAP[c2.rank]
high, low = max(r1, r2), min(r1, r2)
suited = (c1.suit == c2.suit)
pair = (r1 == r2)
if pair:
return 0.58 + (high / 14.0) * 0.27 # AA = 0.85, 22 = 0.61
# Non-paired hands
base_eq = (high * 2 + low) / 42.0
score = 0.38 + base_eq * 0.16
if suited:
score += 0.05
gap = high - low
if gap == 1:
score += 0.03 # Connected cards
elif gap > 4:
score -= 0.04 # Gapped cards
return min(0.85, max(0.25, score))
def run_monte_carlo(self, hole, board, iterations=180) -> float:
"""Runs a fast Monte Carlo simulation against a random opponent range."""
used_cards = set((c.rank, c.suit) for c in hole + board)
deck = []
for r in RANK_MAP.keys():
for s in ["h", "d", "c", "s"]:
if (r, s) not in used_cards:
deck.append(CardMock(r, s))
wins, ties, count = 0, 0, 0
cards_needed_on_board = 5 - len(board)
sample_size = cards_needed_on_board + 2
for _ in range(iterations):
if len(deck) < sample_size:
break
sampled = random.sample(deck, sample_size)
opp_hole = sampled[:2]
extra_board = sampled[2:]
sim_board = board + extra_board
my_score = eval_best_hand(hole + sim_board)
opp_score = eval_best_hand(opp_hole + sim_board)
if my_score > opp_score:
wins += 1
elif my_score == opp_score:
ties += 1
count += 1
return (wins + 0.5 * ties) / count if count > 0 else 0.5
def decide(self, state: GameState) -> Action:
try:
# --- Strategic Context Gathering ---
hole = state.hole_cards
board = state.board
phase = state.phase
valid = state.valid_actions
# Absolute safety net: if no actions are available, just check/fold
if not valid:
return Action.check()
# Calculate mathematical Pot Odds
pot = state.pot
to_call = state.to_call
pot_odds = to_call / (pot + to_call) if (pot + to_call) > 0 else 0.0
# Determine position
is_button = (state.your_seat == state.dealer_seat)
# Stack sizing metrics
opp_stack = state.opponent_stacks[0] if state.opponent_stacks else state.your_stack
effective_stack = min(state.your_stack, opp_stack)
# --- Hand Strength Evaluation ---
if phase == "preflop":
equity = self.get_preflop_strength(hole[0], hole[1])
else:
# 180 iterations completes comfortably within 20-40ms, well under the 5000ms budget
equity = self.run_monte_carlo(hole, board, iterations=180)
# --- Semi-Bluff Detection (Postflop Draw Tracking) ---
has_draw = False
if phase in ["flop", "turn"]:
suits = [c.suit for c in hole + board]
# 4-card flush draw detection
if any(suits.count(s) == 4 for s in set(suits)):
has_draw = True
# --- Action Execution Sub-Routing ---
def fallback_action():
"""Returns a verified passive action to avoid illegal moves."""
if "check" in valid: return Action.check()
if "call" in valid: return Action.call()
return Action.fold()
def raise_action(target_amount: int):
"""Safely scales and clamps values within the allowed server range."""
if "raise" in valid:
clamped = max(state.min_raise, min(state.max_raise, int(target_amount)))
return Action.raise_to(clamped)
if "all_in" in valid and equity > 0.55:
return Action.all_in()
return fallback_action()
# --- Decision Engine Matrix ---
# 1. Short Stack / High-Leverage Shove Engine
# If the pot is large relative to stacks, simplify game tree to push/fold
if phase == "preflop" and effective_stack < 15 * max(1, to_call):
if equity > 0.54:
return Action.all_in() if "all_in" in valid else raise_action(state.max_raise)
if to_call == 0: return fallback_action()
return Action.call() if (equity >= pot_odds and "call" in valid) else fallback_action()
# 2. Preflop Strategy Tree
if phase == "preflop":
if is_button: # We act first on the button (Small Blind)
if to_call <= 2: # Pot is unraised/limped
if equity > 0.48: # Value raise open
return raise_action(max(state.min_raise, 3 * 2))
if equity > 0.38: # Flat call/complete
return Action.call() if "call" in valid else fallback_action()
return fallback_action()
else: # Facing a 3-bet from the Big Blind
if equity > 0.64: return raise_action(to_call * 2.5) # 4-bet
if equity > 0.50 and (equity >= pot_odds): return Action.call() if "call" in valid else fallback_action()
return fallback_action()
else: # We are in the Big Blind
if to_call == 0: # Button limped
if equity > 0.58: return raise_action(state.min_raise * 3) # Punish limpers
return fallback_action()
else: # Button opened a raise
if equity > 0.65: return raise_action(to_call * 3) # 3-bet
if equity >= pot_odds: return Action.call() if "call" in valid else fallback_action()
return fallback_action()
# 3. Postflop Strategy Tree (Flop, Turn, River)
else:
# Value Betting Range
if equity > 0.62:
# Bet larger on wet boards/draw heavy situations (~70% pot), smaller on dry (~50%)
bet_size = pot * 0.65 if equity > 0.75 else pot * 0.50
# Standardize open sizing or incremental response sizing
target = (to_call + bet_size) if to_call > 0 else bet_size
return raise_action(target)
# Tactical Bluff / Semi-Bluff Range
if equity < 0.42:
# 12% pure frequency bluff or 30% semi-bluff on draws when checked to
bluff_roll = random.random()
if to_call == 0 and ((has_draw and bluff_roll < 0.30) or bluff_roll < 0.12):
return raise_action(pot * 0.55)
# Defensive Checking / Calling Range (Bluff Caching & Pot Odds Checks)
if to_call == 0:
return fallback_action()
else:
# Add a minor buffer to pot odds for safe calling margins
buffer = 0.03 if phase != "river" else 0.0
if equity >= (pot_odds + buffer):
return Action.call() if "call" in valid else fallback_action()
return fallback_action()
except Exception:
# Complete fail-safe guard against unforeseen internal logic runtime exceptions
if not state or not state.valid_actions:
return Action.check()
if "check" in state.valid_actions: return Action.check()
if "call" in state.valid_actions: return Action.call()
if "fold" in state.valid_actions: return Action.fold()
return Action.check()