Ad
Code
Diff
  • PLAYER_1 = 1
    PLAYER_2 = 2
    
    
    class NoughtsAndCrosses(object):
        """Basic implementation of Noughts and Crosses"""
        WIN_COMBOS = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
        EMPTY_BOARD = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    
        def __init__(self):
            self.current_board = self.EMPTY_BOARD.copy()
            self.current_player = PLAYER_1  # game always starts with PLAYER_1
            self.player_names = {}
            self.player_markers = {
                PLAYER_1: "",
                PLAYER_2: "",
            }
    
        def _print_board(self):
            """Prints the current board"""
            print("--- Noughts and Crosses ---")
            print(f'{self.current_board[0]} : {self.current_board[1]} : {self.current_board[2]}')
            print("..........")
            print(f'{self.current_board[3]} : {self.current_board[4]} : {self.current_board[5]}')
            print("..........")
            print(f'{self.current_board[6]} : {self.current_board[7]} : {self.current_board[8]}')
    
        def play(self):
            self._print_welcome_message()
            self._get_player_names()
            self._get_player_markers()
            while True:
                self._let_current_player_move()
                if self._player_has_won(self.current_player):
                    print(f"{self.player_names[self.current_player]}, you have won!")
                    break
                elif self._check_if_board_is_full():
                    print(f"Stalemate - End of game")
                    break
                self._switch_current_player()
    
        def _let_current_player_move(self):
            print("Hi", self.player_names[self.current_player])
            while True:
                chosen_board_index = self._get_next_move()
                if self._location_is_taken(chosen_board_index):
                    print('>>> Position taken, try again!')
                    continue
                else:
                    self._update_board(chosen_board_index)
                    self._print_board()
                    break
    
        def _update_board(self, chosen_board_index):
            self.current_board[chosen_board_index] = self.player_markers[self.current_player]
    
        @staticmethod
        def _print_welcome_message():
            print("*" * 50)
            print("Welcome to our Noughts and Crosses Game!")
            print("*" * 50)
    
        def _get_player_names(self):
            self.player_names[1] = input("Enter the name of the first player:\n> ")
            self.player_names[2] = input("Enter the name of the second player:\n> ")
    
        def _get_player_markers(self):
            self.player_markers[PLAYER_1] = input(f"{self.player_names[PLAYER_1]}, choose your marker (X/O):\n> ").upper()
            while self.player_markers[PLAYER_1] not in ["X", "O"]:
                print('>>> Invalid marker! Please choose either "X" or "O".')
                self.player_markers[PLAYER_1] = input(f"{self.player_names[PLAYER_1]}, choose your marker (X/O):\n> ").upper()
            self.player_markers[PLAYER_2] = "X" if self.player_markers[PLAYER_1] == "O" else "O"
    
        def _switch_current_player(self):
            if self.current_player == PLAYER_1:
                self.current_player = PLAYER_2
            else:
                self.current_player = PLAYER_1
    
        def _location_is_taken(self, board_index):
            return self.current_board[board_index] in self.player_markers.values()
    
        def _check_if_board_is_full(self):
            return True if all(marker in self.player_markers.values() for marker in self.current_board) else False
    
        def _player_has_won(self, player):
            for win_combo in self.WIN_COMBOS:
                if set(win_combo) <= set(self._get_player_locations(player)):
                    return True
            return False  # if no winning combinations were found
    
        def _get_player_locations(self, player):
            return [index for index, marker in enumerate(self.current_board) if marker == self.player_markers[player]]
    
        @staticmethod
        def _get_next_move():
            while True:
                chosen_location = input("Cross location (choose 1 - 9):\n> ")
                if not chosen_location.isdigit() or int(chosen_location) not in range(1, 10):
                    print('>>> Invalid input!')
                    continue
                else:
                    chosen_location = int(chosen_location) - 1  # adjust for array index to start at 0 not 1
                    return chosen_location
    
    
    if __name__ == '__main__':
        NoughtsAndCrosses().play()
    
    • PLAYER_1 = 1
    • PLAYER_2 = 2
    • class NoughtsAndCrosses(object):
    • """Basic implementation of Noughts and Crosses"""
    • WIN_COMBOS = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
    • EMPTY_BOARD = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    • def __init__(self):
    • self.current_board = self.EMPTY_BOARD.copy()
    • self.current_player = PLAYER_1 # game always starts with PLAYER_1
    • self.player_names = {}
    • self.location_lists = {
    • PLAYER_1: [],
    • PLAYER_2: []
    • }
    • self.player_markers = {
    • PLAYER_1: "X",
    • PLAYER_2: "O",
    • PLAYER_1: "",
    • PLAYER_2: "",
    • }
    • def _print_board(self):
    • """Prints the current board"""
    • print("--- Noughts and Crosses ---")
    • print(f'{self.current_board[0]} : {self.current_board[1]} : {self.current_board[2]}')
    • print("..........")
    • print(f'{self.current_board[3]} : {self.current_board[4]} : {self.current_board[5]}')
    • print("..........")
    • print(f'{self.current_board[6]} : {self.current_board[7]} : {self.current_board[8]}')
    • def play(self):
    • self._print_welcome_message()
    • self._get_player_names()
    • self._get_player_markers()
    • while True:
    • self._let_current_player_move()
    • if self._player_has_won(self.current_player):
    • print(f"{self.player_names[self.current_player]}, you have won!")
    • break
    • elif self._check_if_board_is_full():
    • print(f"Stalemate - End of game")
    • break
    • self._switch_current_player()
    • def _let_current_player_move(self):
    • print("Hi", self.player_names[self.current_player])
    • while True:
    • chosen_board_index = self._get_next_move()
    • if self._location_is_taken(chosen_board_index):
    • print('>>> Position taken, try again!')
    • continue
    • else:
    • self._update_board_and_location_lists(chosen_board_index)
    • self._update_board(chosen_board_index)
    • self._print_board()
    • break
    • def _update_board_and_location_lists(self, chosen_board_index):
    • def _update_board(self, chosen_board_index):
    • self.current_board[chosen_board_index] = self.player_markers[self.current_player]
    • self.location_lists[self.current_player].append(chosen_board_index)
    • @staticmethod
    • def _print_welcome_message():
    • print("*" * 50)
    • print("Welcome to our Noughts and Crosses Game!")
    • print("*" * 50)
    • def _get_player_names(self):
    • self.player_names[1] = input("Enter the name of the first player:\n> ")
    • self.player_names[2] = input("Enter the name of the second player:\n> ")
    • def _get_player_markers(self):
    • self.player_markers[PLAYER_1] = input(f"{self.player_names[PLAYER_1]}, choose your marker (X/O):\n> ").upper()
    • while self.player_markers[PLAYER_1] not in ["X", "O"]:
    • print('>>> Invalid marker! Please choose either "X" or "O".')
    • self.player_markers[PLAYER_1] = input(f"{self.player_names[PLAYER_1]}, choose your marker (X/O):\n> ").upper()
    • self.player_markers[PLAYER_2] = "X" if self.player_markers[PLAYER_1] == "O" else "O"
    • def _switch_current_player(self):
    • if self.current_player == PLAYER_1:
    • self.current_player = PLAYER_2
    • else:
    • self.current_player = PLAYER_1
    • def _location_is_taken(self, board_index):
    • return self.current_board[board_index] in self.player_markers.values()
    • def _check_if_board_is_full(self):
    • return True if len(self.location_lists[PLAYER_1] + self.location_lists[PLAYER_2]) == 9 else False
    • return True if all(marker in self.player_markers.values() for marker in self.current_board) else False
    • def _player_has_won(self, player):
    • for win_combo in self.WIN_COMBOS:
    • if set(win_combo) <= set(self.location_lists[player]):
    • if set(win_combo) <= set(self._get_player_locations(player)):
    • return True
    • return False # if no winning combinations was found
    • return False # if no winning combinations were found
    • def _get_player_locations(self, player):
    • return [index for index, marker in enumerate(self.current_board) if marker == self.player_markers[player]]
    • @staticmethod
    • def _get_next_move():
    • while True:
    • chosen_location = input("Cross location(choose 1 - 9):
    • > ")
    • if not chosen_location.isdigit() or int(chosen_location) not in range(10):
    • chosen_location = input("Cross location (choose 1 - 9):
    • > ")
    • if not chosen_location.isdigit() or int(chosen_location) not in range(1, 10):
    • print('>>> Invalid input!')
    • continue
    • else:
    • chosen_location = int(chosen_location) - 1 # adjust for array index to start at 0 not 1
    • return chosen_location
    • if __name__ == '__main__':
    • NoughtsAndCrosses().play()