Ejemplo n.º 1
0
class Game(object):
    """ This class represents a game of UNO """
    current_player = None
    current_trick = None
    trump = None
    started = False
    starter = None
    highest_bid = 0
    highest_bidder = None
    reizen_done = False
    weitersagen = False
    reizen_sagenoderhoeren = 0
    sager = None
    hoerer = None
    out = None

    #owner = ADMIN_LIST
    #open = OPEN_LOBBY

    def __init__(self, chat):
        self.chat = chat
        self.last_card = None
        self.last_trick_winner = None
        self.tricks_played = 0
        self.declarer = None
        self.current_trick = Trick()

        self.deck = Deck()

        self.logger = logging.getLogger(__name__)

    @property
    def players(self):
        """Returns a list of all players in this game"""
        players = list()
        if not self.current_player:
            return players

        current_player = self.current_player
        itplayer = current_player.next
        players.append(current_player)
        while itplayer and itplayer is not current_player:
            players.append(itplayer)
            itplayer = itplayer.next
        return players

    def start(self):
        if len(self.players) < 3:
            self.logger.info("Can't start, not enough players.")
        else:
            self.started = True
            self.deck._fill_classic_()
            self.logger.info("Game started.")
            self.sagen_oder_hoeren = 0
            self.sager = self.current_player.next
            self.hoerer = self.current_player
            self.logger.info("Geben: " + str(self.current_player.prev) +
                             " Hören: " + str(self.current_player) +
                             " Sagen: " + str(self.current_player.next))
            #self.

    def turn(self):
        """Marks the turn as over and change the current player"""
        self.logger.debug("Next Player")
        self.current_player = self.current_player.next

    def play_card(self, card):
        """
        Plays a card and triggers its effects.
        Should be called only from Player.play.
        Card is added to current trick.
        """
        self.last_card = card

        self.current_trick.add_card(card)

        self.logger.info("Player " + str(card.owner) + " is playing card " +
                         repr(card))

        if len(self.current_trick.cards) == 3:
            self.tricks_played += 1

            # Determine trick winner
            winnercard = self.current_trick.winner(self.trump)

            # Add trick to trick winner
            winnercard.owner.won_tricks.append(self.current_trick)

            # Set last trick winner of game
            self.last_trick_winner = winnercard.owner

            self.logger.info("Player " + str(winnercard.owner) +
                             " won the trick " + str(self.current_trick.cards))

            # Start a new trick
            self.current_trick = Trick()
            self.last_card = None

            # Trick winner starts new trick
            self.current_player = self.last_trick_winner

            if self.tricks_played == 10:
                self.end()
        else:
            self.turn()

    def end(self):
        self.logger.info("Game ended! Determining winner...")

        players = self.players
        players.remove(self.declarer)

        defenders_points = 0
        for player in players:
            defenders_points += player.result()

        declarer_points = self.declarer.result()
        # For now: adding points of "Skat" to Declarer
        skat = Trick()
        skat.add_card(self.deck.draw())
        skat.add_card(self.deck.draw())

        skat_points = skat.value()
        declarer_points += skat_points

        self.logger.info("Defenders: " + str(defenders_points) +
                         ", Declarer: " + str(declarer_points))

        if declarer_points >= 61:
            self.logger.info("Declarer " + str(self.declarer) + " won with " +
                             str(declarer_points) + " points.")
        else:
            self.logger.info("Defenders " + str(players[0]) + " and " +
                             str(players[1]) + " won with " +
                             str(defenders_points) + " points.")
Ejemplo n.º 2
0
class Game(object):
    """ This class represents a game of UNO """
    current_player = None
    reversed = False
    choosing_color = False
    started = False
    draw_counter = 0
    players_won = 0
    starter = None
    mode = DEFAULT_GAMEMODE
    job = None
    owner = ADMIN_LIST
    open = OPEN_LOBBY
    translate = ENABLE_TRANSLATIONS

    def __init__(self, chat):
        self.chat = chat
        self.last_card = None

        self.deck = Deck()

        self.logger = logging.getLogger(__name__)

    @property
    def players(self):
        """Returns a list of all players in this game"""
        players = list()
        if not self.current_player:
            return players

        current_player = self.current_player
        itplayer = current_player.next
        players.append(current_player)
        while itplayer and itplayer is not current_player:
            players.append(itplayer)
            itplayer = itplayer.next
        return players

    def start(self):
        if self.mode == None or self.mode == "wild":
            self.deck._fill_classic_()
        else:
            self.deck._fill_wild_()

        self._first_card_()
        self.started = True

    def set_mode(self, mode):
        self.mode = mode

    def reverse(self):
        """Reverses the direction of game"""
        self.reversed = not self.reversed

    def turn(self):
        """Marks the turn as over and change the current player"""
        self.logger.debug("Next Player")
        self.current_player = self.current_player.next
        self.current_player.drew = False
        self.current_player.turn_started = datetime.now()
        self.choosing_color = False

    def _first_card_(self):
        # In case that the player did not select a game mode
        if not self.deck.cards:
            self.set_mode(DEFAULT_GAMEMODE)

        # The first card should not be a special card
        while not self.last_card or self.last_card.special:
            self.last_card = self.deck.draw()
            # If the card drawn was special, return it to the deck and loop again
            if self.last_card.special:
                self.deck.dismiss(self.last_card)

        self.play_card(self.last_card)

    def play_card(self, card):
        """
        Plays a card and triggers its effects.
        Should be called only from Player.play or on game start to play the
        first card
        """
        self.deck.dismiss(self.last_card)
        self.last_card = card

        self.logger.info("Playing card " + repr(card))
        if card.value == c.SKIP:
            self.turn()
        elif card.special == c.DRAW_FOUR:
            self.draw_counter += 4
            self.logger.debug("Draw counter increased by 4")
        elif card.value == c.DRAW_TWO:
            self.draw_counter += 2
            self.logger.debug("Draw counter increased by 2")
        elif card.value == c.REVERSE:
            # Special rule for two players
            if self.current_player is self.current_player.next.next:
                self.turn()
            else:
                self.reverse()

        # Don't turn if the current player has to choose a color
        if card.special not in (c.CHOOSE, c.DRAW_FOUR):
            self.turn()
        else:
            self.logger.debug("Choosing Color...")
            self.choosing_color = True

    def choose_color(self, color):
        """Carries out the color choosing and turns the game"""
        self.last_card.color = color
        self.turn()
Ejemplo n.º 3
0
class Game(object):
    """ This class represents a game of UNO """
    current_player = None
    reversed = False
    choosing_color = False
    started = False
    draw_counter = 0
    players_won = 0
    starter = None
    mode = DEFAULT_GAMEMODE
    job = None
    owner = ADMIN_LIST
    open = OPEN_LOBBY
    translate = ENABLE_TRANSLATIONS
    scores = dict()
    last_round_score = list()
    win_score = SCORE_WIN

    def __init__(self, chat):
        self.chat = chat
        self.last_card = None

        self.deck = Deck()

        self.logger = logging.getLogger(__name__)

    @property
    def players(self):
        """Returns a list of all players in this game"""
        players = list()
        if not self.current_player:
            return players

        current_player = self.current_player
        itplayer = current_player.next
        players.append(current_player)
        while itplayer and itplayer is not current_player:
            players.append(itplayer)
            itplayer = itplayer.next
        return players

    def start(self):
        if self.mode == None or self.mode != "wild":
            self.deck._fill_classic_()
        else:
            self.deck._fill_wild_()

        self.current_player = rand_choice(self.players)
        self._first_card_()
        self.started = True

    def set_mode(self, mode):
        self.mode = mode

    def reverse(self):
        """Reverses the direction of game"""
        self.reversed = not self.reversed

    def turn(self):
        """Marks the turn as over and change the current player"""
        self.logger.debug("Next Player")
        self.current_player = self.current_player.next
        self.current_player.drew = False
        self.current_player.turn_started = datetime.now()
        self.choosing_color = False

    def _first_card_(self):
        # In case that the player did not select a game mode
        if not self.deck.cards:
            self.set_mode(DEFAULT_GAMEMODE)

        # The first card should not be a special card
        while not self.last_card or self.last_card.special:
            self.last_card = self.deck.draw()
            # If the card drawn was special, return it to the deck and loop again
            if self.last_card.special:
                self.deck.dismiss(self.last_card)

        self.play_card(self.last_card)

    def play_card(self, card):
        """
        Plays a card and triggers its effects.
        Should be called only from Player.play or on game start to play the
        first card
        """
        self.deck.dismiss(self.last_card)
        self.last_card = card

        self.logger.info("Playing card " + repr(card))
        if card.value == c.SKIP:
            self.turn()
        elif card.special == c.DRAW_FOUR:
            self.draw_counter += 4
            self.logger.debug("Draw counter increased by 4")
        elif card.value == c.DRAW_TWO:
            self.draw_counter += 2
            self.logger.debug("Draw counter increased by 2")
        elif card.value == c.REVERSE:
            # Special rule for two players
            if self.current_player is self.current_player.next.next:
                self.turn()
            else:
                self.reverse()

        # Don't turn if the current player has to choose a color
        if card.special not in (c.CHOOSE, c.DRAW_FOUR):
            self.turn()
        else:
            self.logger.debug("Choosing Color...")
            self.choosing_color = True

    def choose_color(self, color):
        """Carries out the color choosing and turns the game"""
        self.last_card.color = color
        self.turn()

    def add_score(self, player):
        """Add total value of all card in every players hand
        to the winner's score."""
        scores = 0
        self.last_round_score.clear()
        for p in self.players:
            for card in p.cards:
                sc = c.CARD_SCORES[card.value or card.special]
                self.last_round_score.append((sc, card))
                scores += sc
        try:
            self.scores[player.user.id] += scores
        except KeyError:
            self.scores[player.user.id] = scores

    def reset_cards(self):
        """Reset game deck and player's hand"""
        players_cache = self.players
        # clear player's card, might as well use player.cards.clear()
        for player in players_cache:
            for card in player.cards:
                self.deck.dismiss(card)
            player.cards = list()
        # fill deck with normal cards set
        self.deck._fill_classic_()
        # draw player's hand
        for player in players_cache:
            player.draw_score_mode()

    def new_round(self):
        lc = self.last_card
        while self.last_card == lc or not self.last_card or self.last_card.special:
            self.last_card = self.deck.draw()
            # If the card drawn was special, return it to the deck and loop again
            if self.last_card.special:
                self.deck.dismiss(self.last_card)
        self.play_card(self.last_card)

    def get_score(self, player):
        try:
            return self.scores[player.user.id]
        except KeyError:
            self.scores[player.user.id] = 0
            return 0

    def get_scores(self):
        return [(player, self.get_score(player)) for player in self.players]