Skip to content

Instantly share code, notes, and snippets.

@ky28059
Last active October 26, 2025 21:52
Show Gist options
  • Select an option

  • Save ky28059/3e798b904548e506707607d0012b2c11 to your computer and use it in GitHub Desktop.

Select an option

Save ky28059/3e798b904548e506707607d0012b2c11 to your computer and use it in GitHub Desktop.

m0leCon Teaser CTF 2025 โ€” Precipice

Have you ever played bala...precipice???

nc precipice.challs.m0lecon.it 14615

We're given a lengthy Python interface that looks like this:

#!/usr/bin/env python3

from numpy import float32

from game_state import GameState
from scoring import base_scores


def play_round(state):
    assert not state.round_over
    last_cmd = ""
    try:
        while not state.round_over:
            ts = input(">")
            if len(ts) == 0:
                ts = last_cmd
            for t in ts.split(" "):
                if len(t) == 0:
                    continue
                elif t in {"?", "h", "help", }:
                    print(
                        " \"?\" or \"h\" or \"help\" to show this message",
                        " \"v\" or \"verbose\" to toggle verbose ui",
                        " \"s\" or \"sort\" to toggle sorting by rank or by suit",
                        " <a number> to select card by number",
                        " \"p\" or \"play\" to play hand",
                        " \"d\" or \"discard\" to discard hand",
                        " \"a\" or \"ability\" to see the jokers abilities",
                        " \"l\" or \"level\" to see hand level and scoring",
                        sep="\n"
                    )
                elif t in {"v", "verbose", }:
                    state.toggle_verbose_ui()
                elif t in {"s", "sort", }:
                    state.toggle_sorting_order()
                elif t in {"p", "play", }:
                    state.play()
                elif t in {"d", "discard", }:
                    state.discard()
                elif t.isdecimal():
                    state.select(int(t)-1)
                elif t in {"a", "ability", }:
                    for i, j in enumerate(state.jokers, start=1):
                        print(
                            f" -{i}: {j.name}: {j.description} {j.currently(state)}")
                elif t in {"l", "level", }:
                    for hand_type in base_scores.keys():
                        hand_level = state.hand_levels[hand_type]
                        chips, mult = [
                            b * hand_level for b in base_scores[hand_type]]
                        print(f" {hand_type}: {hand_level}: ${chips} X{mult}")
                else:
                    print(f"command not supported: {t!r}")
            last_cmd = ts
    except KeyboardInterrupt:
        pass


def play_game(state):
    state.in_shop()
    last_cmd = ""
    try:
        while not state.game_over:
            t = input(">").strip()
            if len(t) == 0:
                t = last_cmd
            if t in {"?", "h", "help", }:
                print(
                    " \"?\" or \"h\" or \"help\" to show this message",
                    " \"v\" or \"verbose\" to toggle verbose ui",
                    " \"p\" or \"play\" to buy in and play the next ante",
                    " \"f\" or \"forfit\" to forfit (Loser)",
                    f" \"r\" or \"reroll\" to reroll the shop (${state.reroll_shop_price})",
                    " <a number> to select shop joker by number",
                    " \"b\" or \"buy\" to buy select jokers",
                    " -<a number> to select owned joker by number",
                    " \"s\" or \"sell\" to sell select jokers",
                    sep="\n"
                )
            elif t in {"v", "verbose", }:
                state.toggle_verbose_ui()
            elif t in {"p", "play", }:
                state.out_shop()
                state.buy_in()
                play_round(state)
                state.round_ended()
                state.in_shop()
            elif t in {"f", "forfit", }:
                state.quit()
                break
            elif t in {"r", "reroll", }:
                state.reroll_shop()
            elif t.isdecimal():
                state.select_shop_joker(int(t)-1)
            elif t[0] == "-" and t[1:].isdecimal():
                state.select_joker(int(t[1:])-1)
            elif t in {"b", "buy", }:
                state.buy_jokers()
            elif t in {"s", "sell", }:
                state.sell_jokers()
            else:
                print(f"command not supported: {t!r}")
            last_cmd = t
    except KeyboardInterrupt:
        pass


if __name__ == "__main__":
    state = GameState(
        initial_score=0,
        initial_hands=5,
        initial_discards=5,
    )
    play_game(state)

Reading through the source code, it looks like the server implements a game similar to Balatro, and the goal is to beat the last ante for the flag:

   @renders
    def round_ended(self):
        assert not self.game_over
        assert self.round_over
        assert self.hand is not None
        if self.current_ante == len(self.antes) - 1:
            import os

            # import sys
            self.header += [
                CardClass.joker_art,
                choice([
                    "You Aced it!",
                    "You dealt with that pretty well!",
                    "Looks like you weren't bluffing!",
                    "Too bad these chips are all virtual...",
                    "How the turn tables.",
                    "Looks like I've taught you well!",
                    "You made some heads up plays!",
                    "Good thing I didn't bet against you!",
                ]),
            ]
            self.message.append("GG")
            with open("/flag", "r") as f:
                flag = f.read()
            self.message.append(flag)
            import sys
            print("FLAGGED", file=sys.stderr)
            print("ante:", self.current_ante, file=sys.stderr)
            print("score:", self.score, file=sys.stderr)
            print("deck_len:", len(self.game_deck), file=sys.stderr)
            list(map(lambda j: print(j.name, j.description, j.currently(self), file=sys.stderr), self.jokers))
            self.game_over = True
            return
        self.game_deck += self.hand
        self.game_deck += self.discard_pile
        self.discard_pile.clear()
        # ...
antes = [
    0,
    100,
    300,
    800,
    2000,
    5000,
    11000,
    20000,
    35000,
    50000,
    110000,
    1560000,
    17200000,
    1300000000,
    147000000000,
    12.9e13,
    17.7e16,
    18.6e20,
    14.2e25,
    19.2e30,
    19.2e36,
    24.3e43,
    29.7e50,
    21.0e59,
    25.8e67,
    21.6e77,
    22.4e87,
    21.9e98,
    28.4e109,
    22.0e122,
    22.7e135,
    32.1e149,
    39.9e163,
    32.7e179,
    34.4e195,
    34.4e212,
    32.8e230,
    31.1e249,
    32.7e268,
    34.5e288,
    34.8e309,
]

But how do we score 34.8e309? In regular Balatro, scoring close to inf is only possible by stacking retriggers and xMult via for e.g. Perkeo + Observatory, Baron + Mime + steel cards + red seals, etc. Looking in cards.py, however, it's clear that many of these strategies are simply not implemented in this limited recreation of Balatro:

from enum import Enum
from itertools import chain

cards_mode = "txt"
cards_mode = "utf"


class CardEnhancement(Enum):
    NONE = 0
    GOLD = 1
    STONE = 2
    STEEL = 3


# ANSI escape codes for colors
COLORS = {
    "reset": "\033[0m",
    "black": "\033[90m",
    "red": "\033[91m",
    "green": "\033[92m",
    "yellow": "\033[93m",
    "blue": "\033[94m",
    "purple": "\033[95m",
    "white_background": "\033[107m",
}

SUIT_COLORS = {
    None: COLORS["reset"],
    0: COLORS["red"],
    1: COLORS["purple"],
    2: COLORS["blue"],
    3: COLORS["black"],
}


class Card:
    suits = None
    figures = None
    ranks = None
    ranks_sorting_map = {r: i for i, r in enumerate(
        chain(range(2, 13+1), range(1, 1+1)),
        start=2
    )} | {None: 0}
    is_joker = False

    @classmethod
    def clean_art(cls, art):
        # Remove all ANSI color codes for rank/suit extraction
        for color in COLORS.values():
            art = art.replace(color, "")
        return art

    @classmethod
    def color_art(cls, art, suit=None, rank=None, enhancement=CardEnhancement.NONE):
        if enhancement == CardEnhancement.GOLD:
            return f"{COLORS['yellow']}{art}{COLORS['reset']}"
        elif enhancement == CardEnhancement.STONE:
            return f"{COLORS['white_background']}{COLORS['black']}{art}๐Ÿชจ{COLORS['reset']}"
        assert enhancement == CardEnhancement.NONE
        return f"{SUIT_COLORS[suit]}{art}{COLORS['reset']}"

    @classmethod
    def art_factory(cls, suit, rank, enhancement=CardEnhancement.NONE):
        raise NotImplementedError()

    @classmethod
    def rank_from_art(cls, art):
        raise NotImplementedError()

    @classmethod
    def suit_from_art(cls, art):
        raise NotImplementedError()

    def __init__(self, suit, rank, chips_bonus=0, mult_bonus=1, enhancement=CardEnhancement.NONE):
        self.rank = rank
        self.sorting_rank = self.ranks_sorting_map[self.rank]
        self.suit = suit
        self.chips_bonus = chips_bonus
        self.mult_bonus = mult_bonus
        self.enhancement = enhancement
        self.art = self.art_factory(suit, rank, enhancement)

    def __str__(self) -> str:
        return self.art

    def __repr__(self) -> str:
        return self.__str__()

    def is_face_card(self):
        return self.rank in [11, 12, 13]

# ...

if cards_mode == "utf":
    CardClass = UTFCard
elif cards_mode == "txt":
    CardClass = TXTCard
else:
    raise NotImplementedError(f"rendering mode {cards_mode!r} not supported")

cards = [CardClass(s, r) for s in range(4) for r in range(1, 13+1)]

assert len(CardClass.suits) == 4, [CardClass.suits, len(CardClass.suits)]
assert len(CardClass.figures) == 3, [CardClass.figures, len(CardClass.figures)]
assert len(CardClass.ranks) == 13, [CardClass.ranks, len(CardClass.ranks)]
assert len(cards) == len(CardClass.ranks) * \
    len(CardClass.suits), [cards, len(cards)]


def sort_hand(hand, reverse=False, suit_first=False, ace_after_king=True):
    if suit_first:
        return sorted(hand, reverse=reverse, key=lambda c: (c.suit, c.sorting_rank if ace_after_king else c.rank))
    else:
        return sorted(hand, reverse=reverse, key=lambda c: (c.sorting_rank if ace_after_king else c.rank, c.suit))

Indeed, we only have two "real" card enhancements: Gold and Stone (steel cards are unimplemented, and if one somehow gets created the server simply crashes). Furthermore, tarot cards, spectral cards, planets, and seals are all missing.

(As a side note, steel cards ended up being quite a bit of a red herring, as the server also defines a custom non-Balatro joker meant to create steel cards which also crashes the game if it was ever triggered; luckily, this joker was removed from the joker map and couldn't appear in a shop, unlike some other perpetrators...)

from cards import CardEnhancement

from .joker_base import JokerClass, JokerRarity


class SteelMask(JokerClass):
    description = "All face cards become Steel cards when played"
    rarity = JokerRarity.UNCOMMON
    price = 7

    def on_card_scoring(self, state, i, card, ignore_jokers=None):
        if state.is_face_card(card):
            raise NotImplementedError()  # TODO

Note also that scoring is tied to your money (or more precisely, buying from the shop simply subtracts from your score), and score carries over between rounds. As opposed to normal Balatro, this allows us to pretty much buy anything we want from the shop, as hand scores are in the O(100) even on the first round, and rerolls cost a static $5 with jokers costing < $10.

    @renders
    def buy_jokers(self):
        assert self.jokers_in_shop is not None
        assert self.jokers_selected_in_shop is not None
        if len(self.jokers_selected_in_shop) > self.max_joker_slots - len(self.jokers):
            self.message.append(f"You can't have more than {self.max_joker_slots} jokers.")
            return
        price = 0
        for joker_class in self.jokers_selected_in_shop:
            price += joker_class.price
        if price > self.score:
            self.message.append(f"You don't have enough money to buy the selected jokers (${price!r}).")
            return
        while len(self.jokers_selected_in_shop) > 0:
            joker = self.jokers_selected_in_shop.pop(0)
            self.score -= joker.price
            self.jokers.append(joker)
            self.jokers_in_shop.remove(joker)
            for joker in self.jokers:
                joker.on_joker_buy(self, joker)
        self.check_game_over()

But even so, how do we even score close to e309? The key idea is this: jokers that provide retriggers are implemented in the game by re-calling the method on state that runs a specific phase of scoring.

from .joker_base import JokerClass, JokerRarity


class HangingChad(JokerClass):
    description = "Retrigger first played card used in scoring 2 additional times"
    rarity = JokerRarity.COMMON
    price = 4

    def on_card_scoring(self, state, i, card, ignore_jokers=None):
        if i == 0:
            # Retrigger 2 additional times
            for _ in range(2):
                state.message.append(f"{self.name}: retrigger card")
                if ignore_jokers is None:
                    ignore_jokers = set()
                ignore_jokers.add(self)
                state.compute_card_score(i, card, ignore_jokers=ignore_jokers)
                ignore_jokers.discard(self)

(here, the Hanging Chad calls state.compute_card_score() again, which as a side effect re-triggers all jokers' on_card_scoring() callbacks). To avoid infinitely looping with themselves, jokers like the Hanging Chad add themselves to an ignore_jokers list, for which all jokers on the list are skipped in the rerun scoring phase.

Enter the Blueprint:

from copy import deepcopy

from .joker_base import JokerClass, JokerRarity


class Blueprint(JokerClass):
    description = "Copies ability of Joker to the right"
    rarity = JokerRarity.RARE
    price = 10

    def currently(self, state):
        if self.copied_joker is None:
            return "(none)"
        return f"(currently: {self.copied_joker.name})"

    def __init__(self):
        super().__init__()
        self.copied_joker = None

    def find_joker_to_copy(self, state):
        self.copied_joker = None
        found = False
        for joker in state.jokers:
            if found:
                self.copied_joker = deepcopy(joker)
                break
            if joker is self:
                found = True
                continue

    def on_joker_buy(self, state, joker):
        self.find_joker_to_copy(state)
        if self.copied_joker is not None:
            self.copied_joker.on_joker_buy(state, joker)

    def on_joker_sell(self, state, joker):
        self.find_joker_to_copy(state)
        if self.copied_joker is not None:
            self.copied_joker.on_joker_sell(state, joker)

    def on_card_scoring(self, state, i, card, ignore_jokers=None):
        if self.copied_joker is not None:
            self.copied_joker.on_card_scoring(
                state, i, card, ignore_jokers=ignore_jokers)

    def on_hand_scoring(self, state, ignore_jokers=None):
        if self.copied_joker is not None:
            self.copied_joker.on_hand_scoring(
                state, ignore_jokers=ignore_jokers)

    def on_in_hand_card_scoring(self, state, i, card, ignore_jokers=None):
        if self.copied_joker is not None:
            self.copied_joker.on_in_hand_card_scoring(
                state, i, card, ignore_jokers=ignore_jokers)

    def on_in_hand_scoring(self, state, ignore_jokers=None):
        if self.copied_joker is not None:
            self.copied_joker.on_in_hand_scoring(
                state, ignore_jokers=ignore_jokers)

    def on_round_start(self, state):
        if self.copied_joker is not None:
            self.copied_joker.on_round_start(state)

    def on_round_end(self, state):
        if self.copied_joker is not None:
            self.copied_joker.on_round_end(state)

    def on_discard(self, state):
        if self.copied_joker is not None:
            self.copied_joker.on_discard(state)

    def on_play(self, state):
        if self.copied_joker is not None:
            self.copied_joker.on_play(state)

    def on_hand_updated(self, state):
        if self.copied_joker is not None:
            self.copied_joker.on_hand_updated(state)

    def on_card_added_to_deck(self, state, card):
        if self.copied_joker is not None:
            self.copied_joker.on_card_added_to_deck(state, card)

    def on_card_removed_from_deck(self, state, card):
        if self.copied_joker is not None:
            self.copied_joker.on_card_removed_from_deck(state, card)

    def overrides_is_face_card(self, state, card):
        if self.copied_joker is not None:
            return self.copied_joker.overrides_is_face_card(state, card)
        return super().overrides_is_face_card(state, card)

Namely, Blueprint "copies" all the callbacks of self.copied_joker by simply passing down all arguments to self.copied_joker's callbacks. But in the ignore_joker case, if we e.g. have Blueprint copying Hanging Chad,

  • On card score, we will call blueprint.on_card_scoring()
  • Blueprint calls blueprint.copied_joker.on_card_scoring() (where copied joker is Hanging Chad)
  • The copied callback adds blueprint.copied_joker to the ignore_jokers list and re-triggers state.compute_card_score()
  • Since Blueprint is not in the ignore_jokers list, we call blueprint.on_card_scoring()
  • Blueprint calls blueprint.copied_joker.on_card_scoring()
  • ...

for infinite recursion. As a remark, note that the joker order matters: any jokers to the left of the Blueprint will have their on_card_scoring() callbacks execute before Blueprint's, allowing them to actually happen before Blueprint triggers another recursion. Since there is no mechanism for reordering jokers, we need to be careful about the order we buy jokers in.

So how do we leverage this for high scoring? In the Blueprint + Hanging Chad case, we can essentially infinitely trigger any joker's .on_card_scoring() callback (until a stack overflow exception is thrown, which the game simply quietly catches and moves on to the next round):

    def compute_score(self):
        self.hand_chips, self.hand_mult = 0, 1
        # print("initial scoring:    ", self.hand_chips, self.hand_mult)
        try:  # fail safe on unimplemented jokers
            self.compute_hand_score()
            # print("hand_value scoring: ", self.hand_chips, self.hand_mult)
            self.compute_cards_score()
            # print("cards_value scoring:", self.hand_chips, self.hand_mult)
            self.compute_in_hand_cards_score()
            # print("in_hand_cards_value scoring:", self.hand_chips, self.hand_mult)
        except Exception as e:
            print(repr(e), file=stderr)

For .on_card_scoring(), the best joker to retrigger is Photograph, giving us x2 mult per loop:

from .joker_base import JokerClass, JokerRarity


class Photograph(JokerClass):
    description = "First played face card gives X2 Mult when scored"
    rarity = JokerRarity.COMMON
    price = 5

    def __init__(self):
        super().__init__()
        self.is_first_face = False

    def on_hand_scoring(self, state, ignore_jokers=None):
        self.is_first_face = True

    def on_card_scoring(self, state, i, card, ignore_jokers=None):
        if state.is_face_card(card):
            state.message.append(f"{self.name}: X2 Mult for first face card")
            state.hand_mult *= 2
            self.is_first_face = False

    def on_play(self, state):
        self.is_first_face = False

(since their Photograph implementation is bugged, and never checks self.is_first_face for whether to apply the x2 mult on subsequent face card scorings).

However, even with 3 Photographs (their shop deduplication is broken) + Blueprint + Hanging Chad, due to the maximum recursion depth of 1000 we can only get a score of ~e301.

Instead, we can pivot to another ignore_jokers joker: Mime, which retriggers state.compute_in_hand_cards_score().

from .joker_base import JokerClass, JokerRarity


class Mime(JokerClass):
    description = "Retrigger all card held in hand abilities"
    rarity = JokerRarity.UNCOMMON
    price = 5

    def on_in_hand_scoring(self, state, ignore_jokers=None):
        state.message.append(f"{self.name}: retrigger hand cards")
        if ignore_jokers is None:
            ignore_jokers = set()
        ignore_jokers.add(self)
        state.compute_in_hand_cards_score(ignore_jokers=ignore_jokers)
        ignore_jokers.discard(self)

Notably, .compute_in_hands_score() retriggers each card in the hand before recursing by triggering jokers, allowing us to get more than x2 mult per recursion:

    def compute_in_hand_cards_score(self, ignore_jokers=None):
        assert self.hand is not None
        assert self.selected is not None
        assert self.hand_chips is not None
        assert self.hand_mult is not None
        if ignore_jokers is None:
            ignore_jokers = set()
        for i, card in enumerate(self.hand):
            if card not in self.selected:
                self.compute_in_hand_card_score(
                    i, card, ignore_jokers=ignore_jokers)
        for joker in self.jokers:
            if joker not in ignore_jokers:
                joker.on_in_hand_scoring(self, ignore_jokers=ignore_jokers)

Thus, all we need to do is pair this with a Baron. We can see that with just 2 barons, we get up to ~x11 mult per loop with just 3 kings in hand:

from .joker_base import JokerClass, JokerRarity


class Baron(JokerClass):
    description = "Each King held in hand gives X1.5 Mult"
    rarity = JokerRarity.RARE
    price = 8

    def on_in_hand_card_scoring(self, state, i, card, ignore_jokers=None):
        # King has rank 13
        if card.rank == 13:
            state.message.append(f"{self.name}: X1.5 Mult for King")
            state.hand_mult *= 1.5
1.5^2     = 2.25       (K=1)
(1.5^2)^2 = 5.0625     (K=2)
(1.5^2)^3 = 11.390625  (K=3)

So the plan of attack is as follows:

  1. Play the first round randomly. (if we play 5 cards at a time, we're almost guaranteed to have enough money by the end of round)
  2. Reroll until we get the following jokers, in order: [Baron, Baron, Blueprint, Mime]
  3. On the next round, discard for 3 kings and play any hand; the infinite recursion should trigger, giving you inf score.
  4. Play out the rest of the antes until you win and get the flag.

and all thats left is scripting. For this challenge, though, even scripting is non-trivial and mildly annoying due to their game interface and PoW. Even funnier, due to other bugs in their implementation, the moment you try to select an Erosion in the shop the server immediately crashes; since you can't tell which jokers are which before attempting to select them, this is a completely random element that you just need to get lucky enough to avoid.

After some lengthy trial and error, we can create a script like so:

import subprocess

import pwn

# queue = ['Photograph', 'Photograph', 'Photograph', 'Blueprint', 'Hanging Chad']
queue = ['Baron', 'Baron', 'Blueprint', 'Mime']


def skip_shop():
    conn.recvuntil(b'\n $')
    money = conn.recvline()
    print(f'shop: ${money.decode().strip()}')
    conn.sendline(b'p')


def handle_shop():
    conn.recvuntil(b'\n $')
    money = conn.recvline()
    print(f'shop: ${money.decode().strip()}')

    # Query both jokers, reroll until we get all the jokers we want
    while True:
        b = query_shop_joker('1')
        query_shop_joker('2' if not b else '1')

        if len(queue) == 0:
            break
        conn.sendline(b'r')

        conn.recvuntil(b'\n $')
        money = int(conn.recvline())
        print(f'reroll: ${money}')

        if money < 100:
            break

    conn.recvuntil(b'\n>')
    conn.sendline(b'p')


def query_shop_joker(index: str):
    if len(queue) == 0:
        return False

    conn.recvuntil(b'\n>')
    conn.sendline(index.encode())
    conn.recvuntil(f'{index}: '.encode())

    line = conn.recvline().decode()
    name = line.partition(':')[0]

    print('->', name)

    want = queue[0]

    if want == name:
        queue.pop(0)
        conn.sendline(b'b')
        print(f'purchased {name}')
        return True
    else:
        # Deselect the joker
        conn.sendline(index.encode())
        return False


def play_game():
    for _ in range(5):
        conn.recvuntil(b'\n>')
        conn.sendline(b'a 1 2 3 4 5')
        conn.recvuntil(b'\n>')
        conn.sendline(b'p')


def play_game_kings():
    for _ in range(5):
        hand = conn.recvuntil(b'\n 1').decode().split('\n')[-2]
        kings = hand.count('๐Ÿ‚ฎ') + hand.count('๐Ÿ‚พ') + hand.count('๐ŸƒŽ') + hand.count('๐Ÿƒž')
        aces = hand.count('๐Ÿ‚ก') + hand.count('๐Ÿ‚ฑ') + hand.count('๐Ÿƒ') + hand.count('๐Ÿƒ‘')
        conn.recvuntil(b'\n>')

        print(hand, kings, aces)
        if kings >= 3:
            break

        # Find the indices to discard; we probably want to discard on the right first
        # since we play cards from the left.
        remove = list(range(1, 9))[-aces:] + list(range(1, 9))[:8 - kings - aces]
        remove = remove[:5]

        conn.sendline(f'a {" ".join(map(str, remove))}'.encode())
        conn.recvuntil(b'\n>')
        conn.sendline(b'd')
    else:
        print('not able to discard :(')

    for _ in range(5):
        conn.sendline(b'a 1')
        conn.recvuntil(b'\n>').decode()
        conn.sendline(b'p')


conn = pwn.remote('precipice.challs.m0lecon.it', 14615)

# Do PoW :)
cmd = conn.recvuntil(b'Result: ').decode().split('\n')[3]
res = subprocess.run(cmd, capture_output=True, shell=True).stdout.decode()
conn.sendline(res.encode())

skip_shop()

while len(queue) > 0:
    play_game()
    handle_shop()

while True:
    play_game_kings()

    if conn.recvuntil(b'GG', timeout=0.5) != b'':
        print(conn.recvall().decode())
        break

    skip_shop()

which we can run repeatedly (praying it never hits an Erosion)

reroll: $226
-> Riff Raff
-> Gros Michel
reroll: $221
-> Gros Michel
-> Baron
reroll: $216
-> Stone Joker
Traceback (most recent call last):
  File "/mnt/c/Users/kevin/Downloads/ctf/balatro.py", line 112, in <module>
    handle_shop()
  File "/mnt/c/Users/kevin/Downloads/ctf/balatro.py", line 23, in handle_shop
    query_shop_joker('2' if not b else '1')
  File "/mnt/c/Users/kevin/Downloads/ctf/balatro.py", line 46, in query_shop_joker
    conn.recvuntil(f'{index}: '.encode())
  File "/home/ky28059/.local/lib/python3.12/site-packages/pwnlib/tubes/tube.py", line 381, in recvuntil
    res = self.recv(timeout=self.timeout)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ky28059/.local/lib/python3.12/site-packages/pwnlib/tubes/tube.py", line 146, in recv
    return self._recv(numb, timeout) or b''
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ky28059/.local/lib/python3.12/site-packages/pwnlib/tubes/tube.py", line 216, in _recv
    if not self.buffer and not self._fillbuffer(timeout):
                               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ky28059/.local/lib/python3.12/site-packages/pwnlib/tubes/tube.py", line 195, in _fillbuffer
    data = self.recv_raw(self.buffer.get_fill_size())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ky28059/.local/lib/python3.12/site-packages/pwnlib/tubes/sock.py", line 56, in recv_raw
    raise EOFError
EOFError
[*] Closed connection to precipice.challs.m0lecon.it port 14615

until finally, we win:

[+] Opening connection to precipice.challs.m0lecon.it on port 14615: Done
shop: $0.0
shop: $366
-> Brainstorm
-> Burnt Joker
reroll: $366
-> Dusk
-> Hanging Chad
reroll: $361
-> Cavendish
-> Blueprint
reroll: $356
-> Flower Pot
-> Acrobat
reroll: $351
-> Hiker
-> Midas Mask
reroll: $346
-> Certificate
-> Ancient Joker
reroll: $341
-> Banner
-> Sock And Buskin
reroll: $336
-> Ramen
-> Brainstorm
reroll: $331
-> Misprint
-> Banner
reroll: $326
-> Scary Face
-> Sock And Buskin
reroll: $321
-> Vampire
-> Joker
reroll: $316
-> Abstract Joker
-> Midas Mask
reroll: $311
-> Abstract Joker
-> Ramen
reroll: $306
-> Mime
-> Smiley Face
reroll: $301
-> Baron
purchased Baron
-> Turtle Bean
reroll: $288
-> Drunkard
-> Hologram
reroll: $283
-> Baron
purchased Baron
-> Burnt Joker
reroll: $270
-> Certificate
-> Sock And Buskin
reroll: $265
-> Brainstorm
-> Joker
reroll: $260
-> Stone Joker
-> Joker Stencil
reroll: $255
-> Hiker
-> Hiker
reroll: $250
-> Joker Stencil
-> Hiker
reroll: $245
-> Loyalty Card
-> Golden Ticket
reroll: $240
-> Gros Michel
-> Certificate
reroll: $235
-> Blueprint
purchased Blueprint
-> Midas Mask
reroll: $220
-> Drunkard
-> Gros Michel
reroll: $215
-> Blue Joker
-> Ramen
reroll: $210
-> Hologram
-> Dusk
reroll: $205
-> Shoot The Moon
-> Gros Michel
reroll: $200
-> Blue Joker
-> Abstract Joker
reroll: $195
-> Raised Fist
-> Loyalty Card
reroll: $190
-> Baron
-> Dusk
reroll: $185
-> Sock And Buskin
-> Mime
purchased Mime
 ๐Ÿ‚ข ๐Ÿƒˆ ๐Ÿ‚น ๐Ÿƒ‹ ๐Ÿ‚พ ๐Ÿƒ ๐Ÿƒ‘ ๐Ÿ‚ก 1 3
 ๐Ÿ‚ด ๐Ÿ‚ต ๐Ÿ‚ท ๐Ÿ‚ง ๐Ÿ‚น ๐Ÿƒ‹ ๐Ÿ‚ฝ ๐Ÿ‚พ 1 0
 ๐Ÿƒ„ ๐Ÿ‚ค ๐Ÿƒ— ๐Ÿ‚ฉ ๐Ÿƒ‹ ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿƒž 2 0
 ๐Ÿ‚ณ ๐Ÿƒ• ๐Ÿƒ– ๐Ÿƒ‡ ๐Ÿ‚ป ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿƒž 2 0
 ๐Ÿƒ‚ ๐Ÿƒ” ๐Ÿƒ‰ ๐Ÿ‚ช ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿƒž ๐Ÿ‚ฑ 2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚น ๐Ÿƒ‰ ๐Ÿ‚ฉ ๐Ÿ‚ป ๐Ÿ‚ฝ ๐Ÿƒž ๐Ÿ‚ฑ 1 1
 ๐Ÿƒ… ๐Ÿƒ— ๐Ÿ‚ซ ๐Ÿ‚ฝ ๐Ÿ‚ญ ๐Ÿƒž ๐Ÿ‚ฑ   1 1
 ๐Ÿ‚ณ ๐Ÿƒ„ ๐Ÿƒ‡ ๐Ÿƒ™ ๐ŸƒŠ ๐Ÿ‚ญ ๐Ÿƒž   1 0
   ๐Ÿƒ” ๐Ÿƒ• ๐ŸƒŠ ๐Ÿƒš ๐Ÿƒ‹ ๐Ÿ‚ญ ๐Ÿƒž 1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ• ๐Ÿ‚จ ๐Ÿ‚น ๐Ÿƒ‰ ๐Ÿ‚ป ๐Ÿƒ‹ ๐Ÿƒ 0 0
   ๐Ÿƒ– ๐Ÿ‚ป ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ 1 1
 ๐Ÿƒ” ๐Ÿ‚ถ ๐Ÿƒ‡ ๐Ÿƒˆ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ   1 1
 ๐Ÿƒ‚ ๐Ÿ‚ฅ ๐Ÿƒ— ๐Ÿƒ˜ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ   1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ข ๐Ÿ‚ฃ ๐Ÿƒ„ ๐Ÿƒ• ๐Ÿ‚ถ ๐Ÿƒ™ ๐Ÿƒ‘ 0 1
 ๐Ÿ‚ด ๐Ÿ‚ถ ๐Ÿƒ† ๐Ÿƒ‡ ๐Ÿƒ™ ๐Ÿƒ› ๐Ÿƒ‘   0 1
 ๐Ÿƒ“ ๐Ÿ‚ต ๐Ÿƒ™ ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿƒ ๐Ÿƒž   1 0
   ๐Ÿ‚ง ๐Ÿƒ› ๐Ÿ‚ซ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž 2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿ‚ท ๐Ÿƒˆ ๐Ÿ‚ช ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ‘ 1 1
 ๐Ÿ‚ต ๐Ÿ‚บ ๐Ÿ‚ซ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   2 1
 ๐Ÿ‚ข ๐Ÿƒ˜ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   2 1
 ๐Ÿ‚ค ๐Ÿƒ– ๐Ÿ‚ง ๐Ÿƒ™ ๐Ÿ‚ป ๐Ÿ‚พ ๐Ÿ‚ฎ   2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ‡ ๐Ÿ‚จ ๐ŸƒŠ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒž 2 0
   ๐Ÿ‚ฆ ๐Ÿ‚ธ ๐Ÿ‚ป ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒž ๐Ÿƒ‘ 2 1
 ๐Ÿƒ‚ ๐Ÿ‚ฅ ๐Ÿƒ† ๐Ÿ‚ง ๐Ÿ‚น ๐ŸƒŽ ๐Ÿƒž   2 0
   ๐Ÿ‚ถ ๐Ÿ‚ท ๐Ÿ‚น ๐Ÿƒš ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ก 2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฃ ๐Ÿƒ• ๐Ÿ‚ฅ ๐Ÿƒ† ๐Ÿ‚ฆ ๐Ÿƒš ๐Ÿ‚ฎ 1 0
   ๐Ÿ‚ง ๐Ÿƒš ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿƒž ๐Ÿ‚ฎ ๐Ÿ‚ก 2 1
 ๐Ÿ‚ท ๐Ÿƒˆ ๐Ÿƒ˜ ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿƒž ๐Ÿ‚ฎ   2 0
   ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ฎ ๐Ÿƒ‘ 3 1
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ‚ ๐Ÿ‚ข ๐Ÿƒƒ ๐Ÿ‚ต ๐Ÿ‚ฅ ๐Ÿƒˆ ๐Ÿ‚ฉ 0 0
   ๐Ÿ‚ฅ ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿƒš ๐Ÿƒ ๐Ÿƒž ๐Ÿƒ‘ 1 1
 ๐Ÿ‚ด ๐Ÿƒ” ๐Ÿ‚ฆ ๐Ÿƒ— ๐Ÿƒ˜ ๐Ÿƒ ๐Ÿƒž   1 0
   ๐Ÿƒ† ๐Ÿƒ˜ ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿƒž 1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ข ๐Ÿƒ… ๐Ÿƒ† ๐Ÿƒˆ ๐Ÿ‚น ๐Ÿ‚ฉ ๐Ÿ‚ฝ 0 0
   ๐Ÿƒ„ ๐Ÿƒ” ๐Ÿ‚ฆ ๐Ÿ‚น ๐Ÿ‚ฉ ๐Ÿ‚ฝ ๐Ÿƒ 0 0
   ๐Ÿƒ‡ ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ‘ 1 1
 ๐Ÿƒ’ ๐Ÿ‚ฅ ๐Ÿ‚ง ๐ŸƒŠ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿ‚ฎ   2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ณ ๐Ÿƒ„ ๐Ÿ‚จ ๐ŸƒŠ ๐Ÿƒš ๐Ÿ‚ช ๐ŸƒŽ 1 0
   ๐Ÿƒ‡ ๐Ÿƒ— ๐Ÿƒš ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ซ ๐ŸƒŽ 1 0
   ๐Ÿƒ” ๐Ÿ‚ง ๐Ÿƒˆ ๐Ÿƒ› ๐Ÿ‚ซ ๐Ÿ‚ฝ ๐ŸƒŽ 1 0
   ๐Ÿƒ• ๐Ÿ‚ฅ ๐Ÿ‚ซ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ 1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ— ๐Ÿ‚ธ ๐Ÿƒ‰ ๐Ÿƒ ๐ŸƒŽ ๐Ÿ‚ฎ ๐Ÿƒ 2 1
 ๐Ÿƒ” ๐Ÿ‚ฆ ๐Ÿ‚ซ ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ฎ ๐Ÿƒ   3 1
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฆ ๐Ÿƒ‡ ๐Ÿƒ‰ ๐Ÿ‚ป ๐Ÿƒ‹ ๐Ÿ‚ฑ ๐Ÿƒ‘ 0 2
 ๐Ÿƒ’ ๐Ÿƒƒ ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿ‚พ   ๐Ÿƒ‘ 1 1
 ๐Ÿ‚ฒ ๐Ÿ‚ณ ๐Ÿ‚ท ๐Ÿ‚จ ๐Ÿ‚บ ๐Ÿƒ› ๐Ÿ‚ฝ   0 0
   ๐Ÿƒ” ๐Ÿƒ— ๐Ÿ‚ง ๐Ÿ‚บ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ฝ 0 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ‡ ๐Ÿ‚ธ ๐Ÿƒš ๐Ÿ‚ช ๐Ÿƒ ๐Ÿƒž ๐Ÿƒ 1 1
 ๐Ÿƒ… ๐Ÿ‚ง ๐ŸƒŠ ๐Ÿƒ› ๐Ÿƒ ๐Ÿƒž ๐Ÿ‚ฑ   1 1
 ๐Ÿ‚ฒ ๐Ÿ‚ฃ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿƒž ๐Ÿ‚ฑ   1 1
 ๐Ÿƒ’ ๐Ÿ‚ฅ ๐Ÿ‚ถ ๐Ÿƒ– ๐Ÿ‚ญ ๐Ÿƒž ๐Ÿ‚ฑ   1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฅ ๐Ÿƒ† ๐Ÿ‚ท ๐Ÿƒ‡ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿƒ‘ 0 1
 ๐Ÿ‚ด ๐Ÿƒ– ๐Ÿƒ˜ ๐Ÿƒ™ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ฝ   0 0
   ๐Ÿ‚ง ๐Ÿ‚บ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿ‚ฑ ๐Ÿ‚ก 0 2
 ๐Ÿƒƒ ๐Ÿƒ„ ๐Ÿƒ• ๐Ÿƒ‹ ๐Ÿ‚ฝ ๐Ÿƒž   ๐Ÿ‚ก 1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฃ ๐Ÿƒ„ ๐Ÿƒ” ๐Ÿƒ† ๐Ÿƒ‡ ๐Ÿ‚ง ๐Ÿƒ 0 0
   ๐Ÿƒ‡ ๐Ÿ‚ง ๐Ÿ‚ธ ๐Ÿ‚จ ๐Ÿ‚บ ๐Ÿƒ‹ ๐Ÿƒ 0 0
   ๐Ÿ‚ต ๐Ÿ‚ฆ ๐Ÿ‚บ ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒž 2 0
   ๐Ÿƒ™ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒž ๐Ÿ‚ฎ 3 0
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ— ๐Ÿ‚ธ ๐Ÿƒˆ ๐Ÿƒ‰ ๐Ÿƒ‹ ๐Ÿ‚ญ ๐ŸƒŽ 1 0
   ๐Ÿƒ“ ๐Ÿƒ• ๐Ÿ‚จ ๐Ÿƒ‹ ๐Ÿ‚ญ ๐Ÿ‚พ ๐ŸƒŽ 2 0
   ๐Ÿ‚ถ ๐Ÿ‚น ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿƒ 2 1
 ๐Ÿ‚ณ ๐Ÿƒ… ๐Ÿƒš ๐Ÿƒ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿƒ   2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ’ ๐Ÿ‚ฃ ๐Ÿƒ… ๐Ÿƒ• ๐Ÿ‚ฆ ๐Ÿƒ‰ ๐Ÿ‚ฑ 0 1
 ๐Ÿ‚ด ๐Ÿ‚ถ ๐Ÿ‚ฆ ๐Ÿƒ‰ ๐ŸƒŠ ๐Ÿƒ ๐Ÿƒ   0 0
   ๐Ÿƒ‡ ๐Ÿ‚ธ ๐Ÿ‚บ ๐ŸƒŠ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ก 0 1
 ๐Ÿ‚ข ๐Ÿƒ– ๐Ÿƒ‹ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ฎ   1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ“ ๐Ÿ‚ต ๐Ÿ‚ท ๐Ÿƒˆ ๐Ÿ‚ป ๐Ÿƒ‹ ๐ŸƒŽ 1 0
   ๐Ÿƒ† ๐Ÿ‚จ ๐Ÿ‚ป ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿƒ ๐ŸƒŽ 1 0
   ๐Ÿ‚บ ๐Ÿƒš ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ 1 0
   ๐Ÿƒ” ๐Ÿƒ— ๐Ÿ‚ซ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒ 1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ณ ๐Ÿƒ” ๐Ÿƒ• ๐Ÿƒ— ๐Ÿ‚น ๐Ÿ‚ฎ ๐Ÿ‚ก 1 1
 ๐Ÿƒ“ ๐Ÿƒ… ๐Ÿƒ– ๐Ÿ‚ท ๐Ÿ‚น ๐Ÿ‚ฎ ๐Ÿƒ‘   1 1
 ๐Ÿƒ† ๐Ÿƒ‡ ๐Ÿ‚ง ๐Ÿ‚น ๐Ÿ‚ซ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   1 1
 ๐Ÿƒ‰ ๐Ÿƒš ๐Ÿ‚ป ๐Ÿƒ› ๐Ÿ‚ซ ๐ŸƒŽ ๐Ÿ‚ฎ   2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฆ ๐Ÿƒ‡ ๐Ÿ‚ง ๐Ÿƒ˜ ๐Ÿƒ ๐Ÿƒž ๐Ÿ‚ก 1 1
 ๐Ÿƒ“ ๐Ÿƒ• ๐Ÿ‚ธ ๐Ÿƒˆ ๐Ÿƒ ๐ŸƒŽ ๐Ÿƒž   2 0
   ๐Ÿƒ‰ ๐Ÿƒ‹ ๐Ÿƒ ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ฑ ๐Ÿƒ‘ 2 2
 ๐Ÿ‚ฒ ๐Ÿ‚ข ๐Ÿ‚น ๐Ÿ‚ช ๐Ÿ‚ญ ๐Ÿƒž   ๐Ÿƒ‘ 1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚จ ๐Ÿƒ‰ ๐ŸƒŠ ๐Ÿ‚ช ๐Ÿ‚พ ๐Ÿƒž ๐Ÿ‚ฑ 2 1
 ๐Ÿƒ„ ๐Ÿƒ” ๐Ÿ‚ค ๐Ÿ‚ง ๐Ÿ‚ธ ๐Ÿ‚พ ๐Ÿƒž   2 0
   ๐Ÿƒ• ๐Ÿ‚ท ๐Ÿ‚ธ ๐Ÿƒ› ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž 2 0
   ๐Ÿ‚ข ๐Ÿƒƒ ๐Ÿ‚ฃ ๐Ÿƒ™ ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž 2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ’ ๐Ÿƒ“ ๐Ÿ‚ด ๐Ÿƒ‡ ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿƒ 0 0
   ๐Ÿ‚ท ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿƒ ๐ŸƒŽ ๐Ÿ‚ฑ 1 1
 ๐Ÿ‚ฅ ๐Ÿ‚จ ๐Ÿ‚ซ ๐Ÿ‚ฝ ๐Ÿƒ ๐ŸƒŽ ๐Ÿ‚ฑ   1 1
 ๐Ÿƒ– ๐Ÿ‚ง ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿ‚ฑ   2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฃ ๐Ÿƒ” ๐Ÿ‚ค ๐Ÿ‚ถ ๐Ÿ‚ธ ๐Ÿƒ‹ ๐ŸƒŽ 1 0
   ๐Ÿƒ… ๐Ÿ‚ธ ๐Ÿ‚ฉ ๐Ÿƒ‹ ๐Ÿ‚ซ ๐Ÿ‚พ ๐ŸƒŽ 2 0
   ๐Ÿ‚ข ๐Ÿ‚น ๐ŸƒŠ ๐Ÿ‚ซ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿ‚ฎ 3 0
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ข ๐Ÿ‚ค ๐Ÿ‚ถ ๐Ÿƒ† ๐Ÿ‚ท ๐Ÿƒš ๐Ÿ‚ญ 0 0
   ๐Ÿ‚ท ๐Ÿ‚ธ ๐Ÿƒ˜ ๐Ÿƒš ๐Ÿ‚ญ ๐Ÿƒ‘ ๐Ÿ‚ก 0 2
 ๐Ÿ‚ต ๐Ÿ‚ฆ ๐Ÿ‚ง ๐Ÿ‚ฝ ๐Ÿ‚ญ ๐Ÿƒ   ๐Ÿ‚ก 0 2
 ๐Ÿ‚ฃ ๐Ÿƒ‰ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ญ   ๐Ÿƒ 0 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ฃ ๐Ÿƒ„ ๐Ÿ‚ต ๐Ÿƒ† ๐Ÿ‚ธ ๐Ÿ‚ช ๐Ÿ‚ญ 0 0
   ๐Ÿ‚ณ ๐Ÿ‚ค ๐Ÿƒ… ๐Ÿ‚ธ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ญ 0 0
   ๐Ÿƒ‡ ๐Ÿƒ— ๐Ÿƒˆ ๐Ÿ‚ช ๐Ÿƒ› ๐Ÿ‚ญ ๐ŸƒŽ 1 0
   ๐Ÿ‚ถ ๐Ÿ‚ง ๐Ÿƒ‹ ๐Ÿƒ› ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿ‚ก 1 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿƒ… ๐Ÿ‚ธ ๐Ÿƒ˜ ๐Ÿƒ™ ๐Ÿƒš ๐Ÿƒ› 0 0
   ๐Ÿ‚ง ๐Ÿƒ™ ๐Ÿƒš ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿƒž 2 0
   ๐Ÿ‚น ๐Ÿ‚ฝ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ฎ ๐Ÿ‚ฑ 4 1
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ” ๐Ÿ‚ต ๐Ÿ‚ป ๐Ÿƒ› ๐Ÿƒ ๐Ÿ‚พ ๐Ÿƒ 1 1
 ๐Ÿƒ’ ๐Ÿ‚ข ๐Ÿ‚ถ ๐Ÿ‚ง ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿ‚พ   1 0
   ๐Ÿƒ‰ ๐Ÿƒ™ ๐Ÿ‚บ ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ 1 0
   ๐Ÿƒ„ ๐Ÿƒ– ๐Ÿ‚ฆ ๐Ÿ‚จ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ 1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿ‚ต ๐Ÿƒ… ๐Ÿ‚ธ ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿƒ‹ 0 0
   ๐Ÿƒ“ ๐Ÿ‚ฃ ๐Ÿƒˆ ๐Ÿ‚ฉ ๐ŸƒŠ ๐Ÿ‚ช ๐Ÿƒ‹ 0 0
   ๐Ÿƒ• ๐Ÿƒ† ๐ŸƒŠ ๐Ÿ‚ช ๐Ÿƒ‹ ๐Ÿ‚ญ ๐Ÿ‚พ 1 0
   ๐Ÿ‚ถ ๐Ÿ‚ท ๐Ÿƒ™ ๐Ÿƒ‹ ๐Ÿ‚ญ ๐Ÿ‚พ ๐ŸƒŽ 2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ข ๐Ÿƒ” ๐Ÿƒ• ๐Ÿ‚ง ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿ‚ซ 0 0
   ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿ‚ซ ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿƒž ๐Ÿ‚ฎ 3 0
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿƒ… ๐Ÿ‚ฅ ๐Ÿ‚ฆ ๐Ÿ‚ท ๐Ÿ‚จ ๐Ÿƒ 0 0
   ๐Ÿ‚ท ๐Ÿ‚จ ๐Ÿƒ‰ ๐Ÿƒ™ ๐Ÿƒ ๐Ÿƒ ๐ŸƒŽ 1 0
   ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿƒ‘ ๐Ÿ‚ก 2 2
 ๐Ÿƒ” ๐Ÿ‚ต ๐Ÿ‚ถ ๐Ÿƒ– ๐ŸƒŽ ๐Ÿ‚ฎ   ๐Ÿ‚ก 2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ค ๐Ÿ‚ฅ ๐Ÿ‚ถ ๐Ÿ‚ท ๐Ÿƒ‡ ๐Ÿƒ‰ ๐Ÿƒ 0 1
 ๐Ÿƒ‡ ๐Ÿƒ— ๐Ÿ‚ธ ๐Ÿ‚น ๐Ÿƒ‰ ๐Ÿ‚ฉ ๐Ÿƒš   0 0
   ๐Ÿƒ” ๐Ÿƒ… ๐Ÿƒ– ๐Ÿƒ‰ ๐Ÿ‚ฉ ๐Ÿƒš ๐ŸƒŽ 1 0
   ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿƒš ๐Ÿ‚ช ๐Ÿƒ‹ ๐Ÿƒ ๐ŸƒŽ 1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ… ๐Ÿƒ† ๐Ÿƒ– ๐Ÿƒˆ ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿ‚ฎ 1 0
   ๐Ÿ‚ค ๐Ÿƒ— ๐Ÿ‚ง ๐Ÿ‚ช ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿ‚ฎ 1 0
   ๐Ÿƒ˜ ๐Ÿƒ™ ๐Ÿ‚ป ๐Ÿƒ‹ ๐Ÿƒ ๐Ÿƒž ๐Ÿ‚ฎ 2 0
   ๐Ÿ‚ท ๐Ÿƒ‡ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒž ๐Ÿ‚ฎ 3 0
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ” ๐Ÿƒ• ๐Ÿƒ— ๐Ÿƒˆ ๐Ÿ‚น ๐Ÿ‚ซ ๐Ÿƒ 0 0
   ๐Ÿ‚น ๐ŸƒŠ ๐Ÿ‚ป ๐Ÿ‚ซ ๐Ÿƒ ๐Ÿƒ ๐ŸƒŽ 1 0
   ๐Ÿ‚ข ๐Ÿƒ“ ๐Ÿƒ– ๐Ÿƒ‡ ๐Ÿƒ ๐Ÿƒ ๐ŸƒŽ 1 0
   ๐Ÿ‚ธ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿƒ ๐Ÿ‚ญ ๐ŸƒŽ ๐Ÿƒž 2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿ‚ท ๐Ÿƒ˜ ๐Ÿ‚ฝ ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿ‚ฑ 1 1
 ๐Ÿƒ… ๐Ÿƒ‡ ๐Ÿƒ— ๐Ÿƒ‰ ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž   2 0
   ๐Ÿ‚ต ๐Ÿ‚ฅ ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž 2 0
   ๐Ÿƒ• ๐Ÿ‚จ ๐Ÿƒ› ๐Ÿ‚ญ ๐Ÿ‚พ ๐Ÿƒž ๐Ÿ‚ก 2 1
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ” ๐Ÿƒ™ ๐Ÿƒš ๐Ÿƒ ๐Ÿ‚พ ๐Ÿ‚ฎ ๐Ÿƒ 2 1
 ๐Ÿ‚ง ๐Ÿƒ˜ ๐Ÿ‚น ๐ŸƒŠ ๐Ÿ‚พ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   2 1
 ๐Ÿƒ• ๐Ÿƒ† ๐Ÿ‚ฝ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   3 1
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ– ๐Ÿƒ˜ ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿƒ› ๐Ÿ‚ซ ๐ŸƒŽ 1 0
   ๐Ÿƒ† ๐Ÿ‚ธ ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿƒ› ๐Ÿ‚ซ ๐ŸƒŽ 1 0
   ๐Ÿƒ“ ๐Ÿ‚บ ๐Ÿƒ› ๐Ÿ‚ซ ๐Ÿ‚พ ๐ŸƒŽ ๐Ÿ‚ฎ 3 0
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ„ ๐Ÿƒ” ๐Ÿƒ˜ ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿ‚ซ ๐Ÿ‚ฎ 1 0
   ๐Ÿ‚ฃ ๐Ÿ‚ท ๐Ÿ‚ป ๐Ÿ‚ซ ๐Ÿƒ ๐Ÿ‚ฎ ๐Ÿ‚ฑ 1 1
 ๐Ÿƒ“ ๐Ÿƒ– ๐Ÿ‚ธ ๐ŸƒŠ ๐Ÿƒ ๐Ÿ‚ฎ ๐Ÿ‚ฑ   1 1
 ๐Ÿ‚ฒ ๐Ÿƒ— ๐Ÿ‚จ ๐Ÿƒ™ ๐Ÿƒ ๐Ÿƒž ๐Ÿ‚ฎ   2 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿ‚ด ๐Ÿƒ” ๐Ÿ‚ธ ๐Ÿƒˆ ๐Ÿƒ™ ๐Ÿ‚ญ ๐Ÿƒž 1 0
   ๐Ÿ‚ค ๐Ÿ‚ฅ ๐Ÿƒ™ ๐Ÿ‚บ ๐Ÿ‚ป ๐Ÿ‚ญ ๐Ÿƒž 1 0
   ๐Ÿ‚จ ๐Ÿƒš ๐Ÿ‚ป ๐Ÿƒ ๐Ÿ‚ญ ๐Ÿƒž ๐Ÿ‚ฑ 1 1
 ๐Ÿ‚ฒ ๐Ÿƒ‚ ๐Ÿƒ“ ๐Ÿƒ– ๐Ÿ‚น ๐Ÿ‚ญ ๐Ÿƒž   1 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒ– ๐Ÿƒ‡ ๐Ÿƒˆ ๐Ÿ‚ฉ ๐Ÿ‚ช ๐Ÿ‚ฑ ๐Ÿƒ‘ 0 2
 ๐Ÿƒ’ ๐Ÿƒƒ ๐Ÿ‚ฃ ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿ‚ญ   ๐Ÿƒ‘ 0 1
 ๐Ÿ‚ฒ ๐Ÿ‚ต ๐Ÿ‚ฅ ๐Ÿƒ— ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿ‚ญ   0 0
   ๐Ÿ‚ถ ๐Ÿƒ‰ ๐Ÿ‚บ ๐ŸƒŠ ๐Ÿ‚ช ๐Ÿ‚ป ๐Ÿ‚ญ 0 0
not able to discard :(
shop: $inf
 ๐Ÿƒ ๐Ÿƒ 0 0
   ๐Ÿƒƒ ๐Ÿ‚ด ๐Ÿ‚ถ ๐Ÿƒ™ ๐Ÿƒš ๐Ÿ‚ฝ ๐Ÿ‚พ 1 0
   ๐Ÿƒ” ๐Ÿƒ‰ ๐Ÿƒš ๐Ÿƒ‹ ๐Ÿ‚ฝ ๐Ÿ‚พ ๐Ÿ‚ฑ 1 1
 ๐Ÿƒ’ ๐Ÿƒ… ๐Ÿ‚ฆ ๐Ÿƒ› ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚พ   1 0
   ๐Ÿ‚ต ๐Ÿ‚ธ ๐Ÿ‚จ ๐Ÿ‚บ ๐Ÿ‚ฝ ๐Ÿƒ ๐Ÿ‚พ 1 0
not able to discard :(
[+] Receiving all data: Done (116B)
[*] Closed connection to precipice.challs.m0lecon.it port 14615

 ptm{7urns_0u7_7h3r3_w@s_p@p3r0nis_m0n3y_p00l_@7_7h3_b0770m_0f_7h3_pr3cipic3}
\x1b[2J
 ~$inf
 $3.308591879916669e+233
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment