class TestModelShowTurn(unittest.TestCase):
    """ Checks the visual aspect of the user knowing whose turn. """

    def setUp(self):
        """Inits empty grid for testing"""
        self.theView = View()

    def tearDown(self):
        """ Closes the view """
        del self.theView

    @patch('builtins.input', return_value='2')
    def test_show_turn_player_a_keyboard_input_2(self, input_value):
        """ Check if keyboard input 2 works """
        move = self.theView.show_turn(["Player_A"])

        self.assertEqual(move, 1)

    @patch('builtins.input', side_effect=['a','2'])
    def test_show_turn_player_a_keyboard_input_a(self, input_value):
        move = self.theView.show_turn(["Player_A"])
        """ Check if keyboard input a works """

        self.assertEqual(move, 1)

    @patch('builtins.input', side_effect=['','2'])
    def test_show_turn_player_a_keyboard_input_blank(self, input_value):
        """ Check if blank keyboard input works """
        move = self.theView.show_turn(["Player_A"])

        self.assertEqual(move, 1)

    @patch('builtins.input', side_effect=['9','2'])
    def test_show_turn_player_a_keyboard_input_9(self, input_value):
        """ Check if keyboard input 9 works """
        move = self.theView.show_turn(["Player_A"])

        self.assertEqual(move, 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):
     """Inits empty grid for testing"""
     self.theView = View()