Exemple #1
0
class SixtyNine(NumberCard):
    CARD_FREQUENCY = CardFrequency(1.2)
    CARD_TYPE = "69"
    EFFECT_DESCRIPTION = "A surprise ;)"

    def play_card(self, player):
        # only send "nice" sound effect if this is the bottom card in the pile
        is_bottom = True
        n_cards = 0
        for card in self.game.planning_pile:
            if not isinstance(card, SixtyNine):
                if not isinstance(card, CopyCat):
                    continue
                if not isinstance(card.copied, SixtyNine):
                    continue

            if card.get_id() == self.get_id() and is_bottom is True:
                n_cards += 1
            elif n_cards > 0:
                n_cards += 1

            is_bottom = False

        # play sound effect if more than 1 69 card
        if n_cards > 0:
            if n_cards < 15:
                r = random.randrange(1, 5)
                file = "/static/sounds/nice" + str(r) + ".mp3"
            else:  # f****d sound effect for >=15 69 cards played at once
                r = random.randrange(1, 4)
                file = "/static/sounds/nice_fucked" + str(r) + ".mp3"

            player.refresh_card_play_animation()
            json_to_send = {"type": "sound", "sound": file}
            self.game.send_to_all_players("animate", json_to_send)
Exemple #2
0
class NumberCard(AbstractCard):
    CARD_FREQUENCY = CardFrequency(2)

    def prepare_card(self, player, allow_cancel):
        if len(self.game.planning_pile) == 0:
            return True
        if hasattr(self.game.planning_pile[0], 'still_needs'):
            self.game.planning_pile[0].still_needs -= int(self.get_type())
        return True

    def undo_prepare_card(self, player):
        if len(self.game.planning_pile) == 0:
            return
        if hasattr(self.game.planning_pile[0], 'still_needs'):
            self.game.planning_pile[0].still_needs += int(self.get_type())
Exemple #3
0
class PurpleOne(NumberCard):
    NAME = "Purple One"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "1"
    CARD_IMAGE_URL = 'cards/1_purple.png'
Exemple #4
0
class YellowZero(NumberCard):
    NAME = "Yellow Zero"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "yellow"
    CARD_TYPE = "0"
    CARD_IMAGE_URL = 'cards/0_yellow.png'
Exemple #5
0
class RedZero(NumberCard):
    NAME = "Red Zero"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "red"
    CARD_TYPE = "0"
    CARD_IMAGE_URL = 'cards/0_red.png'
Exemple #6
0
class PurpleSixtyNine(SixtyNine):
    NAME = "Purple Sixty Nine"
    CARD_FREQUENCY = CardFrequency(0.6)
    CARD_COLOUR = "purple"
    CARD_IMAGE_URL = 'cards/69_purple.png'
Exemple #7
0
class PurpleZero(NumberCard):
    NAME = "Purple Zero"
    CARD_FREQUENCY = CardFrequency(0.5)
    CARD_COLOUR = "purple"
    CARD_TYPE = "0"
    CARD_IMAGE_URL = 'cards/0_purple.png'
Exemple #8
0
class PurpleEight(NumberCard):
    NAME = "Purple Eight"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "8"
    CARD_IMAGE_URL = 'cards/8_purple.png'
Exemple #9
0
class PurpleSeven(NumberCard):
    NAME = "Purple Seven"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "7"
    CARD_IMAGE_URL = 'cards/7_purple.png'
Exemple #10
0
class GreenZero(NumberCard):
    NAME = "Green Zero"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "green"
    CARD_TYPE = "0"
    CARD_IMAGE_URL = 'cards/0_green.png'
Exemple #11
0
class PurpleSix(NumberCard):
    NAME = "Purple Six"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "6"
    CARD_IMAGE_URL = 'cards/6_purple.png'
Exemple #12
0
class BlueZero(NumberCard):
    NAME = "Blue Zero"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "blue"
    CARD_TYPE = "0"
    CARD_IMAGE_URL = 'cards/0_blue.png'
Exemple #13
0
class PurpleFour(NumberCard):
    NAME = "Purple Four"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "4"
    CARD_IMAGE_URL = 'cards/4_purple.png'
Exemple #14
0
class PurpleTwo(NumberCard):
    NAME = "Purple Two"
    CARD_FREQUENCY = CardFrequency(1)
    CARD_COLOUR = "purple"
    CARD_TYPE = "2"
    CARD_IMAGE_URL = 'cards/2_purple.png'
Exemple #15
0
class AbstractCard:
    CARD_IMAGE_URL = 'cards/generic.png'
    COMPATIBILITY_DESCRIPTION = None  # generate this using get_compatibility_description()
    EFFECT_DESCRIPTION = 'No effects.'  # default description of the cards effects
    CARD_FREQUENCY = CardFrequency(0)
    NAME = "Abstract card"
    CARD_COLOUR = "Abstract"
    CARD_TYPE = "Abstract"
    ADDITIONAL_URLS = [
    ]  # if any card additional urls need to be loaded, add these here
    CAN_BE_ON_PICKUP = False
    # Used for generating compatibility description, set to False if there's only 1 colour of this type.
    MULTI_COLOURED = True

    def __init__(self, game):
        self.game = game
        self.id = self._make_id()

    def ready_to_play(self):
        """
        Can the player finish there turn
        :return: returns (True, None) if they can, returns (False, "reason") if they cant
        """
        return True, None

    def prepare_card(self, player, allow_cancel):
        """
        Prepares the card in the planning pile
        :return: returns if the card should be played (False is usually if you press a cancel button)
        """
        return True

    def undo_prepare_card(self, player):
        pass

    def play_card(self, player):
        pass

    def get_play_with(self, player):
        pass

    def is_compatible_with(self, player, card):
        """
        Can these 2 cards be played together
        :param card:
        :param player:
        :return: True or False
        """
        if card.get_type() == self.get_type():
            return True
        if card.get_colour() == self.get_colour():
            return True
        if card.get_colour() == "colour swapper":
            return True

        # white cards can be placed on anything that isn't black
        if self.get_colour() == "white":
            return card.get_colour() != "black"
        # black cards can be placed on any colour, but not purple or white.
        elif self.get_colour() == "black":
            return card.get_colour() != "white" and card.get_colour(
            ) != "purple"
        # purple cards can only be placed on white cards (if type/colour different)
        elif self.get_colour() == "purple":
            return card.get_colour() == "white"
        # coloured cards can be placed on black or white cards
        else:
            return card.get_colour() == "black" or card.get_colour() == "white"

    def can_be_played_on(self, player, card):
        """
        Can this card be played on the given card
        :param card:
        :param player: is it the players turn of not
        :return: True or False
        """
        if player.is_turn() is False:
            return False
        if self.game.pickup != 0 and self.can_be_on_pickup() is False:
            return False
        return card.is_compatible_with(
            player, self) and self.is_compatible_with(player, card)

    def can_play_with(self, player, card, is_first_card):
        """
        Can this additional card be played with this card? Considers if this is the first card in the planning pile
        :param card:
        :param player:
        :param is_first_card:
        :return:
        """
        if is_first_card:
            return card.get_type() == self.get_type()

        return False

    def can_be_played_with(self, player):
        """
        Can this card be played on the given planning pile?
        By default this checks if you can play with ANY of the cards in the planning pile
        :param player:
        :return:
        """
        is_first_card = True
        for card in self.game.planning_pile:
            if card.can_play_with(player, self, is_first_card):
                return True
            is_first_card = False
        return False

    def _make_id(self):
        """
        makes and ID that is unique to itself and is human readable
        """
        return extended_formatter.format("{cls.NAME!h}_card_{id}",
                                         cls=self,
                                         id=id(self))

    @classmethod
    def get_compatibility_description(cls):
        if cls.COMPATIBILITY_DESCRIPTION is not None:
            to_return = cls.COMPATIBILITY_DESCRIPTION
        elif cls.CARD_COLOUR == "black":
            to_return = "This is a regular black card. Compatible with all black, red, green, yellow and blue cards."
        elif cls.CARD_COLOUR == "white":
            to_return = "This is a regular white card. Compatible with all white, " \
                        "purple, red, green, yellow and blue cards."
        elif cls.CARD_COLOUR == "purple":
            to_return = "This is a regular purple card. Compatible with all purple and white cards."
        else:
            to_return = "This is a regular {cls.CARD_COLOUR} card. " \
                        "Compatible with all {cls.CARD_COLOUR}, black and white cards."

        if cls.MULTI_COLOURED:
            to_return += " Also compatible with {cls.CARD_TYPE} cards of any colour."

        return extended_formatter.format(to_return, cls=cls)

    def __gt__(self, other):
        """
        Is this card greater than (goes after) the given other card.
        This is used for sorting.
        Sorts by card category index, then type, then color then name then id
        :param other: other card
        :return: True if this card is grater
        """
        if self.get_category_index() != other.get_category_index():
            return self.get_category_index() > other.get_category_index()
        elif self.get_type() != other.get_type():
            return self.get_type() > other.get_type()
        elif self.get_colour() != other.get_colour():
            return self.get_colour() > other.get_colour()
        elif self.get_name() != other.get_name():
            return self.get_name() > other.get_name()
        else:
            return self.get_id() > other.get_id()

    def __lt__(self, other):
        return not self.__gt__(other)

    def get_url(self):
        return url_for('static', filename=escape(self.CARD_IMAGE_URL))

    def get_category_index(self):
        return cards.get_card_index(self)

    def get_id(self):
        return self.id

    def get_name(self):
        return self.NAME

    def get_colour(self):
        return self.CARD_COLOUR

    def get_type(self):
        return self.CARD_TYPE

    def can_be_on_pickup(self):
        return self.CAN_BE_ON_PICKUP