【问题标题】:Why does the board only show one x in the console and why can't I switcch from x to o's?为什么板子在控制台只显示一个x,为什么我不能从x切换到os?
【发布时间】:2020-04-18 04:39:47
【问题描述】:

每当我尝试使用全局变量从 x 切换到 o 时,都会收到一条错误消息,提示“Turn is undefined”。所以我把所有东西都移到了一个函数中,以摆脱对全局的需求,但它仍然不起作用。然后在设置了一些打印后,我意识到当您单击多个框时,board[] 会被完全重写,而不是仅仅分配一个值并保留该值。我该如何解决这些问题?点击 2 个不同的方块后查看控制台,以获得更清晰的图片。

import turtle

from turtle import *

pen = turtle.Turtle()
pen.speed(0)
setup(601,601)
#Creating Menu option buttons
def button(length):
    for i in range(4):
        pen.forward(length)
        pen.left(90)

def column(n, length):
    pen.penup()
    pen.goto(-100,250)
    pen.pendown()
    pen.left(270)
    for i in range(n):
        button(length)
        pen.forward(length)
    pen.penup()
    pen.left(90)
    pen.forward(n * length)
    pen.left(180)
    pen.pendown()

column(5, 100)

#Menu Options
pen.penup()
pen.goto(-100, 190)
pen.write("START GAME", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-75, 90)
pen.write("RULES", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-97, -10)
pen.write("HIGH SCORE", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-65, -110)
pen.write("FAQ", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-93, -210)
pen.write("QUIT GAME", font=("Arial",12,"normal"))


def runGame():
    pen = turtle.Turtle()
    speed(0)
    setup(1366,738)
    title("Group 3's tictactoe")
    pensize(15)


    #Rows
    def dRow():
        up()
        goto(-500,-100)
        down()
        forward(1000)
        up()
        goto(-500, 100)
        down()
        forward(1000)
    dRow()
    #columns
    def dCol():
        up()
        goto(-175,-400)
        left(90)
        down()
        forward(1000)
        up()
        goto(175, -400)
        down()
        forward(1000)
    dCol()

    #Win conditions
    def place(x,y):
        global turn
        #Creating Board
        board = ["","","",
                 "","","",
                 "","","",] 
        turn = "X"
        point = ""

        #create X's
        def Xs(x, y):
            up()
            goto(x+30, y-35)
            setheading(130)
            down()
            forward(100)
            up()
            goto(x+30, y+40)
            setheading(230)
            down()
            forward(100)
            up()
            print(x, y)

        #Create O's
        def Os(x, y):
            up()
            goto(x,y-80)
            setheading(0)
            down()
            circle(80)
            up()
            print(x, y)

        #Check what square was clicked and assign that an (x or O) value to that point
        if -526<x<-182 and 360>y>107:
            point = 0
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -168<x<167 and 360>y>107:
            point = 1
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif 182<x<504 and 360>y>107:
            point = 2
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -506<x<-184 and 92>y>-92:
            point = 3
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -167<x<167 and 92>y>-92:
            point = 4
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        elif 185<x<505 and 92>y>-92:
            point = 5
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -504<x<-182 and -108>y>-360:
            point = 6
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -167<x<166 and -108>y>-360:
            point = 7
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        elif 185<x<531 and -108>y>-360:
            point = 8
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        else:
            print("Do something")


        print("The current entire board is: ",board)

        def drawPieces(board):
            for piece in board:
                if piece == "X":
                    Xs(x,y)
                elif board == "O":
                    Os(x,y)

        def clicked(x,y):
            if board[0] == "X" and board[4] == "X" and board[8] == "X":
                style = ('Courier', 80, 'bold')
                write('You WIN!', font=style, align='center')
            else:
                global turn
                if turn == "X":
                    turn = "O"
                    drawPieces(board)
                else:
                    turn = "X"
                    drawPieces(board)
                print("This turn is: ",turn)
        clicked(x, y)



    onscreenclick(place)
    mainloop()

#Making options clickable
def btnclick(x,y):
    if -100 < x < 1 and 250 > y > 150:
        print("Start Game")
        print(x, y)
        turtle.clearscreen()
        runGame()

    elif -100 < x < 1 and 150 > y > 50:
        print("Rules")
        print(x, y)
        turtle.clearscreen()
        screen = turtle.Screen()
        answer = screen.textinput("Welcome to Our GAME!", "Whats your name?")

    elif -100 < x < 1 and 50 > y > -50:
        print("Highscore")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -50 > y > -150:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -150 > y > -250:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -250 > y > -350:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    else:
        print("Click One Of The Options!")
        print(x, y)



turtle.onscreenclick(btnclick, 1)
turtle.listen()

turtle.done()

【问题讨论】:

  • 经验丰富的编码人员给新编码人员的最常见建议之一是避免使用全局变量。关于为什么要避免它们,有很多冗长的解释,但它们都归结为“因为它们会导致错误发生”。如果您可以编写代码以不使用全局变量,则不会出现此错误。 :)

标签: python python-3.x turtle-graphics python-turtle


【解决方案1】:

您的代码中的主要问题是,每次调用 place 时都会初始化 boradturn

def place(x,y):
        global turn
        #Creating Board
        board = ["","","",
                 "","","",
                 "","","",] 
        turn = "X"
        point = ""

因此,每次新回合开始时,都会创建一个新棋盘并设置回合"X"

在全局命名空间中创建bordturn,并在place中使用:

#Creating Board
board = ["","","",
              "","","",
              "","","",] 
turn = "X"

def runGame():
    # [...]

    #Win conditions
    def place(x,y):
        global turn, board

        point = ""

        #create X's
        # [...]

此外,clicked 还存在一些问题。也可以在 clicked 中使用全局变量 boardturndrawPieces 根本不起作用,因为xy 永远不会改变,所有的部分都绘制在同一个位置。画出新的作品就足够了。分别由XsOsclicked 上绘制:

def runGame():
    # [...]

    #Win conditions
    def place(x,y):
        global turn, board

        point = ""
        # [...]

        def clicked(x,y):
            global board, turn
            if board[0] == "X" and board[4] == "X" and board[8] == "X":
                style = ('Courier', 80, 'bold')
                write('You WIN!', font=style, align='center')
            else:
                if turn == "X":
                    Xs(x,y)
                    turn = "O"
                else:
                    Os(x,y)
                    turn = "X"
                print("This turn is: ",turn)
        clicked(x, y)

完整代码:

import turtle

from turtle import *

pen = turtle.Turtle()
pen.speed(0)
setup(601,601)
#Creating Menu option buttons
def button(length):
    for i in range(4):
        pen.forward(length)
        pen.left(90)

def column(n, length):
    pen.penup()
    pen.goto(-100,250)
    pen.pendown()
    pen.left(270)
    for i in range(n):
        button(length)
        pen.forward(length)
    pen.penup()
    pen.left(90)
    pen.forward(n * length)
    pen.left(180)
    pen.pendown()

column(5, 100)

#Menu Options
pen.penup()
pen.goto(-100, 190)
pen.write("START GAME", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-75, 90)
pen.write("RULES", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-97, -10)
pen.write("HIGH SCORE", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-65, -110)
pen.write("FAQ", font=("Arial",12,"normal"))

pen.penup()
pen.goto(-93, -210)
pen.write("QUIT GAME", font=("Arial",12,"normal"))

#Creating Board
board = ["","","",
              "","","",
              "","","",] 
turn = "X"

def runGame():
    pen = turtle.Turtle()
    speed(0)
    setup(1366,738)
    title("Group 3's tictactoe")
    pensize(15)

    #Rows
    def dRow():
        up()
        goto(-500,-100)
        down()
        forward(1000)
        up()
        goto(-500, 100)
        down()
        forward(1000)
    dRow()
    #columns
    def dCol():
        up()
        goto(-175,-400)
        left(90)
        down()
        forward(1000)
        up()
        goto(175, -400)
        down()
        forward(1000)
    dCol()

    #Win conditions
    def place(x,y):
        global turn, board

        point = ""

        #create X's
        def Xs(x, y):
            up()
            goto(x+30, y-35)
            setheading(130)
            down()
            forward(100)
            up()
            goto(x+30, y+40)
            setheading(230)
            down()
            forward(100)
            up()
            print(x, y)

        #Create O's
        def Os(x, y):
            up()
            goto(x,y-80)
            setheading(0)
            down()
            circle(80)
            up()
            print(x, y)

        #Check what square was clicked and assign that an (x or O) value to that point
        if -526<x<-182 and 360>y>107:
            point = 0
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -168<x<167 and 360>y>107:
            point = 1
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif 182<x<504 and 360>y>107:
            point = 2
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -506<x<-184 and 92>y>-92:
            point = 3
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -167<x<167 and 92>y>-92:
            point = 4
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        elif 185<x<505 and 92>y>-92:
            point = 5
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -504<x<-182 and -108>y>-360:
            point = 6
            print("This is square: ",point)
            board[int(point)] = turn
            print("this board space is: ", board[point], board)
        elif -167<x<166 and -108>y>-360:
            point = 7
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        elif 185<x<531 and -108>y>-360:
            point = 8
            print("This is square: ",point)
            board[int(point)] = board[int(point)] + str(turn)
            print("this board space is: ", board[point], board)
        else:
            print("Do something")


        print("The current entire board is: ",board)

        def drawPieces(board):
            for piece in board:
                if piece == "X":
                    Xs(x,y)
                elif piece == "O":
                    Os(x,y)

        def clicked(x,y):
            global board, turn
            if board[0] == "X" and board[4] == "X" and board[8] == "X":
                style = ('Courier', 80, 'bold')
                write('You WIN!', font=style, align='center')
            else:
                if turn == "X":
                    Xs(x,y)
                    turn = "O"
                else:
                    Os(x,y)
                    turn = "X"
                print("This turn is: ",turn)
        clicked(x, y)



    onscreenclick(place)
    mainloop()

#Making options clickable
def btnclick(x,y):
    if -100 < x < 1 and 250 > y > 150:
        print("Start Game")
        print(x, y)
        turtle.clearscreen()
        runGame()

    elif -100 < x < 1 and 150 > y > 50:
        print("Rules")
        print(x, y)
        turtle.clearscreen()
        screen = turtle.Screen()
        answer = screen.textinput("Welcome to Our GAME!", "Whats your name?")

    elif -100 < x < 1 and 50 > y > -50:
        print("Highscore")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -50 > y > -150:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -150 > y > -250:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    elif -100 < x < 1 and -250 > y > -350:
        print("Hi")
        print(x, y)
        turtle.clearscreen()
    else:
        print("Click One Of The Options!")
        print(x, y)



turtle.onscreenclick(btnclick, 1)
turtle.listen()

turtle.done()

【讨论】:

  • 当我这样做时,我得到一个错误,说没有定义板,尽管已经将它声明为全局。 board[int(point)] = board[int(point)] + str(turn)
  • @TyrellReid 所以你做错了。当然,我已经测试了代码,它对我来说很好。我已将完整的代码添加到答案中。
  • 我明白了。现在可以了。我已经移动了棋盘并移出了位置(),但它们仍在运行游戏()中。所以要让全局变量正常工作,它们必须在任何其他函数之前声明?
  • @TyrellReid 必须先声明(设置)每个变量,然后才能读取它。答案甚至可以接受吗? (答案左侧的复选标记)。请阅读What should I do when someone answers my question?
猜你喜欢
  • 2018-04-19
  • 2010-10-20
  • 2011-06-10
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多