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.")
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()
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]