Search code examples
pythontic-tac-toe

handling outlier cases for tictactoe


I need help with the outlier cases. I have mentioned below where the cases are failing.

possibleTurns = ("A1","A2","A3","B1","B2","B3","C1","C2","C3")
movesUsed = []

def main():    
    players = ["X","O"]
    while len(movesUsed) <9:
        #Player 1 Move
        turnp1 = input(f"Choose a move Player 1: ")
        print(f"Your move was: {turnp1}")
        validMove = analyzeMove(turnp1)
        move(validMove,players[0])
        score()
        movesUsed.append(validMove)
        #Player 2 Move
        turnp2 = input(f"Choose a move Player 2: ")
        print(f"Your move was: {turnp2}")
        validMove = analyzeMove(turnp2)
        move(validMove,players[1])
        score()
        movesUsed.append(validMove)```

def analyzeMove(themove):
    if themove.upper() in possibleTurns:
        return themove
    # This works but it switches the turn to player 1 even if its player 2 who makes a mistake.
    if themove.upper() not in possibleTurns:
        print("Invalid Move")
        main()
    # A used move will replace the old move so an X A1 will become O if O is chosen in error.
    if themove.upper() in movesUsed:
        print("That move was used!")
        main()

Solution

  • The problem is that when you call main() recursively, it always starts at player 1's turn.

    Instead of recursing when the input is invalid, use a while loop to keep asking for input until it's valid. analyzeMove can return False to indicate that the move isn't valid, and the loop asks again.

    Another bug is that analyzeMove() checks if the move is in possibleTurns before checking if it has already been used.

    Also, rather than duplicating all the code for player 1 and 2, use a variable to indicate whose turn it is.

    possibleTurns = ("A1","A2","A3","B1","B2","B3","C1","C2","C3")
    movesUsed = []
    
    def main():    
        players = ["X","O"]
        cur_player = 0
        while len(movesUsed) < 9:
            while True:
                turnp1 = input(f"Choose a move Player {cur_player+1}: ")
                print(f"Your move was: {turnp1}")
                validMove = analyzeMove(turnp1)
                if validMove:
                    break
            move(validMove,players[cur_player])
            score()
            movesUsed.append(validMove)
            cur_player = 1 if cur_player == 0 else 0
    
    def analyzeMove(themove):
        if themove.upper() in movesUsed:
            print("That move was used!")
            return False
        if themove.upper() in possibleTurns:
            return themove
        else:
            print("Invalid Move")
            return False