class TicTacToe(object):
    def __init__(self):
        rows = 3
        columns = 3
        cellSize = 6
        self.checkersToWin = 3
        self.humanIsBlack = False
        self.humanTurn = True
        self.board = Board(rows, columns)
        self.boardView = BoardView(cellSize)

        print ("Welcome to Tic Tac Toe :)")

        t = Tests(rows, columns, self.checkersToWin)
        t.runTests()

        print ("*** Game Start ***")
        self._gameLoop()

    # responsible for running the game
    # gives turn to the approproate player
    # checks state after turn is completed
    def _gameLoop(self):

        if self.humanTurn:
            self._humanTurn()
        else:
            self._computerTurn()

        self.boardView.showBoard(self.board)

        # check for winning state
        winner = self.board.hasWinner(self.checkersToWin)
        if winner != -1:
            self._handleGameOver(winner)
            return

        if self.board.isCatsGame(self.checkersToWin):
            print ("Cat's game: ")
            print (cat())
            return

        self.humanTurn = not self.humanTurn
        self._gameLoop()

    # handles game over
    def _handleGameOver(self, winner):
        # there is a winner
        self.boardView.showBoard(self.board)
        if winner == 1:
            print ("You won! ")
        else:
            print ("You lost :( ... Better luck next time!")

    # human turn logic

    def _humanTurn(self):
        print ("It's your turn. You are O's!")
        self.boardView.showBoard(self.board)
        self._requestHumanMove()

    def _requestHumanMove(self):
        column = self._getInputInRange("Enter column for you move: ", self.board.height)
        row = self._getInputInRange("Enter row for you move: ", self.board.height)

        if self.board.isEmptyAtColumnRow(column, row):
            self.board.setChecker(column, row, self.humanIsBlack)
        else:
            print ("Looks like the square at column: " + str(column) + ", row: " + str(row) + " is occupied!")
            print ("Please pick a different location!")
            self._requestHumanMove()

    def _getInputInRange(self, string, range):
        while True:
            try:
                row = int(raw_input(string))
                if row >= range:
                    print (str(row) + " is not less than " + str(range))
                    return self._getInputInRange(string, range)

                return row
            except ValueError:

                print "Whoops that doesn't look like a valid number.  Try again..."

    # computer turn logic

    def _computerTurn(self):
        print ("It's the computer's turn!")
        column, row = getAIMoveTuple(self.board, self.checkersToWin, not self.humanIsBlack)
        self.board.setChecker(column, row, not self.humanIsBlack)
        print ("The computer played at column: " + str(column) + " and at row: " + str(row))