user135094
user135094

Reputation: 1

Python debugging advice needed

I am trying to make a tic tac toe program, I set the user to be X and the computer to be Y. Once a winner is declared it is supposed to start the game to play again. It runs perfectly through the loop the first time, but on the following game it changes the user to O and the computer to O, also only the user has a turn the computer never goes, but the program registers the computer as winning because the computer is O . If the program chooses the computer to go first, it will make the first move, but it wont get a turn again. I think there is something wrong with the loop but I cant figure out where.

 import random


winningCombinations=[]
userhistory=[]
secondchance=[]

def drawBoard(board):
    # This function prints out the board that it was passed.
    # "board" is a list of 10 strings representing the board (ignore index 0)
    print('')
    print('')
    print('   |   |')
    print(' ' + board[7] + ' | ' + board[8] + ' | ' + board[9])
    print('   |   |')
    print('-----------')
    print('   |   |')
    print(' ' + board[4] + ' | ' + board[5] + ' | ' + board[6])
    print('   |   |')
    print('-----------')
    print('   |   |')
    print(' ' + board[1] + ' | ' + board[2] + ' | ' + board[3])
    print('   |   |')
    print('')
    print('')

def getComputerMove():

    # Here is our algorithm for our Tic Tac Toe AI:
    if userhistory in winningCombinations:
        #try to beat it
        blockingMove = secondchance[len(secondchance)-1]
        return blockingMove
    else:
        #make a rando move

        move = random.randint(1, 9)
        while theBoard[move] != ' ': #if the move is invalid or occupied
            move = random.randint(1, 9)
        return move




print('Welcome to Tic Tac Toe!')

#First ask the user if it wants to be X or 0
userin = ''
#while not (userin == 'X' or userin == 'O'):
#   userin = raw_input('Do you want to be X or O?').upper()
# the first element in the tuple is the player's letter, the second is the computer's letter.
#if userin == 'X':
#    playerLetter, computerLetter = ['X', 'O']
#elif userin =="O":
#    computerLetter, playerLetter =  ['O', 'X']


numGames = 1 #to keep track of the user history



#computergenerates who gets to go first
if random.randint(0, 1) == 0:
    turn = 'computer'
else:
    turn = 'player'
print('The ' + turn + ' will go first.')



while True:

# Reset the board
    theBoard = [' '] * 10
    del userhistory[:]


    gameIsPlaying = True


    while gameIsPlaying:
        playerLetter = 'X'
        computerLetter = 'O'

        if turn == 'player':
            # Player's turn.
            drawBoard(theBoard)


            umove = int(raw_input('What is your next move? (1-9)'))
            while theBoard[umove] != ' ': #if the move is invalid or occupied
                umove = int(raw_input('What is your next move? (1-9)'))

            theBoard[umove]=playerLetter #places move onto board
            userhistory.append(umove) #records users moves
            secondchance.append(umove)#records users moves



#Check to see if its a winner
            if ((theBoard[7] == playerLetter and theBoard[8] == playerLetter and theBoard[9] == playerLetter) or # across the top
    (theBoard[4] == playerLetter and theBoard[5] == playerLetter and theBoard[6] == playerLetter) or # across the middle
    (theBoard[1] == playerLetter and theBoard[2] == playerLetter and theBoard[3] == playerLetter) or # across the bottom
    (theBoard[7] == playerLetter and theBoard[4] == playerLetter and theBoard[1] == playerLetter) or # down the left side
    (theBoard[8] == playerLetter and theBoard[5] == playerLetter and theBoard[2] == playerLetter) or # down the middle
    (theBoard[9] == playerLetter and theBoard[6] == playerLetter and theBoard[3] == playerLetter) or # down the right side
    (theBoard[7] == playerLetter and theBoard[5] == playerLetter and theBoard[3] == playerLetter) or # diagonal
    (theBoard[9] == playerLetter and theBoard[5] == playerLetter and theBoard[1] == playerLetter)):

                drawBoard(theBoard)
                print('Hooray! You have won the game!')
                del userhistory[len(userhistory)-1] #deleting last element to find the combination just before losing

                winningCombinations.append(userhistory) #stores the winning combination into another list
                numGames+=1
                gameIsPlaying = False

            else:
                empty = ' '
                if empty not in theBoard:
                    print('The game is a tie!')
                    break

                else:
                    turn = 'computer'


        else:
            # Computer's turn.
            cmove = getComputerMove()

            theBoard[cmove] = computerLetter

            if ((theBoard[7] == computerLetter and theBoard[8] == computerLetter and theBoard[9] == computerLetter) or # across the top
    (theBoard[4] == computerLetter and theBoard[5] == computerLetter and theBoard[6] == computerLetter) or # across the middle
    (theBoard[1] == computerLetter and theBoard[2] == computerLetter and theBoard[3] == computerLetter) or # across the bottom
    (theBoard[7] == computerLetter and theBoard[4] == computerLetter and theBoard[1] == computerLetter) or # down the left side
    (theBoard[8] == computerLetter and theBoard[5] == computerLetter and theBoard[2] == computerLetter) or # down the middle
    (theBoard[9] == computerLetter and theBoard[6] == computerLetter and theBoard[3] == computerLetter) or # down the right side
    (theBoard[7] == computerLetter and theBoard[5] == computerLetter and theBoard[3] == computerLetter) or # diagonal
    (theBoard[9] == computerLetter and theBoard[5] == computerLetter and theBoard[1] == computerLetter)):

                drawBoard(theBoard)
                print('Aw! You have lost the game, the computer has beaten you!')
                gameIsPlaying = False


            else:
                empty = ' '
                if empty not in theBoard:
                    print('The game is a tie!')
                    break


                else:

                    turn = 'player'

Upvotes: 0

Views: 41

Answers (1)

Prune
Prune

Reputation: 77847

Since you're asking for debugging advice, I'll answer at that level.

When you have a sick patient, ask where it hurts. The print command is a blunt, but effective weapon. At critical points in your code, stick in a statement such as

print "CHECKPOINT A", "turn =", turn

In other words, trace both logic flow and useful values. These statements are especially useful at the top or bottom of a block (loop or function).

Next, when you have a long block of code, consider moving some of the logic into a function. In this program, your code to detect a win would be a good candidate: you have 8 long lines of identical code you could isolate and replace with a function call.

I expect that these two will be enough to track down the problem; they handle almost all of my own failures. Rather than repeating long-standing advice, one point after another, I commend to you the blog post how to debug for further suggestions.

Upvotes: 3

Related Questions