Source code for maverick.players.archetypes.fish

from typing import TYPE_CHECKING

from ...player import Player
from ...enums import ActionType
from ...playeraction import PlayerAction
from ...utils import estimate_holding_strength

if TYPE_CHECKING:  # pragma: no cover
    from ...game import Game

__all__ = ["FishBot"]


[docs] class FishBot(Player): """A generally weak or inexperienced bot that makes systematic, exploitable mistakes. Has access to hand strength evaluation but misinterprets or ignores the information. Calls with weak hands, misunderstands pot odds, and makes poor decisions even with hand equity data available. - **Key Traits:** Plays too many hands, poor position awareness, excessive calling, inconsistent bet sizing, misuses hand strength information. - **Strengths:** Unpredictable in the short term. - **Weaknesses:** Negative expected value over time, calls with poor equity. - **Typical Thought:** *"Maybe this will work."* - **Common At:** Low-stakes online games, casual live games. """ cls_uid = "38781a3af8c4437f94cbaa351398aee9"
[docs] def decide_action( self, *, game: "Game", valid_actions: list[ActionType], min_raise_amount: int, call_amount: int, min_bet_amount: int, ) -> PlayerAction: """Make exploitable mistakes characteristic of weak players, misusing hand strength.""" # Evaluate hand strength but use it poorly private_cards = self.state.holding.cards community_cards = game.state.community_cards # Get hand equity but often ignore it if community_cards: hand_equity = estimate_holding_strength( private_cards, community_cards=community_cards, n_private=game.rules.showdown.hole_cards_required, n_simulations=100, # Fish doesn't spend much time thinking n_players=len(game.state.get_players_in_hand()), ) else: # Pre-flop estimation hand_equity = estimate_holding_strength( private_cards, n_private=game.rules.showdown.hole_cards_required, n_simulations=50, n_players=len(game.state.get_players_in_hand()), ) # Fish has terrible thresholds - calls with anything any_hand = hand_equity > 0.15 # Plays way too many hands # Calls too much (the fish's signature move) - ignores hand strength if ActionType.CALL in valid_actions: # Fish calls with bad odds and weak hands if call_amount <= self.state.stack * 0.4: return PlayerAction(player_uid=self.uid, action_type=ActionType.CALL) # Check when possible (passive) if ActionType.CHECK in valid_actions: return PlayerAction(player_uid=self.uid, action_type=ActionType.CHECK) # Occasionally bets with weird sizing, regardless of hand strength if ActionType.BET in valid_actions: # Inconsistent sizing - sometimes min bet bet_amount = min(min_bet_amount, self.state.stack) return PlayerAction( player_uid=self.uid, action_type=ActionType.BET, amount=bet_amount ) # Rarely raises (not aggressive enough), even with good hands if ActionType.RAISE in valid_actions and any_hand: # Weak raises when does raise raise_amount = min(min_raise_amount, self.state.stack) return PlayerAction( player_uid=self.uid, action_type=ActionType.RAISE, amount=raise_amount ) # Folds when can't call return PlayerAction(player_uid=self.uid, action_type=ActionType.FOLD)