Skip to content

Commit a996b06

Browse files
committed
feat: update example bot to the new Bot class
1 parent da47254 commit a996b06

File tree

1 file changed

+132
-35
lines changed

1 file changed

+132
-35
lines changed

examples/my_first_bot.py

Lines changed: 132 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,160 @@
1+
"""Simple bot example demonstrating the balatrobot API.
2+
3+
This example shows how to create a basic bot that plays Balatro using
4+
a predefined sequence of actions.
5+
"""
6+
17
import itertools
8+
from typing import Any, Iterator
29

310
from balatrobot import Actions, Bot, Decks, Stakes
11+
from balatrobot.base import ActionSchema
412

5-
plays = itertools.cycle(
13+
# Predefined sequence of actions using the ActionSchema format
14+
plays: Iterator[ActionSchema] = itertools.cycle(
615
[
716
# This sequence of plays is winning for the first round
817
# for the seed "EXAMPLE" and the deck "Red Deck" with stake 1.
9-
[Actions.DISCARD_HAND, [2, 3, 4, 6]],
10-
[Actions.DISCARD_HAND, [1, 2, 6, 8]],
11-
[Actions.PLAY_HAND, [2, 3, 5, 6, 7]],
12-
[Actions.PLAY_HAND, [3, 4, 7, 8]],
18+
{"action": Actions.DISCARD_HAND, "args": [2, 3, 4, 6]},
19+
{"action": Actions.DISCARD_HAND, "args": [1, 2, 6, 8]},
20+
{"action": Actions.PLAY_HAND, "args": [2, 3, 5, 6, 7]},
21+
{"action": Actions.PLAY_HAND, "args": [3, 4, 7, 8]},
1322
]
1423
)
1524

1625

1726
class MyFirstBot(Bot):
18-
def __init__(self, deck=Decks.RED, stake=Stakes.WHITE, seed="EXAMPLE"):
27+
"""Example bot implementation using the ActionSchema API.
28+
29+
This bot demonstrates a simple strategy using predefined actions.
30+
It always selects blinds, uses a fixed sequence of plays, and
31+
skips most optional actions.
32+
33+
Attributes:
34+
round_count (int): The current round number.
35+
"""
36+
37+
def __init__(
38+
self,
39+
deck: Decks = Decks.RED,
40+
stake: Stakes = Stakes.WHITE,
41+
seed: str = "EXAMPLE",
42+
) -> None:
43+
"""Initialize the bot with default settings.
44+
45+
Args:
46+
deck (Decks): The deck type to use.
47+
stake (Stakes): The stake level to play at.
48+
seed (str): The random seed for the game.
49+
"""
1950
super().__init__(deck=deck, stake=stake, seed=seed)
20-
self.round_count = 0
51+
self.round_count: int = 0
52+
53+
def skip_or_select_blind(self, env: dict[str, Any]) -> ActionSchema:
54+
"""Always select blinds to play them.
2155
22-
def skip_or_select_blind(self, G):
23-
"""Always select blinds to play them"""
24-
return [Actions.SELECT_BLIND]
56+
Args:
57+
env (dict[str, Any]): The current game environment state.
2558
26-
def select_cards_from_hand(self, G):
27-
"""Simple strategy: play the first card"""
59+
Returns:
60+
ActionSchema: Action to select blind.
61+
"""
62+
return {"action": Actions.SELECT_BLIND, "args": None}
63+
64+
def select_cards_from_hand(self, env: dict[str, Any]) -> ActionSchema:
65+
"""Simple strategy: use predefined card selection sequence.
66+
67+
Args:
68+
env (dict[str, Any]): The current game environment state.
69+
70+
Returns:
71+
ActionSchema: Action with card selection from predefined sequence.
72+
"""
2873
return next(plays)
2974

30-
def select_shop_action(self, G):
31-
"""Always leave the shop immediately"""
32-
return [Actions.END_SHOP]
75+
def select_shop_action(self, env: dict[str, Any]) -> ActionSchema:
76+
"""Always leave the shop immediately.
3377
34-
def select_booster_action(self, G):
35-
"""Skip all booster packs"""
36-
return [Actions.SKIP_BOOSTER_PACK]
78+
Args:
79+
env (dict[str, Any]): The current game environment state.
3780
38-
def sell_jokers(self, G):
39-
"""Don't sell any jokers"""
40-
return [Actions.SELL_JOKER, []]
81+
Returns:
82+
ActionSchema: Action to end shop.
83+
"""
84+
return {"action": Actions.END_SHOP, "args": None}
4185

42-
def rearrange_jokers(self, G):
43-
"""Don't rearrange jokers"""
44-
return [Actions.REARRANGE_JOKERS, []]
86+
def select_booster_action(self, env: dict[str, Any]) -> ActionSchema:
87+
"""Skip all booster packs.
4588
46-
def use_or_sell_consumables(self, G):
47-
"""Don't use consumables"""
48-
return [Actions.USE_CONSUMABLE, []]
89+
Args:
90+
env (dict[str, Any]): The current game environment state.
4991
50-
def rearrange_consumables(self, G):
51-
"""Don't rearrange consumables"""
52-
return [Actions.REARRANGE_CONSUMABLES, []]
92+
Returns:
93+
ActionSchema: Action to skip booster pack.
94+
"""
95+
return {"action": Actions.SKIP_BOOSTER_PACK, "args": None}
5396

54-
def rearrange_hand(self, G):
55-
"""Don't rearrange hand"""
56-
return [Actions.REARRANGE_HAND, []]
97+
def sell_jokers(self, env: dict[str, Any]) -> ActionSchema:
98+
"""Don't sell any jokers.
5799
100+
Args:
101+
env (dict[str, Any]): The current game environment state.
58102
59-
# Run the bot
60-
if __name__ == "__main__":
103+
Returns:
104+
ActionSchema: Action to sell jokers with empty list.
105+
"""
106+
return {"action": Actions.SELL_JOKER, "args": []}
107+
108+
def rearrange_jokers(self, env: dict[str, Any]) -> ActionSchema:
109+
"""Don't rearrange jokers.
110+
111+
Args:
112+
env (dict[str, Any]): The current game environment state.
113+
114+
Returns:
115+
ActionSchema: Action to rearrange jokers with empty list.
116+
"""
117+
return {"action": Actions.REARRANGE_JOKERS, "args": []}
118+
119+
def use_or_sell_consumables(self, env: dict[str, Any]) -> ActionSchema:
120+
"""Don't use consumables.
121+
122+
Args:
123+
env (dict[str, Any]): The current game environment state.
124+
125+
Returns:
126+
ActionSchema: Action to use consumables with empty list.
127+
"""
128+
return {"action": Actions.USE_CONSUMABLE, "args": []}
129+
130+
def rearrange_consumables(self, env: dict[str, Any]) -> ActionSchema:
131+
"""Don't rearrange consumables.
132+
133+
Args:
134+
env (dict[str, Any]): The current game environment state.
135+
136+
Returns:
137+
ActionSchema: Action to rearrange consumables with empty list.
138+
"""
139+
return {"action": Actions.REARRANGE_CONSUMABLES, "args": []}
140+
141+
def rearrange_hand(self, env: dict[str, Any]) -> ActionSchema:
142+
"""Don't rearrange hand.
143+
144+
Args:
145+
env (dict[str, Any]): The current game environment state.
146+
147+
Returns:
148+
ActionSchema: Action to rearrange hand with empty list.
149+
"""
150+
return {"action": Actions.REARRANGE_HAND, "args": []}
151+
152+
153+
def main() -> None:
61154
bot = MyFirstBot()
62155
bot.running = True
63156
bot.run()
157+
158+
159+
if __name__ == "__main__":
160+
main()

0 commit comments

Comments
 (0)