Esempio n. 1
0
class Croupier(Player):
    def __init__(self, game, name):
        super().__init__(game, name)
        self.cards = Hand(maxwidth=11)

    def __repr__(self):
        return self.cards.repr(style="horizontal")
Esempio n. 2
0
class Player(object):
    """
    Base class for player objects. Encapsulates the core game mechanics of drawing
    and playing cards.
    """
    def __init__(self, game, name):
        self.cards = Hand(style=self.__class__.style, name=name)
        self.game = game
        self.name = name
        self.message = self.game.message

    def take_card(self):
        """
        Take a card from the deck. If the deck is empty, take the bottom n-1 cards
        from the central stack and shuffle them to get a new deck.
        """
        if not self.game.deck:
            self.game.deck = self.game.central_stack[:-1]
            self.game.central_stack = [self.game.central_stack[-1]]
            shuffle(self.game.deck)
        self.cards.append(self.game.deck.pop())

    def handle_sevens(self):
        """
        Take 2n cards from the deck if there are n "active" sevens in the middle.
        """
        for _ in range(self.game.sevens):
            self.take_card()
            self.take_card()
        self.message.push("{} has to draw {} cards!".format(
            self.name, 2 * self.game.sevens))
        self.game.sevens = 0
        print(self.game)

    def matches(self, top_card):
        matching_suite = [c for c in self.cards if c.suite == top_card.suite]
        matching_rank = [c for c in self.cards if c.rank == top_card.rank]
        return matching_suite, matching_rank

    def move(self):
        """
        Automates the players choices as far as possible regardless of if it is
        a human or AI player. Returns True, if we have to skip one round, False,
        if the player has to pass, and None otherwise.
        """
        top_card = self.game.central_stack[-1]
        # If the top card is a 8, we have to skip this round if the 8 is still
        # effective, that is, if no other player before us has skipped because
        # of this card.
        if self.game.eights:
            self.message.push("{} has to skip one round.".format(self.name))
            self.game.eights = 0
            return True
        # If the top card is a 7, we can avoid having to draw 2(n) cards if we play
        # a 7 of our own. However, we leave this choice (if there is one) to the
        # player, hence, we call handle_sevens only if there is no other possibility
        elif top_card.rank == "7" and self.game.sevens:
            sevens = [c for c in self.cards if c.rank == "7"]
            if not sevens:
                self.handle_sevens()
        # Now look if we have matching cards. If not, draw a card from the deck.
        matching_suite, matching_rank = self.matches(top_card)
        if not matching_suite and not matching_rank:
            self.take_card()
            self.message.push("{} has to draw a card.".format(self.name))
            print(self.game)
        # Look (possibly) again for a match. If there is none, we have to pass.
        matching_suite, matching_rank = self.matches(top_card)
        if not matching_suite and not matching_rank:
            self.message.push("{} has to pass.".format(self.name))
            return False
        # At this point, there is (possibly) a choice left to the player, which
        # may differ for AI and human players. Therefore, we return None.
        return None

    def play(self, card):
        """
        Play out a card, announce that we have won by raising MauMau, increment
        and decrement the counters of unhandeled sevens and eights
        """
        self.cards.remove(card)
        self.game.central_stack.append(card)
        self.message.push("{} plays {} of {}.".format(self.name, card.rank,
                                                      card.suite))
        if card.rank == "7":
            self.game.sevens += 1
        else:
            self.game.sevens = 0
        if card.rank == "8":
            self.game.eights = 1
        else:
            self.game.eights = 0
        if not self.cards:
            raise MauMau

    def __repr__(self):
        return self.cards.repr(style=self.style)