简体   繁体   中英

TicTacToe game stuck in a while loop

I have the following code for a basic TicTacToe game. When playing the code does not break out of the while loop even when the winner is True and the length of used numbers is less than 9. I tried debugging it with breakpoints and the debugger indicates the breakpoint is hit, but the while loop persists.


def TicTacToe():
    #options available 
    nums = [0,1,2,3,4,5,6,7,8,9]
    used = []
    
    #winner winner chicken dinner combinations
    
    
    #board 
    def board():
        print(f" {nums[0]}  |  {nums[1]}  |  {nums[2]}  ")
        print("----|-----|----")
        print(f" {nums[3]}  |  {nums[4]}  |  {nums[5]}  ")
        print("----|-----|----")
        print(f" {nums[6]}  |  {nums[7]}  |  {nums[8]}  ")
    
    # def progress(): 
        
    
        # return wwcd
    
    def round(player = "X"):
        print(used)
        winner = False
        
        while len(used) < 9 and winner == False:
            print(len(used))
            
            if player == "X":
                
                board()
                selected = int(input("Select number on the board to place X: "))
                if selected in nums and selected not in used:
                    used.append(selected)
                    nums[selected] = "X"
                    
                    
                    
                       
                    if (nums[0] == "X" and nums[1] == "X" and nums[2] == "X") or (nums[3] == "X" and nums[4] =="X" and nums[5] =="X") or (nums[6] == "X" and nums[7] =="X" and nums[8] =="X") or (nums[0] == "X" and nums[4] =="X" and nums[8] =="X") or (nums[6] == "X" and nums[4] =="X" and nums[2] =="X") or (nums[0] == "X" and nums[3] =="X" and nums[6] =="X") or (nums[1] == "X" and nums[4] =="X" and nums[7] =="X") or (nums[2] == "X" and nums[5] =="X" and nums[8] =="X"): 
                            board()
                            print("Congradulations X, you win!")
                            winner = True
                            break
                            
                            
                            
                            
                            
                    else:
                        print('O turn now')
                        round("O")
            elif player == "O":
                board()
                selected = int(input("Select number on the board to place O: "))
                if selected in nums and selected not in used:
                    used.append(selected)
                    nums[selected] = "O"
                    
                    
                        
                    if (nums[0] == "O" and nums[1] == "O" and nums[2] == "O") or (nums[3] == "O" and nums[4] =="O" and nums[5] =="O") or (nums[6] == "O" and nums[7] =="O" and nums[8] =="O") or (nums[0] == "O" and nums[4] =="O" and nums[8] =="O") or (nums[6] == "O" and nums[4] =="O" and nums[2] =="O") or (nums[0] == "O" and nums[3] =="O" and nums[6] =="O") or (nums[1] == "O" and nums[4] =="O" and nums[7] =="O") or (nums[2] == "O" and nums[5] =="O" and nums[8] =="O"): 
                            board()
                            print("Congradulations O, you win!")
                            winner = True
                            print('Hit, Winner found')
                            
                            
                            
                            
                    else:
                        round()
                        
                

                
            
    round()
    

TicTacToe()

There is a logical problem.

The break is working well after assigning True to winner variable. The problem is that you call the round() function again, so the winner became False again. To avoid this unwanted calling round() function at the end, you need some re-structure your code.

You declared variables such as nums and used at the beginning of TicTacToc function, but declared winner inside the function round() . It would be better to declare winner outside of the function round() so that winner keep assigned value.

However, if you declare winner outside of the function round() , it will throw an error because, unlike nums and used ( list type), winner is not a list so it cannot be refer in round function. (To understand why, you may want to google call by reference and call by value ). To resolve this issue, you can use global keyword inside round function, indicating that we will use the winner variable in the round function. Then, your code will work.

However, I highly recommend re-construct your code to avoid using global keyword because it sometime makes code confusing. It would be nice not using nested function.

Other minor problems are...

  • Use different name of function for round , because it is pre-defined built-in keyword in Python.
  • Use winner is False instead of winner == False . (PEP 8: E712 comparison to False should be 'if cond is False:' or 'if not cond:')

Follwing is a code I fixed using global , so that it works. However, make sure that you need to re-construct the code without global and unnecessary nested functions.

def TicTacToe():
    # options available
    nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    used = []
    winner = False

    # winner winner chicken dinner combinations

    # board
    def board():
        print(f" {nums[0]}  |  {nums[1]}  |  {nums[2]}  ")
        print("----|-----|----")
        print(f" {nums[3]}  |  {nums[4]}  |  {nums[5]}  ")
        print("----|-----|----")
        print(f" {nums[6]}  |  {nums[7]}  |  {nums[8]}  ")

    # def progress():

    # return wwcd
    def round(player="X"):
        print(used)
        global winner # meaning that you will use the winner declared outside.
        winner = False
        while (len(used) < 9) and (winner is False):
            print(len(used), winner)

            if player == "X":
                board()
                selected = int(input("Select number on the board to place X: "))
                if selected in nums and selected not in used:
                    used.append(selected)
                    nums[selected] = "X"

                    if (nums[0] == "X" and nums[1] == "X" and nums[2] == "X") or (
                            nums[3] == "X" and nums[4] == "X" and nums[5] == "X") or (
                            nums[6] == "X" and nums[7] == "X" and nums[8] == "X") or (
                            nums[0] == "X" and nums[4] == "X" and nums[8] == "X") or (
                            nums[6] == "X" and nums[4] == "X" and nums[2] == "X") or (
                            nums[0] == "X" and nums[3] == "X" and nums[6] == "X") or (
                            nums[1] == "X" and nums[4] == "X" and nums[7] == "X") or (
                            nums[2] == "X" and nums[5] == "X" and nums[8] == "X"):
                        board()
                        print("Congradulations X, you win!")
                        winner = True
                        break
                    else:
                        print('O turn now')
                        round("O")
            elif player == "O":
                board()
                selected = int(input("Select number on the board to place O: "))
                if selected in nums and selected not in used:
                    used.append(selected)
                    nums[selected] = "O"

                    if (nums[0] == "O" and nums[1] == "O" and nums[2] == "O") or (
                            nums[3] == "O" and nums[4] == "O" and nums[5] == "O") or (
                            nums[6] == "O" and nums[7] == "O" and nums[8] == "O") or (
                            nums[0] == "O" and nums[4] == "O" and nums[8] == "O") or (
                            nums[6] == "O" and nums[4] == "O" and nums[2] == "O") or (
                            nums[0] == "O" and nums[3] == "O" and nums[6] == "O") or (
                            nums[1] == "O" and nums[4] == "O" and nums[7] == "O") or (
                            nums[2] == "O" and nums[5] == "O" and nums[8] == "O"):
                        board()
                        print("Congradulations O, you win!")
                        winner = True
                    else:
                        round()

    round()  # This call the round function althouth winner is already True.

TicTacToe()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM