class TestModelUpdateBoard(unittest.TestCase):
    """ Checks the model to see if the board changes are stored. """

    def setUp(self):
        """ Init's current player and players"""
        self.model = Model()

    def tearDown(self):
        """ Closes the model """
        del self.model

    def test_userinput_changes_board_5pieces(self):
        """ Test for a vertical board update index 5 and 5 pieces"""

        self.model.update_board(5)

        mock_board = [[" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 5 + ["\u25CF"], [" "] * 6]

        self.assertEqual(self.model.grid, mock_board, "Column did not update")

    def test_userinput_changes_board_six_pieces(self):
        """ Test for a vertical board update index 5 and six pieces """

        self.model.grid = [[" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, ["\u25CF"] * 6, [" "] * 6]

        column_full = self.model.update_board(5)
        self.assertTrue(column_full, "Board said column was not full")

    def test_userinput_changes_board_differences(self):
        """ Test differences in the boards and full column """

        self.model.grid = [[" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 3 + ["\u25CF"] * 3, [" "] * 6]

        column_full = self.model.update_board(5)

        mock_board = [[" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 6, [" "] * 2 + ["\u25CF"] * 4, [" "] * 6]

        self.assertFalse(column_full, "Board said column was full")
        self.assertEqual(self.model.grid, mock_board, "Column did not update")
class TestModelSwapPlayer(unittest.TestCase):
    """ Checks the model to see if the changing of the player is stored. """

    def setUp(self):
        """ Init's current player and players"""
        self.players = {1: ["Player_a", "x"], 2: ["Player_b", "o"]}
        self.test_function = Model()

    def tearDown(self):
        """ Closes the model """
        del self.test_function

    def test_change_to_player_a(self):
        """Testing if current player 1 gets self.players 1 value"""
        self.test_function.current_player = 1
        self.test_function.swap_player()
        self.assertEqual(self.test_function.current_player, 2)

    def test_change_to_player_b(self):
        """Testing if the current player 2 get self.player 2 value"""
        self.test_function.current_player = 2
        self.test_function.swap_player()
        self.assertEqual(self.test_function.current_player, 1)
class Controller:
    """ Creates logic for communication model and view. """

    def __init__(self):
        """ Init's controller"""
        self.winner = False
        self.view = View()
        self.model = Model()
        self.board = self.model.grid

    def get_board_status(self):
        """ Takes input from grid and updates view for display. """
        self.view.show_board(self.board)

    def get_move(self):
        """
        Get's the input from the view and stores it in the update_board in the model.
        """
        move_needed = True

        while move_needed:
            move = self.view.show_turn(self.model.playing_player)

            move_needed = self.model.update_board(move)

    def check_tie(self):
        """
        Loops through the board and looks for a empty space. If it does find a space it print's that it was a tie.
        """
        for x in self.board: # loop through each inner list
            if x[0] == " ":
                return False
        self.view.show_tie()
        return True

    def check_winner(self):
        """
        Checks to see if four in a row exists horizontally, vertically, or diagonally."""
        #checks columns
        for x in self.board:
            if self.model.playing_player[1] * 4 in "".join(x):
                return True
        #Checks the rows
        for each_row in range(6):
            if self.model.playing_player[1] * 4 in "".join(column[each_row] for column in self.board):
                return True

        #Get's diagonals(cartesian product of a series of lists)
        #checks diagonal
        for row, column in product(range(5,2, -1), range(4)):
            if self.model.playing_player[1] * 4 in "".join(self.board[column + i][row - i] for i in range(4)):
                return True
        #checks the other diagonal
        for row, column in product(range(3), range(4)):
            if self.model.playing_player[1] * 4 in "".join(self.board[column + i][row + i] for i in range(4)):
                return True

        return False

    def main(self):
        """
        Starts game and calls all helper functions to control the flow of the game.
        """
        winner = False
        self.view.starting_print()
        while winner == False:
            self.view.show_board(self.board)
            self.get_move()
            winner = self.check_winner()
            if winner:
                self.view.show_board(self.board)
                self.view.show_winner(self.model.playing_player[0])
                break
            winner = self.check_tie()
            if winner:
                self.view.show_board(self.board)
                self.view.show_tie()
            self.model.swap_player()
 def __init__(self):
     """ Init's controller"""
     self.winner = False
     self.view = View()
     self.model = Model()
     self.board = self.model.grid
 def setUp(self):
     """ Init's current player and players"""
     self.model = Model()
 def setUp(self):
     """ Init's current player and players"""
     self.players = {1: ["Player_a", "x"], 2: ["Player_b", "o"]}
     self.test_function = Model()