添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

So, im making a tic-tac-toe game and im nearly finished i think. im trying to make it so the game can be played more than just once before it ends. So i put it into a def() function… but running it results in NameError: name 'turn' is not defined . Any ideas why and how to fix this?

def game(): blanksheet = "|1|2|3|\n|4|5|6|\n|7|8|9|" sheet = blanksheet print(sheet) gone = [] turn = 0 def play(XO,player,listXO): global turn global sheet global listx global listo while True: num = input(player+" enter an available number where you want to put an "+XO+".\n > ") num = int(num) except ValueError: print("Not a valid number, try again.") continue if num < 1 or num > 9: print("Number not in correct range, try again.") continue if num in gone: print("Number already used, try again.") continue gone.append(num) listXO.append(num) turn += 1 #the "problem is here" sheet = sheet.replace(str(num),XO) print(sheet) break win = "h" listx = [] listo = [] def checkstatus(listXO, playerwin): if len(listXO) >= 3: if 1 in listXO and 2 in listXO and 3 in listXO: winspeak(playerwin) #vertical elif 4 in listXO and 5 in listXO and 6 in listXO: winspeak(playerwin) #vertical elif 7 in listXO and 8 in listXO and 9 in listXO: winspeak(playerwin) #vertical elif 1 in listXO and 4 in listXO and 7 in listXO: winspeak(playerwin) #horizontal elif 2 in listXO and 5 in listXO and 8 in listXO: winspeak(playerwin) #horizontal elif 3 in listXO and 6 in listXO and 9 in listXO: winspeak(playerwin) #horizontal elif 1 in listXO and 5 in listXO and 9 in listXO: winspeak(playerwin) #diagonal elif 3 in listXO and 5 in listXO and 7 in listXO: winspeak(playerwin) #diagonal if (len(listx) + len(listo)) == 9: print("\n Neither player wins, thats a tie!") exit() def winspeak(player): print("\n"+player+" wins!") exit() def checkplay(): while win != "Xwin" or win != "Owin": if turn % 2 == 0: play("X","Player 1",listx) checkstatus(listx,"Player 1") else: play("O","Player 2",listo) checkstatus(listo,"Player 2") checkplay() game()

Why are your other functions defined inside game()? There are occasionally reasons to do this (like closures), but I don’t think they apply here.

You’ve told play() that it should find turn as a global variable. But you’ve never created a global variable with that name. You’ve created turn above it, but that one is inside game(), so it’s local to that function.

So the variable in game() is local, while the variable in play() is global.

I would probably take turn out of play(). It doesn’t seem to need it. Have the caller increment it when play() returns.

These

You’ve told play() that it should find turn as a global variable. But you’ve never created a global variable with that name. You’ve created turn above it, but that one is inside game(), so it’s local to that function.

So the variable in game() is local, while the variable in play() is global.

I would probably take turn out of play(). It doesn’t seem to need it. Have the caller increment it when play() returns.

Those aren’t “other errors”, they’re an attempt to explain what is currently happening in your code.

You need to decide if you’re going to be using a global variable or not. If you are, then the variable has to be assigned in global scope. (Either outside any function, or in a function where it’s declared global).

It may not need to be a global if the only other place it is used is in play(). My recommendation is to

  • Remove the nested function definitions. They’re not making your code clearer.
  • Remove turn from play(). Put that logic elsewhere. Now play() doesn’t need to modify it and you don’t have to make it a global variable.
  • Hi Drew,

    Remember that Python uses indentation to tell what is inside a function
    and what is outside it. You should define your functions at the top of
    you file. Each function should start at level 1 (unindented) like this:

    def game(): # block is indented # don't indent the function signature def play(XO, player, listXO): # block is indented # Finally at the end: game() # not indented

    Don’t indent functions inside other functions.

    Leave a nice space (two lines) between functions to make it easier to
    spot when one ends and the next begins. That makes no difference to the
    Python interpreter, but it helps the reader (you) spot where one
    function ends and the next begins.

    Constants that never change should be defined at the top of your
    program, before the functions. It is the convention to write them in
    all capitals so the reader knows that they should never change:

    BLANKSHEET = "|1|2|3|\n|4|5|6|\n|7|8|9|\n"
    

    Your global variables should be defined in the game() function:

    def game():
        global turn, sheet, listx, listo
        turn = 0
        sheet = BLANKSHEET
        print(sheet)
    

    There may be other improvements and comments needed afterwards.

    Have fun with your programming!

    Simply because it isn’t needed. play()'s job seems to be to ask the player where they want to move in the game. It needs to know what moves have happened before (so it can not duplicate them), what are valid moves, etc. And then it returns the chosen move to the caller.

    But it doesn’t matter whose turn it is. The only thing it uses the variable for is to update it when the play is made. Well, the caller could do that just as well. That makes play() shorter and more single-purpose. That makes it easier to write correctly and debug.

    It’s not required at all. You could certainly pass turn between them, or set it up as a global variable. But reducing the scope of where things are used is usually best.