balatrobot 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of balatrobot might be problematic. Click here for more details.

balatrobot/enums.py ADDED
@@ -0,0 +1,478 @@
1
+ from enum import Enum, unique
2
+
3
+
4
+ @unique
5
+ class State(Enum):
6
+ """Game state values representing different phases of gameplay in Balatro,
7
+ from menu navigation to active card play and shop interactions."""
8
+
9
+ SELECTING_HAND = 1
10
+ HAND_PLAYED = 2
11
+ DRAW_TO_HAND = 3
12
+ GAME_OVER = 4
13
+ SHOP = 5
14
+ PLAY_TAROT = 6
15
+ BLIND_SELECT = 7
16
+ ROUND_EVAL = 8
17
+ TAROT_PACK = 9
18
+ PLANET_PACK = 10
19
+ MENU = 11
20
+ TUTORIAL = 12
21
+ SPLASH = 13
22
+ SANDBOX = 14
23
+ SPECTRAL_PACK = 15
24
+ DEMO_CTA = 16
25
+ STANDARD_PACK = 17
26
+ BUFFOON_PACK = 18
27
+ NEW_ROUND = 19
28
+
29
+
30
+ @unique
31
+ class Actions(Enum):
32
+ """Bot action values corresponding to user interactions available in
33
+ different game states, from card play to shop purchases and inventory
34
+ management."""
35
+
36
+ SELECT_BLIND = 1
37
+ SKIP_BLIND = 2
38
+ PLAY_HAND = 3
39
+ DISCARD_HAND = 4
40
+ END_SHOP = 5
41
+ REROLL_SHOP = 6
42
+ BUY_CARD = 7
43
+ BUY_VOUCHER = 8
44
+ BUY_BOOSTER = 9
45
+ SELECT_BOOSTER_CARD = 10
46
+ SKIP_BOOSTER_PACK = 11
47
+ SELL_JOKER = 12
48
+ USE_CONSUMABLE = 13
49
+ SELL_CONSUMABLE = 14
50
+ REARRANGE_JOKERS = 15
51
+ REARRANGE_CONSUMABLES = 16
52
+ REARRANGE_HAND = 17
53
+ PASS = 18
54
+ START_RUN = 19
55
+ SEND_GAMESTATE = 20
56
+
57
+
58
+ @unique
59
+ class Decks(Enum):
60
+ """Starting deck types in Balatro, each providing unique starting
61
+ conditions, card modifications, or special abilities that affect gameplay
62
+ throughout the run."""
63
+
64
+ RED = "Red Deck"
65
+ BLUE = "Blue Deck"
66
+ YELLOW = "Yellow Deck"
67
+ GREEN = "Green Deck"
68
+ BLACK = "Black Deck"
69
+ MAGIC = "Magic Deck"
70
+ NEBULA = "Nebula Deck"
71
+ GHOST = "Ghost Deck"
72
+ ABANDONED = "Abandoned Deck"
73
+ CHECKERED = "Checkered Deck"
74
+ ZODIAC = "Zodiac Deck"
75
+ PAINTED = "Painted Deck"
76
+ ANAGLYPH = "Anaglyph Deck"
77
+ PLASMA = "Plasma Deck"
78
+ ERRATIC = "Erratic Deck"
79
+
80
+
81
+ @unique
82
+ class Stakes(Enum):
83
+ """Difficulty stake levels in Balatro that increase game difficulty through
84
+ various modifiers and restrictions, with higher stakes providing greater
85
+ challenges and rewards."""
86
+
87
+ WHITE = 1
88
+ RED = 2
89
+ GREEN = 3
90
+ BLACK = 4
91
+ BLUE = 5
92
+ PURPLE = 6
93
+ ORANGE = 7
94
+ GOLD = 8
95
+
96
+
97
+ @unique
98
+ class ErrorCode(Enum):
99
+ """Standardized error codes used in BalatroBot API that match those defined in src/lua/api.lua for consistent error handling across the entire system."""
100
+
101
+ # Protocol errors (E001-E005)
102
+ INVALID_JSON = "E001"
103
+ MISSING_NAME = "E002"
104
+ MISSING_ARGUMENTS = "E003"
105
+ UNKNOWN_FUNCTION = "E004"
106
+ INVALID_ARGUMENTS = "E005"
107
+
108
+ # Network errors (E006-E008)
109
+ SOCKET_CREATE_FAILED = "E006"
110
+ SOCKET_BIND_FAILED = "E007"
111
+ CONNECTION_FAILED = "E008"
112
+
113
+ # Validation errors (E009-E012)
114
+ INVALID_GAME_STATE = "E009"
115
+ INVALID_PARAMETER = "E010"
116
+ PARAMETER_OUT_OF_RANGE = "E011"
117
+ MISSING_GAME_OBJECT = "E012"
118
+
119
+ # Game logic errors (E013-E016)
120
+ DECK_NOT_FOUND = "E013"
121
+ INVALID_CARD_INDEX = "E014"
122
+ NO_DISCARDS_LEFT = "E015"
123
+ INVALID_ACTION = "E016"
124
+
125
+
126
+ @unique
127
+ class Jokers(Enum):
128
+ """Joker cards available in Balatro with their effects."""
129
+
130
+ # Common Jokers (Rarity 1)
131
+ j_joker = "+4 Mult"
132
+ j_greedy_joker = "+3 Mult if played hand contains a Diamond"
133
+ j_lusty_joker = "+3 Mult if played hand contains a Heart"
134
+ j_wrathful_joker = "+3 Mult if played hand contains a Spade"
135
+ j_gluttenous_joker = "+3 Mult if played hand contains a Club"
136
+ j_jolly = "+8 Mult if played hand contains a Pair"
137
+ j_zany = "+12 Mult if played hand contains a Three of a Kind"
138
+ j_mad = "+10 Mult if played hand contains a Two Pair"
139
+ j_crazy = "+12 Mult if played hand contains a Straight"
140
+ j_droll = "+10 Mult if played hand contains a Flush"
141
+ j_sly = "+50 Chips if played hand contains a Pair"
142
+ j_wily = "+100 Chips if played hand contains a Three of a Kind"
143
+ j_clever = "+80 Chips if played hand contains a Two Pair"
144
+ j_devious = "+100 Chips if played hand contains a Straight"
145
+ j_crafty = "+80 Chips if played hand contains a Flush"
146
+ j_half = "+20 Mult if played hand contains 3 or fewer cards"
147
+ j_stencil = "×1 Mult for each empty Joker slot"
148
+ j_four_fingers = "All Flushes and Straights can be made with 4 cards"
149
+ j_mime = "Retrigger all card held in hand abilities"
150
+ j_credit_card = "Go up to -$20 in debt"
151
+ j_ceremonial = "When Blind is selected, destroy Joker to the right and permanently add double its sell value to this Mult"
152
+ j_banner = "+30 Chips for each remaining discard"
153
+ j_mystic_summit = "+15 Mult when 0 discards remaining"
154
+ j_marble = "Adds one Stone card to deck when Blind is selected"
155
+ j_loyalty_card = "×4 Mult every 6 hands played, ×1 Mult every 3 hands played"
156
+ j_8_ball = "1 in 4 chance for each 8 played to create a Tarot card when scored"
157
+ j_misprint = "+0 to +23 Mult"
158
+ j_dusk = "Retrigger all played cards in final hand of round"
159
+ j_raised_fist = "Adds double the rank of lowest ranked card held in hand to Mult"
160
+ j_chaos = "1 free Reroll per shop"
161
+ j_fibonacci = "Each played Ace, 2, 3, 5, or 8 gives +8 Mult when scored"
162
+ j_steel_joker = "Gives ×1.5 Mult for each Steel Card in your full deck"
163
+ j_scary_face = "Played face cards give +30 Chips when scored"
164
+ j_abstract = "+3 Mult for each Joker card"
165
+ j_delayed_grat = "Earn $2 per discard if no discards are used by end of round"
166
+ j_hack = "Retrigger each played 2, 3, 4, or 5"
167
+ j_pareidolia = "All cards are considered face cards"
168
+ j_gros_michel = "+15 Mult, 1 in 4 chance this card is destroyed at end of round"
169
+ j_even_steven = "Played cards with even rank give +4 Mult when scored"
170
+ j_odd_todd = "Played cards with odd rank give +31 Chips when scored"
171
+ j_scholar = "Played Aces give +20 Chips and +4 Mult when scored"
172
+ j_business = "Played face cards have a 1 in 2 chance to give $2 when scored"
173
+ j_supernova = "Adds the number of times poker hand has been played this run to Mult"
174
+ j_ride_the_bus = "This Joker gains +1 Mult per consecutive hand played without a face card, resets when face card is played"
175
+ j_space = "1 in 4 chance to upgrade level of played poker hand"
176
+ j_egg = "Gains $3 of sell value at end of round"
177
+ j_burglar = "When Blind is selected, gain +3 hands and lose all discards"
178
+ j_blackboard = "×3 Mult if all cards held in hand are Spades or Clubs"
179
+ j_runner = "Gains +15 Chips if played hand contains a Straight"
180
+ j_ice_cream = "+100 Chips, -5 Chips for every hand played"
181
+ j_dna = "If first hand of round has only 1 card, add a permanent copy to deck and draw it to hand"
182
+ j_splash = "Every played card counts in scoring"
183
+ j_blue_joker = "+2 Chips for each remaining card in deck"
184
+ j_sixth_sense = (
185
+ "If first hand of round is a single 6, destroy it and create a Spectral card"
186
+ )
187
+ j_constellation = "This Joker gains ×0.1 Mult every time a Planet card is used"
188
+ j_hiker = "Every played card permanently gains +5 Chips when scored"
189
+ j_faceless = "Earn $5 if 3 or more face cards are discarded at the same time"
190
+ j_green_joker = "+1 Mult per hand played, -1 Mult per discard"
191
+ j_superposition = "Create a Tarot card if poker hand contains an Ace and a Straight"
192
+ j_todo_list = "Earn $4 if poker hand is a Pair, poker hand changes at end of round"
193
+ j_cavendish = "×3 Mult, 1 in 1000 chance this card is destroyed at end of round"
194
+ j_card_sharp = "×3 Mult if played poker hand has already been played this round"
195
+ j_red_card = "This Joker gains +3 Mult when any Booster Pack is skipped"
196
+ j_madness = "When Small Blind or Big Blind is selected, gain ×0.5 Mult and destroy a random Joker"
197
+ j_square = "This Joker gains +4 Chips if played hand has exactly 4 cards"
198
+ j_seance = "If poker hand is a Straight Flush, create a random Spectral card"
199
+ j_riff_raff = "When Blind is selected, create 2 Common Jokers"
200
+ j_vampire = (
201
+ "This Joker gains ×0.1 Mult per Enhanced card played, removes card Enhancement"
202
+ )
203
+ j_shortcut = "Allows Straights to be made with gaps of 1 rank"
204
+ j_hologram = (
205
+ "This Joker gains ×0.25 Mult every time a playing card is added to your deck"
206
+ )
207
+ j_vagabond = "Create a Tarot card if hand is played with $4 or less"
208
+ j_baron = "Each King held in hand gives ×1.5 Mult"
209
+ j_cloud_9 = "Earn $1 for each 9 in your full deck at end of round"
210
+ j_rocket = (
211
+ "Earn $1 at end of round, payout increases by $2 when Boss Blind is defeated"
212
+ )
213
+ j_obelisk = "This Joker gains ×0.2 Mult per consecutive hand played without playing your most played poker hand"
214
+ j_midas_mask = "All played face cards become Gold cards when scored"
215
+ j_luchador = "Sell this card to disable the current Boss Blind"
216
+ j_photograph = "First played face card gives ×2 Mult"
217
+ j_gift = "Add $1 of sell value to every Joker and Consumable card at end of round"
218
+ j_turtle_bean = "+5 hand size, reduces by 1 each round"
219
+ j_erosion = "+4 Mult for each card below 52 in your full deck"
220
+ j_reserved_parking = "Each face card held in hand has a 1 in 3 chance to give $1"
221
+ j_mail = "Earn $3 for each discarded rank, rank changes every round"
222
+ j_to_the_moon = "Earn an extra $1 of interest for every $5 you have at end of round"
223
+ j_hallucination = (
224
+ "1 in 2 chance to create a Tarot card when any Booster Pack is opened"
225
+ )
226
+ j_fortune_teller = "+1 Mult per Tarot card used this run"
227
+ j_juggler = "+1 hand size"
228
+ j_drunkard = "+1 discard"
229
+ j_stone = "Gives +25 Chips for each Stone Card in your full deck"
230
+ j_golden = "Earn $4 at end of round"
231
+ j_lucky_cat = (
232
+ "This Joker gains ×0.25 Mult every time a Lucky card successfully triggers"
233
+ )
234
+ j_baseball = "Uncommon Jokers each give ×1.5 Mult"
235
+ j_bull = "+2 Chips for each dollar you have"
236
+ j_diet_cola = "Sell this card to create a free Double Tag"
237
+ j_trading = "If first discard of round has only 1 card, destroy it and earn $3"
238
+ j_flash = "This Joker gains +2 Mult per reroll in the shop"
239
+ j_popcorn = "+20 Mult, -4 Mult per round played"
240
+ j_ramen = "×2 Mult, loses ×0.01 Mult per card discarded"
241
+ j_trousers = "This Joker gains +2 Mult if played hand contains a Two Pair"
242
+ j_ancient = "Each played card with suit gives ×1.5 Mult when scored, suit changes at end of round"
243
+ j_walkie_talkie = "Each played 10 or 4 gives +10 Chips and +4 Mult when scored"
244
+ j_selzer = "Retrigger all cards played for the next 10 hands"
245
+ j_castle = "This Joker gains +3 Chips per discarded card, suit changes every round"
246
+ j_smiley = "Played face cards give +5 Mult when scored"
247
+ j_campfire = "This Joker gains ×0.5 Mult for each card sold, resets when Boss Blind is defeated"
248
+ j_golden_ticket = "Played Gold cards earn $4 when scored"
249
+ j_mr_bones = "Prevents death if chips scored are at least 25% of required chips"
250
+ j_acrobat = "×3 Mult on final hand of round"
251
+ j_sock_and_buskin = "Retrigger all played face cards"
252
+ j_swashbuckler = "Adds the sell value of all other owned Jokers to Mult"
253
+ j_troubadour = "+2 hand size, -1 hand per round"
254
+ j_certificate = (
255
+ "When round begins, add a random playing card with a random seal to your hand"
256
+ )
257
+ j_smeared = "Hearts and Diamonds count as the same suit, Spades and Clubs count as the same suit"
258
+ j_throwback = "×0.25 Mult for each skipped Blind this run"
259
+ j_hanging_chad = "Retrigger first played card 2 additional times"
260
+ j_rough_gem = "Played cards with Diamond suit earn $1 when scored"
261
+ j_bloodstone = (
262
+ "1 in 3 chance for played cards with Heart suit to give ×1.5 Mult when scored"
263
+ )
264
+ j_arrowhead = "Played cards with Spade suit give +50 Chips when scored"
265
+ j_onyx_agate = "Played cards with Club suit give +7 Mult when scored"
266
+ j_glass = "Gives ×2 Mult for each Glass Card in your full deck"
267
+ j_ring_master = "Joker, Tarot, Planet, and Spectral cards may appear multiple times"
268
+ j_flower_pot = "×3 Mult if poker hand contains a Diamond card, a Club card, a Heart card, and a Spade card"
269
+ j_blueprint = "Copies ability of Joker to the right"
270
+ j_wee = "This Joker gains +8 Chips when each played 2 is scored"
271
+ j_merry_andy = "+3 discards, -1 hand size"
272
+ j_oops = "All number cards are 6s"
273
+ j_idol = (
274
+ "Each played card of rank gives ×2 Mult when scored, rank changes every round"
275
+ )
276
+ j_seeing_double = "×2 Mult if played hand has a scoring Club card and a scoring card of any other suit"
277
+ j_matador = "Earn $8 if played hand triggers the Boss Blind ability"
278
+ j_hit_the_road = "This Joker gains ×0.5 Mult for every Jack discarded this round"
279
+ j_duo = "×2 Mult if played hand contains a Pair"
280
+ j_trio = "×3 Mult if played hand contains a Three of a Kind"
281
+ j_family = "×4 Mult if played hand contains a Four of a Kind"
282
+ j_order = "×3 Mult if played hand contains a Straight"
283
+ j_tribe = "×2 Mult if played hand contains a Flush"
284
+ j_stuntman = "+250 Chips, -2 hand size"
285
+ j_invisible = "After 2 rounds, sell this card to Duplicate a random Joker"
286
+ j_brainstorm = "Copies the ability of leftmost Joker"
287
+ j_satellite = "Earn $1 at end of round per unique Planet card used this run"
288
+ j_shoot_the_moon = "Each Queen held in hand gives +13 Mult"
289
+ j_drivers_license = (
290
+ "×3 Mult if you have at least 16 Enhanced cards in your full deck"
291
+ )
292
+ j_cartomancer = "Create a Tarot card when Blind is selected"
293
+ j_astronomer = "All Planet cards and Celestial Packs in the shop are free"
294
+ j_burnt = "Upgrade the level of the first discarded poker hand each round"
295
+ j_bootstraps = "+2 Mult for every $5 you have"
296
+ j_canio = "This Joker gains ×1 Mult when a face card is destroyed"
297
+ j_triboulet = "Played Kings and Queens each give ×2 Mult when scored"
298
+ j_yorick = "This Joker gains ×1 Mult every 23 cards discarded"
299
+ j_chicot = "Disables effect of every Boss Blind"
300
+ j_perkeo = "Creates a Negative copy of 1 random Consumable card in your possession at the end of the shop"
301
+
302
+
303
+ @unique
304
+ class Consumables(Enum):
305
+ """Consumable cards available in Balatro with their effects."""
306
+
307
+ # Tarot consumable cards and their effects.
308
+
309
+ c_fool = (
310
+ "Creates the last Tarot or Planet Card used during this run (The Fool excluded)"
311
+ )
312
+ c_magician = "Enhances 2 selected cards to Lucky Cards"
313
+ c_high_priestess = "Creates up to 2 random Planet cards (Must have room)"
314
+ c_empress = "Enhances 2 selected cards to Mult Cards"
315
+ c_emperor = "Creates up to 2 random Tarot cards (Must have room)"
316
+ c_hierophant = "Enhances 2 selected cards to Bonus Cards"
317
+ c_lovers = "Enhances 1 selected card to a Wild Card"
318
+ c_chariot = "Enhances 1 selected card to a Steel Card"
319
+ c_justice = "Enhances 1 selected card to a Glass Card"
320
+ c_hermit = "Doubles money (max of $20)"
321
+ c_wheel_of_fortune = "1 in 4 chance to add Foil, Holographic, or Polychrome edition to a random Joker"
322
+ c_strength = "Increases rank of up to 2 selected cards by 1"
323
+ c_hanged_man = "Destroys up to 2 selected cards"
324
+ c_death = "Select 2 cards, convert the left into the right"
325
+ c_temperance = "Gives the total sell value of all current Jokers (Max of $50)"
326
+ c_devil = "Enhances 1 selected card to a Gold Card"
327
+ c_tower = "Enhances 1 selected card to a Stone Card"
328
+ c_star = "Converts up to 3 selected cards to Diamonds"
329
+ c_moon = "Converts up to 3 selected cards to Clubs"
330
+ c_sun = "Converts up to 3 selected cards to Hearts"
331
+ c_judgement = "Creates a random Joker card (Must have room)"
332
+ c_world = "Converts up to 3 selected cards to Spades"
333
+
334
+ # Planet consumable cards that level up poker hands.
335
+
336
+ c_mercury = "Levels up Pair"
337
+ c_venus = "Levels up Three of a Kind"
338
+ c_earth = "Levels up Full House"
339
+ c_mars = "Levels up Four of a Kind"
340
+ c_jupiter = "Levels up Flush"
341
+ c_saturn = "Levels up Straight"
342
+ c_uranus = "Levels up Two Pair"
343
+ c_neptune = "Levels up Straight Flush"
344
+ c_pluto = "Levels up High Card"
345
+ c_planet_x = "Levels up Flush House"
346
+ c_ceres = "Levels up Five of a Kind"
347
+ c_eris = "Levels up Flush Five"
348
+
349
+ # Spectral consumable cards with powerful effects.
350
+
351
+ c_familiar = "Destroy 1 random card in your hand, add 3 random Enhanced face cards to your hand"
352
+ c_grim = (
353
+ "Destroy 1 random card in your hand, add 2 random Enhanced Aces to your hand"
354
+ )
355
+ c_incantation = "Destroy 1 random card in your hand, add 4 random Enhanced numbered cards to your hand"
356
+ c_talisman = "Add a Gold Seal to 1 selected card"
357
+ c_aura = "Add Foil, Holographic, or Polychrome effect to 1 selected card"
358
+ c_wraith = "Creates a random Rare Joker, sets money to $0"
359
+ c_sigil = "Converts all cards in hand to a single random suit"
360
+ c_ouija = "Converts all cards in hand to a single random rank, -1 hand size"
361
+ c_ectoplasm = "Add Negative to a random Joker, -1 hand size for rest of run"
362
+ c_immolate = "Destroys 5 random cards in hand, gain $20"
363
+ c_ankh = "Create a copy of a random Joker, destroy all other Jokers"
364
+ c_deja_vu = "Add a Red Seal to 1 selected card"
365
+ c_hex = "Add Polychrome to a random Joker, destroy all other Jokers"
366
+ c_trance = "Add a Blue Seal to 1 selected card"
367
+ c_medium = "Add a Purple Seal to 1 selected card"
368
+ c_cryptid = "Create 2 copies of 1 selected card"
369
+ c_soul = "Creates a Legendary Joker (Must have room)"
370
+ c_black_hole = "Upgrade every poker hand by 1 level"
371
+
372
+
373
+ @unique
374
+ class Vouchers(Enum):
375
+ """Voucher cards that provide permanent upgrades."""
376
+
377
+ v_overstock_norm = "+1 card slot available in shop (to 3 slots)"
378
+ v_clearance_sale = "All cards and packs in shop are 25% off"
379
+ v_hone = "Foil, Holographic, and Polychrome cards appear 2X more frequently"
380
+ v_reroll_surplus = "Rerolls cost $2 less"
381
+ v_crystal_ball = "+1 consumable slot"
382
+ v_telescope = (
383
+ "Celestial Packs always contain the Planet card for your most played poker hand"
384
+ )
385
+ v_grabber = "Permanently gain +1 hand per round"
386
+ v_wasteful = "Permanently gain +1 discard per round"
387
+ v_tarot_merchant = "Tarot cards appear 2X more frequently in the shop"
388
+ v_planet_merchant = "Planet cards appear 2X more frequently in the shop"
389
+ v_seed_money = "Raise the cap on interest earned in each round to $10"
390
+ v_blank = "Does nothing"
391
+ v_magic_trick = "Playing cards are available for purchase in the shop"
392
+ v_hieroglyph = "-1 Ante, -1 hand each round"
393
+ v_directors_cut = "Reroll Boss Blind 1 time per Ante, $10 per roll"
394
+ v_paint_brush = "+1 hand size"
395
+ v_overstock_plus = "+1 card slot available in shop (to 4 slots)"
396
+ v_liquidation = "All cards and packs in shop are 50% off"
397
+ v_glow_up = "Foil, Holographic, and Polychrome cards appear 4X more frequently"
398
+ v_reroll_glut = "Rerolls cost an additional $2 less"
399
+ v_omen_globe = "Spectral cards may appear in any of the Arcana Packs"
400
+ v_observatory = "Planet cards in your consumable area give ×1.5 Mult for their specific poker hand"
401
+ v_nacho_tong = "Permanently gain an additional +1 hand per round"
402
+ v_recyclomancy = "Permanently gain an additional +1 discard per round"
403
+ v_tarot_tycoon = "Tarot cards appear 4X more frequently in the shop"
404
+ v_planet_tycoon = "Planet cards appear 4X more frequently in the shop"
405
+ v_money_tree = "Raise the cap on interest earned in each round to $20"
406
+ v_antimatter = "+1 Joker slot"
407
+ v_illusion = "Playing cards in shop may have an Enhancement, Edition, or Seal"
408
+ v_petroglyph = "-1 Ante again, -1 discard each round"
409
+ v_retcon = "Reroll Boss Blind unlimited times, $10 per roll"
410
+ v_palette = "+1 hand size again"
411
+
412
+
413
+ @unique
414
+ class Tags(Enum):
415
+ """Tag rewards that provide various benefits."""
416
+
417
+ tag_uncommon = "Shop has a free Uncommon Joker"
418
+ tag_rare = "Shop has a free Rare Joker"
419
+ tag_negative = "Next base edition shop Joker becomes Negative"
420
+ tag_foil = "Next base edition shop Joker becomes Foil"
421
+ tag_holo = "Next base edition shop Joker becomes Holographic"
422
+ tag_polychrome = "Next base edition shop Joker becomes Polychrome"
423
+ tag_investment = "After defeating this Boss Blind, gain $25"
424
+ tag_voucher = "Adds one Voucher to the next shop"
425
+ tag_boss = "Rerolls the Boss Blind"
426
+ tag_standard = "Gives a free Mega Standard Pack"
427
+ tag_charm = "Gives a free Mega Arcana Pack"
428
+ tag_meteor = "Gives a free Mega Celestial Pack"
429
+ tag_buffoon = "Gives a free Mega Buffoon Pack"
430
+ tag_handy = "Gain $1 for each hand played this run"
431
+ tag_garbage = "Gain $1 for each unused discard this run"
432
+ tag_ethereal = "Gives a free Spectral Pack"
433
+ tag_coupon = "Initial cards and booster packs in next shop are free"
434
+ tag_double = (
435
+ "Gives a copy of the next selected Tag, excluding subsequent Double Tags"
436
+ )
437
+ tag_juggle = "+3 Hand Size for the next round only"
438
+ tag_d_six = "In the next Shop, Rerolls start at $0"
439
+ tag_top_up = "Create up to 2 Common Jokers (if you have space)"
440
+ tag_speed = "Gives $5 for each Blind you've skipped this run"
441
+ tag_orbital = "Upgrade poker hand by 3 levels"
442
+ tag_economy = "Doubles your money (max of $40)"
443
+ tag_rush = "+1 Boss Blind reward"
444
+ tag_skip = "Gives $5 plus $1 for every skipped Blind this run"
445
+
446
+
447
+ @unique
448
+ class Editions(Enum):
449
+ """Special editions that can be applied to cards."""
450
+
451
+ e_foil = "+50 Chips"
452
+ e_holo = "+10 Mult"
453
+ e_polychrome = "×1.5 Mult"
454
+ e_negative = "+1 Joker slot"
455
+
456
+
457
+ @unique
458
+ class Enhancements(Enum):
459
+ """Enhancements that can be applied to playing cards."""
460
+
461
+ m_bonus = "+30 Chips when scored"
462
+ m_mult = "+4 Mult when scored"
463
+ m_wild = "Can be used as any suit"
464
+ m_glass = "×2 Mult, 1 in 4 chance to destroy when scored"
465
+ m_steel = "×1.5 Mult when this card stays in hand"
466
+ m_stone = "+50 Chips when scored, no rank or suit"
467
+ m_gold = "$3 when this card is held in hand at end of round"
468
+ m_lucky = "1 in 5 chance for +20 Mult and 1 in 15 chance for $20 when scored"
469
+
470
+
471
+ @unique
472
+ class Seals(Enum):
473
+ """Seals that can be applied to playing cards."""
474
+
475
+ Red = "Retrigger this card 1 time. Retriggering means that the effect of the cards is applied again including counting again in the score calculation"
476
+ Blue = "Creates the Planet card for the final poker hand played if held in hand at end of round (Must have room)"
477
+ Gold = "$3 when this card is played and scores"
478
+ Purple = "Creates a Tarot card when discarded (Must have room)"
@@ -0,0 +1,166 @@
1
+ """Custom exceptions for BalatroBot API."""
2
+
3
+ from typing import Any
4
+
5
+ from .enums import ErrorCode
6
+
7
+
8
+ class BalatroError(Exception):
9
+ """Base exception for all BalatroBot errors."""
10
+
11
+ def __init__(
12
+ self,
13
+ message: str,
14
+ error_code: str | ErrorCode,
15
+ state: int | None = None,
16
+ context: dict[str, Any] | None = None,
17
+ ) -> None:
18
+ super().__init__(message)
19
+ self.message = message
20
+ self.error_code = (
21
+ error_code if isinstance(error_code, ErrorCode) else ErrorCode(error_code)
22
+ )
23
+ self.state = state
24
+ self.context = context or {}
25
+
26
+ def __str__(self) -> str:
27
+ return f"{self.error_code.value}: {self.message}"
28
+
29
+ def __repr__(self) -> str:
30
+ return f"{self.__class__.__name__}(message='{self.message}', error_code='{self.error_code.value}', state={self.state})"
31
+
32
+
33
+ # Protocol errors (E001-E005)
34
+ class InvalidJSONError(BalatroError):
35
+ """Invalid JSON in request (E001)."""
36
+
37
+ pass
38
+
39
+
40
+ class MissingNameError(BalatroError):
41
+ """Message missing required 'name' field (E002)."""
42
+
43
+ pass
44
+
45
+
46
+ class MissingArgumentsError(BalatroError):
47
+ """Message missing required 'arguments' field (E003)."""
48
+
49
+ pass
50
+
51
+
52
+ class UnknownFunctionError(BalatroError):
53
+ """Unknown function name (E004)."""
54
+
55
+ pass
56
+
57
+
58
+ class InvalidArgumentsError(BalatroError):
59
+ """Invalid arguments provided (E005)."""
60
+
61
+ pass
62
+
63
+
64
+ # Network errors (E006-E008)
65
+ class SocketCreateFailedError(BalatroError):
66
+ """Socket creation failed (E006)."""
67
+
68
+ pass
69
+
70
+
71
+ class SocketBindFailedError(BalatroError):
72
+ """Socket bind failed (E007)."""
73
+
74
+ pass
75
+
76
+
77
+ class ConnectionFailedError(BalatroError):
78
+ """Connection failed (E008)."""
79
+
80
+ pass
81
+
82
+
83
+ # Validation errors (E009-E012)
84
+ class InvalidGameStateError(BalatroError):
85
+ """Invalid game state for requested action (E009)."""
86
+
87
+ pass
88
+
89
+
90
+ class InvalidParameterError(BalatroError):
91
+ """Invalid or missing required parameter (E010)."""
92
+
93
+ pass
94
+
95
+
96
+ class ParameterOutOfRangeError(BalatroError):
97
+ """Parameter value out of valid range (E011)."""
98
+
99
+ pass
100
+
101
+
102
+ class MissingGameObjectError(BalatroError):
103
+ """Required game object missing (E012)."""
104
+
105
+ pass
106
+
107
+
108
+ # Game logic errors (E013-E016)
109
+ class DeckNotFoundError(BalatroError):
110
+ """Deck not found (E013)."""
111
+
112
+ pass
113
+
114
+
115
+ class InvalidCardIndexError(BalatroError):
116
+ """Invalid card index (E014)."""
117
+
118
+ pass
119
+
120
+
121
+ class NoDiscardsLeftError(BalatroError):
122
+ """No discards remaining (E015)."""
123
+
124
+ pass
125
+
126
+
127
+ class InvalidActionError(BalatroError):
128
+ """Invalid action for current context (E016)."""
129
+
130
+ pass
131
+
132
+
133
+ # Mapping from error codes to exception classes
134
+ ERROR_CODE_TO_EXCEPTION = {
135
+ ErrorCode.INVALID_JSON: InvalidJSONError,
136
+ ErrorCode.MISSING_NAME: MissingNameError,
137
+ ErrorCode.MISSING_ARGUMENTS: MissingArgumentsError,
138
+ ErrorCode.UNKNOWN_FUNCTION: UnknownFunctionError,
139
+ ErrorCode.INVALID_ARGUMENTS: InvalidArgumentsError,
140
+ ErrorCode.SOCKET_CREATE_FAILED: SocketCreateFailedError,
141
+ ErrorCode.SOCKET_BIND_FAILED: SocketBindFailedError,
142
+ ErrorCode.CONNECTION_FAILED: ConnectionFailedError,
143
+ ErrorCode.INVALID_GAME_STATE: InvalidGameStateError,
144
+ ErrorCode.INVALID_PARAMETER: InvalidParameterError,
145
+ ErrorCode.PARAMETER_OUT_OF_RANGE: ParameterOutOfRangeError,
146
+ ErrorCode.MISSING_GAME_OBJECT: MissingGameObjectError,
147
+ ErrorCode.DECK_NOT_FOUND: DeckNotFoundError,
148
+ ErrorCode.INVALID_CARD_INDEX: InvalidCardIndexError,
149
+ ErrorCode.NO_DISCARDS_LEFT: NoDiscardsLeftError,
150
+ ErrorCode.INVALID_ACTION: InvalidActionError,
151
+ }
152
+
153
+
154
+ def create_exception_from_error_response(
155
+ error_response: dict[str, Any],
156
+ ) -> BalatroError:
157
+ """Create an appropriate exception from an error response."""
158
+ error_code = ErrorCode(error_response["error_code"])
159
+ exception_class = ERROR_CODE_TO_EXCEPTION.get(error_code, BalatroError)
160
+
161
+ return exception_class(
162
+ message=error_response["error"],
163
+ error_code=error_code,
164
+ state=error_response["state"],
165
+ context=error_response.get("context"),
166
+ )