def discard_card(self, player, card): """Discard card and apply its game effects. Parameters: player -- Player who discards card card -- Card to be discarded """ # remove card from player hand player.hand.remove(card) # and add to discard pile self.discards.append(card) UI.print_discard_result(True, card) # we are done if the player has no more cards in his hand if not player.hand: return # if card is an eight, skip next player elif card.value == '8': self.skip = True # if card is a two, next player needs to draw two elif card.value == '2': self.draw2 = True # if card is a queen, next player needs to draw four elif card.value == 'Q': self.draw4 = True # if card is a king, game direction reverses elif card.value == 'K': self.direction *= -1 UI.print_message("Game direction reversed.") # if card is a jack, ask player with whom to swap hands elif card.value == 'J': others = [p for p in self.players if p is not player] choice = player.ask_for_swap(others) self.swap_hands(player, choice)
def pick_up_card(self, player, n=1): """Pick card from stock and add to player hand. Parameters: player -- Player who picks the card Keyword arguments: n -- number of cards to pick (default 1) Returns: number of cards actually picked Picks n cards from the stock pile and adds it to the player hand. If the stock has less than n cards, all but the top most discard are shuffled back into the stock. If this is still not sufficient, the maximum possible number of cards is picked. """ # repeat n times for i in range(1, (n + 1)): # if no more card in stock pile if not self.stock: # add back discarded cards (but not top card) if len(self.discards) == 1: UI.print_message("All cards distributed") return i - 1 self.stock = self.discards[:-1] del self.discards[:-1] # shuffle stock random.shuffle(self.stock) UI.print_message("Discards are shuffled back.") # draw stock card card = self.stock.pop() # and add to hand player.hand.append(card) return n
def swap_hands(self, p1, p2): """Exchanges the hands of the two given players. Parameters: p1 -- one of the players participating in the hand swap p2 -- the other player participating in the hand swap """ p1.hand, p2.hand = p2.hand, p1.hand UI.print_message('{} swaps hands with {}.'.format(p1.name, p2.name))
def draw_and_discard(self, player, top_card): """Draw a card from stock and discard it if possible. Parameters: player -- the Player that draws the card calls pick_up_card to obtain a stock card and adds it to the player's hand. If the card can be discarded, discard_card is called with the newly picked card. """ UI.print_message("No matching card. Drawing ...") # return if no card could be picked if not self.pick_up_card(player): return # discard picked card if possible card = player.hand[-1] if self.can_discard(card, top_card) is True: self.discard_card(player, card) # otherwise inform the player elif not player.is_ai: UI.print_discard_result(False, card)
def run_player(self, player): """Process a single player's turn. Parameters: player -- Player to make the turn Returns: True if the game continues, otherwise False. In each turn, game effects are applied according to the outcome of the last turn. The player is then asked to select a card via a call to Player.select_card which is then discarded via a call to discard_card. If the player has no discardable card (or chooses voluntarily not to discard), draw_and_discard is called to draw from stock. """ # apply any pending penalties (skip, draw2, draw4) if self.skip is True: # return without performing any discard self.skip = False UI.print_message('{} is skipped.'.format(player.name)) return elif self.draw2 is True: # draw two cards picked = self.pick_up_card(player, n=2) self.draw2 = False UI.print_message('{} draws {} cards.'.format(player.name, picked)) elif self.draw4 is True: # draw four cards picked = self.pick_up_card(player, n=4) self.draw4 = False UI.print_message('{} draws {} cards.'.format(player.name, picked)) top_card = self.discards[-1] hand_sizes = [len(p.hand) for p in self.players] UI.print_player_info(player, top_card, hand_sizes) # determine discardable cards discardable = [ card for card in player.hand if self.can_discard(card, top_card) is True ] # have player select card hands = self.get_normalized_hand_sizes(player) card = player.select_card(discardable, hands) if discardable else None if card: # discard card and determine whether player has won self.discard_card(player, card) # if all cards discarded, return True if len(player.hand) == 0: return True else: return False else: # draw and (potentially) discard self.draw_and_discard(player, top_card) # player still has cards and the game goes on return False
def swap_hands(self, p1, p2): """Exchanges the hands of the two given players.""" p1.hand, p2.hand = p2.hand, p1.hand UI.print_message('{} swaps hands with {}.'.format(p1.name, p2.name))