def __init__(self, human_names, computer_strategies, deck_file=None, total_turns=10): self.view = TerminalView() self.turns_remaining = total_turns self.deck = Deck(deck_file) self.discard = Deck() self.direction = self.CLOCKWISE self.current_player_index = 0 self.top_card = self.deal_one_card() if "wild" in self.top_card.special: self.top_card.color = choice(self.COLORS) self.players = [] for name in human_names: self.players.append(HumanPlayer(name)) for i in range(4 - len(human_names) - len(computer_strategies)): computer_strategies.append("basic") for i, strategy_string in enumerate( computer_strategies[:(4 - len(human_names))]): if strategy_string.lower() == "random": self.players.append( RandomComputerPlayer("Computer {} ({})".format( i, strategy_string))) elif strategy_string.lower() == "student": self.players.append( StudentComputerPlayer("Computer {} ({})".format( i, strategy_string))) else: self.players.append( ComputerPlayer("Computer {} ({})".format( i, strategy_string)))
def __init__(self, server_address): authenticated = False self.user = '' self.server_address = server_address self.view = TerminalView()
class Client(): def __init__(self, server_address): authenticated = False self.user = '' self.server_address = server_address self.view = TerminalView() def start(self): while True: choices = [ "Register a New User", "Send a Message", "Get Your Messages", "Edit Registration", "Quit" ] choice = self.view.menu_choice(choices) if choice == 0: self.register() elif choice == 1: self.send_message() elif choice == 2: self.get_messages() elif choice == 3: self.edit_registration() elif choice == 4: break else: pass def get_server_address(self): while True: server_address = self.view.get_server_address() if server_address.find("http://") == -1 and server_address.find( "https://") == -1: server_address = "http://" + server_address try: ping_address = server_address + "/" r = requests.get(ping_address, timeout=5) if r.status_code == requests.codes.ok: break except: pass self.view.report_ping_failed() return server_address def register(self): '''Gets a username and password (with a password verification) and sends it to the server''' user = self.view.get_username() password = self.view.get_password() confirm = self.view.get_password_confirm() if password == confirm: bot_server_address = None if self.view.check_if_bot(): bot_server_address = self.get_server_address() register_address = self.server_address + "/register" payload = { "username": user, "password": password, "server_address": bot_server_address } r = requests.post(register_address, json=payload) response = r.json() if r.ok: if response == USER_EXISTS_IN_DB: self.view.error(USER_EXISTS_IN_DB, "User already exists. Please try again.") return USER_EXISTS_IN_DB else: self.view.success("Thank you for registering!") return SUCCESS else: self.view.error(r.status_code, r.reason) return r.status_code else: self.view.error(AUTHENTICATION_FAILED, "Passwords do not match.") def authenticate(self): ''' Gets a username and password and sends it to the server''' username = self.view.get_username() password = self.view.get_password() auth_address = self.server_address + "/auth" payload = {"username": username, "password": password} r = requests.get(auth_address, json=payload) response = r.json() if response == SUCCESS: self.user = username return SUCCESS else: return r.json() def get_messages(self): isAuthenticated = self.authenticate() if isAuthenticated == SUCCESS: get_address = self.server_address + "/get_messages" payload = {"username": self.user} r = requests.get(get_address, json=payload) if r.ok: response_content = r.json() messageList = response_content['messages'] self.view.display(messageList, len(messageList)) else: self.view.error(r.status_code, r.reason) elif isAuthenticated == USER_DOES_NOT_EXIST: self.view.error(USER_DOES_NOT_EXIST, "User does not exist.") else: self.view.error(AUTHENTICATION_FAILED, "Authentication Failed.") def send_message(self): isAuthenticated = self.authenticate() if isAuthenticated == SUCCESS: # Post the message to the server send_address = self.server_address + "/" payload = self.view.create_message(self.user) r = requests.post(send_address, json=payload) if r.ok: self.view.success('Message Sent!') else: self.view.error(r.status_code, r.text) elif isAuthenticated == USER_DOES_NOT_EXIST: self.view.error(USER_DOES_NOT_EXIST, "User does not exist.") else: self.view.error(AUTHENTICATION_FAILED, "Authentication Failed.") def edit_registration(self): user = self.view.get_username() password = self.view.get_password() new_password = None if self.view.change("password"): new_password = self.view.get_password() confirm = self.view.get_password_confirm() if new_password != confirm: self.view.error(AUTHENTICATION_FAILED, "Passwords do not match.") return new_server_address = None if self.view.change("server address"): new_server_address = self.get_server_address() edit_address = self.server_address + "/edit" payload = { "username": user, "old_password": password, "new_password": new_password, "server_address": new_server_address } r = requests.post(edit_address, json=payload) response = r.json() if r.ok: if response == SUCCESS: self.view.success("Registration updated.") return SUCCESS elif response == USER_DOES_NOT_EXIST: self.view.error(USER_DOES_NOT_EXIST, "User does not exist.") return USER_DOES_NOT_EXIST elif response == AUTHENTICATION_FAILED: self.view.error(AUTHENTICATION_FAILED, "Authentication failed.") return AUTHENTICATION_FAILED else: self.view.error(r.status_code, r.reason) return r.status_code
class UnoGame(object): """Creates an instance of an UnoGame which runs the logic of the game to give players turn, make sure players play valid cards, and determine when a player wins. The UnoGame also enforces the rules of special cards in Uno like reverse or draw four. Args: deck_file (str): The filepath to the deck of cards total_rounds (int): The number of rounds to play before ending the game human_names (list of str): names of human player (up to 4) computer_strategies (list of str): names of strategies for computer players () """ START_CARDS = 7 NUM_PLAYERS = 4 CLOCKWISE = 1 ANTICLOCKWISE = -1 COLORS = ["red", "blue", "green", "yellow"] def __init__(self, human_names, computer_strategies, deck_file=None, total_turns=10): self.view = TerminalView() self.turns_remaining = total_turns self.deck = Deck(deck_file) self.discard = Deck() self.direction = self.CLOCKWISE self.current_player_index = 0 self.top_card = self.deal_one_card() if "wild" in self.top_card.special: self.top_card.color = choice(self.COLORS) self.players = [] for name in human_names: self.players.append(HumanPlayer(name)) for i in range(4 - len(human_names) - len(computer_strategies)): computer_strategies.append("basic") for i, strategy_string in enumerate( computer_strategies[:(4 - len(human_names))]): if strategy_string.lower() == "random": self.players.append( RandomComputerPlayer("Computer {} ({})".format( i, strategy_string))) elif strategy_string.lower() == "student": self.players.append( StudentComputerPlayer("Computer {} ({})".format( i, strategy_string))) else: self.players.append( ComputerPlayer("Computer {} ({})".format( i, strategy_string))) def play(self): """ Plays an uno game Returns: (str) name of the game winner """ self.deal_starting_cards() win = False while self.turns_remaining > 0 and not win: win = self.play_turn() self.turns_remaining -= 1 if win: winner = self.players[self.current_player_index] self.view.show_winning_game(winner) return winner.name def deal_starting_cards(self): """ Deals cards to all players to begin the games """ if self.deck.get_num_cards() < self.START_CARDS * self.NUM_PLAYERS: self.view.show_out_of_cards() return False for i in range(self.START_CARDS): for player in self.players: self.deal_one_card(player) def play_turn(self): """ Plays one round of uno Returns: (bool) whether the game has been won by the current player """ player = self.current_player() self.view.show_beginning_turn(player, self.top_card) card = player.choose_card(self.top_card) if card: self.view.show_played_card(player, card) if self.valid_card_choice(card): if self.top_card.special == 'wild' or self.top_card.special == 'wild-draw-four': self.top_card.color = None #reseting the color of the wild card before it goes into the discard pile self.discard.add_card(self.top_card) self.top_card = card if len(player.hand) == 0: return True if card.special: self.special_card_action(card) else: self.view.show_invalid_card(player, card, self.top_card) player.add_to_hand(card) self.deal_n_cards(2, player) else: self.deal_n_cards(1, player) self.increment_player_num() return False def deal_n_cards(self, n, player=None): """ Takes n cards from the Deck and deals them to a Player or returns the Card(s) if no Player is specified. If the deck is empty, the discard pile is shuffled and becomes the deck Args: n (int): number of cards to deal player (Player): Player to deal the card (None if no Player) Returns: Card or list of Card: the drawn card(s) """ cards = [] for i in range(n): if self.deck.get_num_cards() == 0: if self.discard.get_num_cards() == 0: self.view.show_empty_decks() return None self.view.show_shuffling_deck() self.discard.shuffle_deck() empty_deck = self.deck self.deck = self.discard self.discard = empty_deck card = self.deck.get_top_card() cards.append(card) if player: player.add_to_hand(card) self.view.show_drawing_card(player) return cards def deal_one_card(self, player=None): """Just makes life a little easier. Args: player (Player): optional player to deal the card to """ return self.deal_n_cards(1, player)[0] def increment_player_num(self): """ Increments/decrements the current_player_index depending on the direction of the game. Resets when number drops below 0 or goes over 3. """ self.current_player_index = (self.current_player_index + self.direction) % len(self.players) def current_player(self): """Returns the current Player object. """ return self.players[self.current_player_index] def next_player(self): """Returns the next Player object depending on the direction of the game """ next_player_index = (self.current_player_index + self.direction) % len( self.players) return self.players[next_player_index] def valid_card_choice(self, card_choice): """ Check to see if the card is playable given the top card Args: card_choice (Card): a potentially playable Card Returns: (bool) for whether the card is playable """ if card_choice: if card_choice.special == "wild" or card_choice.special == "wild-draw-four": return True if (self.top_card.number and self.top_card.number == card_choice.number) or ( self.top_card.color and self.top_card.color == card_choice.color) or ( self.top_card.special and self.top_card.special == card_choice.special): return True return False def wild(self): """Allows the current player to change the top card color. NOTE: this sets the color of the wild card to the players choice to maintain game state. """ new_color = self.current_player().choose_color() self.top_card.color = new_color def skip(self): """ Skips the next player's turn """ self.increment_player_num() def reverse(self): """ Reverses the direction of the game """ self.direction *= -1 # ----------- 💻 PART 2️⃣: WRITE YOUR CODE HERE ⬇️ ----------- # Edit this function to include calls to your special card functions # The game expects the special cards in the following format: 'wild', 'skip', 'reverse', 'wild-draw-four', 'draw-two' def special_card_action(self, card): """ Deals with a special card's action Args: card (Card): they special card that was played """ if card.special == 'wild': self.wild() elif card.special == 'skip': self.skip() elif card.special == 'reverse': self.reverse() else: raise ValueError( "UnoGame doesn't know how to play special card: {}".format( card.special)) self.view.show_card_action(self.current_player(), self.next_player(), self.top_card)
class Client(): def __init__(self, server_address): authenticated = False self.user = '' self.server_address = server_address self.view = TerminalView() def start(self): while True: choices = ["Register a New User", "Send a Message", "Get Your Messages", "Quit"] choice = self.view.menu_choice(choices) if choice == 0: self.register() else: if choice == 1: self.send_message() elif choice == 2: self.get_messages() elif choice == 3: break else: pass def register(self): '''Gets a username and password (with a password verification) and sends it to the server''' user = self.view.get_username() password = self.view.get_password() confirm = self.view.get_password_confirm() if password == confirm: register_address = self.server_address + "/register" payload = {"username": user, "password": password} r = requests.post(register_address, json=payload) response = r.json() if r.ok: if response == USER_EXISTS_IN_DB: self.view.error(USER_EXISTS_IN_DB, "User already exists. Please try again.") return USER_EXISTS_IN_DB else: self.view.success("Thank you for registering!") return SUCCESS else: self.view.error(r.status_code, r.reason) return r.status_code else: self.view.error(AUTHENTICATION_FAILED, "Authentication Failed.") def authenticate(self): ''' Gets a username and password and sends it to the server''' username = self.view.get_username() password = self.view.get_password() auth_address = self.server_address + "/auth" payload = {"username": username, "password": password} r = requests.get(auth_address, json=payload) response = r.json() if response == SUCCESS: self.user = username return SUCCESS else: return r.json() def get_messages(self): isAuthenticated = self.authenticate() if isAuthenticated == SUCCESS: get_address = self.server_address + "/get_messages" payload = {"username": self.user} r = requests.get(get_address, json=payload) if r.ok: response_content = r.json() messageList = response_content['messages'] self.view.display(messageList, len(messageList)) else: self.view.error(r.status_code, r.reason) elif isAuthenticated == USER_DOES_NOT_EXIST: self.view.error(USER_DOES_NOT_EXIST, "User does not exist.") else: self.view.error(AUTHENTICATION_FAILED, "Authentication Failed.") def send_message(self): isAuthenticated = self.authenticate() if isAuthenticated == SUCCESS: # Post the message to the server send_address = self.server_address + "/" payload = self.view.create_message(self.user) r = requests.post(send_address, json=payload) if r.ok: self.view.success('Message Sent!') else: self.view.error(r.status_code, r.reason) elif isAuthenticated == USER_DOES_NOT_EXIST: self.view.error(USER_DOES_NOT_EXIST, "User does not exist.") else: self.view.error(AUTHENTICATION_FAILED, "Authentication Failed.")