Пример #1
0
 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)))
Пример #2
0
    def __init__(self, server_address):

        authenticated = False
        self.user = ''
        self.server_address = server_address
        self.view = TerminalView()
Пример #3
0
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
Пример #4
0
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)
Пример #5
0
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.")