在Python turtle检查事件时进行管理

在Python turtle检查事件时进行管理,python,event-handling,turtle-graphics,Python,Event Handling,Turtle Graphics,我正在使用Python海龟图形创建一个Connect 4游戏。出现的主要问题是,当您使用诸如onkey或onclick之类的事件时,会立即检查它们,然后检查代码的其余部分。有没有一种方法可以暂停代码,直到事件发生,然后继续,在循环之后,等待另一个事件发生 在下面的代码中,游戏得到设置,然后运行play()函数。在play()。然后,它开始在水平、垂直或对角方向上检查一行中的4。它创建了一个错误,因为列列表是空的,直到我按下向下键将一个片段放入电路板的一列并将该片段附加到该列。我可以创建已经填充了

我正在使用Python海龟图形创建一个Connect 4游戏。出现的主要问题是,当您使用诸如
onkey
onclick
之类的事件时,会立即检查它们,然后检查代码的其余部分。有没有一种方法可以暂停代码,直到事件发生,然后继续,在循环之后,等待另一个事件发生

在下面的代码中,游戏得到设置,然后运行
play()
函数。在
play()。然后,它开始在水平、垂直或对角方向上检查一行中的4。它创建了一个错误,因为列列表是空的,直到我按下向下键将一个片段放入电路板的一列并将该片段附加到该列。我可以创建已经填充了
None
'
或零的列,但随后我必须更改我的drop函数的工作方式,因为它当前基于列表中项目数的y值。是否有一种方法可以在每件物品掉落后只运行一次检查功能

另外,我对编码比较陌生,这是我第一次使用这个网站。我已复制并粘贴了以下代码:

import turtle
class Connect4:
  "A connect 4 game"
  def __init__(self):
    self.pen = turtle.Turtle()
    self.scr = turtle.Screen()
    self.board = Connect4Board(self.pen, self.scr)
    self.moves = 0
    self.playing = True
    self.piece = Connect4Piece(self.scr, self.board, self)

    self.setup()
    self.play()

  def setup(self):
    self.board.draw_board()

  def play(self):
    if self.moves == self.board.rows*self.board.columns:
      game_over()
    self.piece.st()
    self.piece.goto(0, self.board.board_height/2)
    while True:

      self.scr.onkey(self.piece.prev_col, 'Left')
      self.scr.onkey(self.piece.next_col, 'Right')
      self.scr.onkey(self.piece.drop, 'Down')
      self.scr.onkey(self.reset, 'r')
      self.scr.listen()
      self.check()

  "Check if there is 4 pieces in a line horizontally, vertically or diagonally"
  def check(self):
    self.check_horizontal()
    self.check_vertical()
    self.check_diagonal()

  def check_horizontal(self):
    print("Checking horizontally")
    for rows in range(self.board.rows):
      for columns in range(self.board.columns - 3):
        if self.board.squares[columns][rows] == 0:
          continue
        elif (self.board.squares[columns][rows] == self.board.squares[columns+1][rows] == self.board.squares[columns+2][rows] == self.board.squares[columns+3][rows]):
          print(self.board.squares[columns][rows].color())
          if self.board.squares[columns][rows].color() == ('red','red'):
            print("Red wins!")
          if self.board.squares[columns][rows].color() == ('black','black'):
            print("Black wins!")

  def check_vertical(self):
    print("Checking vertically")

  def check_diagonal(self):
    print("Checking diagonally")

  def reset(self):

    self.board.reset()
    self.piece.clear()

    self.moves = 0
    self.play()

  def game_over(self):
    self.pen.pu()
    self.pen.goto(0, board_height/2 + 20)
    self.pen.pd()
    self.pen.write("Black wins!", align='center', font = ('Arial', 24, 'normal'))
    self.pen.pu()
    to.goto(0, board_height/2 + 10)
    self.pen.write("Play Again?", align='center', font = ('Arial', 24, 'normal'))
    self.playing = False

class Connect4Board:
  def __init__(self, pen, screen):
      #Used to create the board
    self.square_size = 60
    self.rows = 6
    self.columns = 7
    self.pen = pen
    self.frame_color = 'blue'
    self.board_length = self.square_size*self.columns
    self.board_height = self.square_size*self.rows
    self.squares = [[] for cols in range(self.columns)] 
    """for cols in range(self.columns):
      empty = []
      self.squares.append(empty)"""

    self.pen.speed(0)
    self.pen.ht()

  def _draw_square(self, x, y):
    self.pen.pu()
    self.pen.goto(x-self.square_size/2, y-self.square_size/2)
    self.pen.pd()
    self.pen.fillcolor(self.frame_color)
    self.pen.begin_fill()
    for sides in range(4):
      self.pen.fd(self.square_size)
      self.pen.left(90)
    self.pen.end_fill()

  def _draw_circle(self, x, y):
    self.pen.pu()
    self.pen.goto(x, y)
    self.pen.pd()
    self.pen.fillcolor('white')
    self.pen.begin_fill()
    self.pen.circle(self.square_size/2)
    self.pen.end_fill()

  def draw_board(self):
    for row in range(self.rows):
      for col in range(self.columns):
        x = col*self.square_size - self.board_length/2 + self.square_size/2
        y = row*self.square_size - self.board_length/2
        self._draw_square(x, y)
        self._draw_circle(x, y - self.square_size/2)

  def reset(self):
    self.squares = []
    for cols in range(self.columns):
      empty = []
      self.squares.append(empty)

class Connect4Piece(turtle.Turtle):

  def __init__(self, screen, board, game):
    turtle.Turtle.__init__(self, screen)
    self.board = board
    self.speed(0)
    self.pu()
    self.shape('turtle')
    self.cnum = 3
    self.game = game
    self.ht()

  "Moves the piece to the left and updates it's column number"
  def prev_col(self):
    if self.xcor() - self.board.square_size > -self.board.board_length/2:
      self.setx(self.xcor() - self.board.square_size)
      self.cnum -= 1

  "Moves the piece to the right and updates it's column number"
  def next_col(self):
    if self.xcor() + self.board.square_size < self.board.board_length/2:
      self.setx(self.xcor() + self.board.square_size)
      self.cnum += 1

  def drop(self):
    "Make sure the column isn't full. If it's not then move the turtle to the next available space in the row."
    if len(self.board.squares[self.cnum]) != self.board.rows:
      self.sety(len(self.board.squares[self.cnum])              *self.board.square_size - self.board.board_height/2 - self.board.square_size/2 )

      "Stamp an image of the turtle to represent placing a piece"
      self.stamp()
      self.board.squares[self.cnum].append(self.color())

      "Move the piece back above the middle column and set it's column back to 3"
      self.goto(0, self.board.board_height/2)
      self.cnum = 3

      "Change the piece's color"
      if self.color() == ('red','red'):
        self.color('black')
      else:
        self.color('red')

      self.game.moves += 1
      print(self.game.moves, "moves")

game = Connect4()
导入海龟
类别4:
“连接4游戏”
定义初始化(自):
self.pen=turtle.turtle()
self.scr=turtle.Screen()
self.board=Connect4Board(self.pen、self.scr)
self.moves=0
自弹=真
self.piece=连接件4(self.scr、self.board、self)
self.setup()
self.play()
def设置(自):
self.board.draw_board()
def播放(自我):
如果self.moves==self.board.rows*self.board.columns:
游戏结束
self.piece.st()
self.piece.goto(0,self.board.board_高度/2)
尽管如此:
self.scr.onkey(self.piece.prev_col,“左”)
self.scr.onkey(self.piece.next_col,‘右’)
self.scr.onkey(self.piece.drop,“Down”)
self.scr.on键(self.reset,'r')
self.scr.listen()
self.check()
“检查一行中是否有4个部件水平、垂直或对角”
def检查(自我):
自我检查水平()
自我检查_垂直()
自我检查(对角线)
def检查_水平(自):
打印(“水平检查”)
对于范围内的行(self.board.rows):
对于范围内的列(self.board.columns-3):
如果self.board.squares[列][行]==0:
持续
elif(self.board.squares[列][行]==self.board.squares[列+1][行]==self.board.squares[列+2][行]==self.board.squares[列+3][行]:
打印(self.board.squares[列][行].color())
如果self.board.squares[列][行].color()==('red','red'):
打印(“红色胜利!”)
如果self.board.squares[列][行].color()==('black','black'):
打印(“黑赢!”)
def检查_垂直(自):
打印(“垂直检查”)
def检查(自):
打印(“对角检查”)
def重置(自):
self.board.reset()
self.piece.clear()
self.moves=0
self.play()
def游戏结束(自我):
self.pen.pu()
self.pen.goto(0,板高/2+20)
self.pen.pd()
self.pen.write(“黑色获胜!”,align='center',font=('Arial',24',normal'))
self.pen.pu()
to.goto(0,板高度/2+10)
self.pen.write(“再次播放?”,align='center',font=('Arial',24',normal'))
自我表现=错误
类别Connect4Board:
定义初始化(自身、笔、屏幕):
#用于创建板
自平方_尺寸=60
self.rows=6
self.columns=7
self.pen=钢笔
self.frame_color='blue'
self.board_length=self.square_size*self.columns
self.board_高度=self.square_尺寸*self.rows
self.squares=[]表示范围内的列(self.columns)]
“”用于范围内的列(self.columns):
空=[]
self.squares.append(空)“”
自动笔速度(0)
self.pen.ht()
def_绘制正方形(自、x、y):
self.pen.pu()
self.pen.goto(x-self.square\u size/2,y-self.square\u size/2)
self.pen.pd()
self.pen.fillcolor(self.frame\u颜色)
self.pen.begin\u fill()
对于范围(4)内的侧面:
self.pen.fd(self.square_大小)
左自记笔(90)
self.pen.end_fill()
定义绘制圆(自、x、y):
self.pen.pu()
self.pen.goto(x,y)
self.pen.pd()
self.pen.fillcolor('白色')
self.pen.begin\u fill()
自记笔圆圈(自记正方形尺寸/2)
self.pen.end_fill()
def牵引板(自):
对于范围内的行(self.rows):
对于范围内的列(自列):
x=col*self.square\u尺寸-self.board\u长度/2+self.square\u尺寸/2
y=行*self.square\u尺寸-self.board\u长度/2
自绘制正方形(x,y)
自成圆圈(x,y-自成正方形大小/2)
def重置(自):
self.squares=[]
对于范围内的列(self.columns):
空=[]
self.squares.append(空)
类连接件4件(turtle.turtle):
定义初始(自我、屏幕、棋盘、游戏):
乌龟。乌龟。初始化(自我,屏幕)
self.board=board
自身速度(0)
self.pu()
self.shape(‘海龟’)
self.cnum=3
self.game=游戏
self.ht()
“将工件向左移动并更新其列号”
def prev_col(自身):
如果self.xcor()-self.board.square\u size>-self.board.board\u length/2:
self.setx(self.xcor()-self.board.square_size)
self.cnum-=1
“将工件向右移动并更新其列号”
def next_col(自我):
如果self.xcor()+self.board.square_尺寸while True:

  self.scr.onkey(self.piece.prev_col, 'Left')
  self.scr.onkey(self.piece.next_col, 'Right')
  self.scr.onkey(self.piece.drop, 'Down')
  self.scr.onkey(self.reset, 'r')
  self.scr.listen()
  self.check()
from turtle import Turtle, Screen

class Connect4:
    "A connect 4 game"

    def __init__(self, screen):
        self.pen = Turtle()
        self.scr = screen
        self.board = Connect4Board(self.pen)
        self.moves = 0
        self.playing = False
        self.piece = Connect4Piece(self.board, self)

        self.scr.tracer(False)
        self.board.draw_board()
        self.scr.tracer(True)

        self.scr.onkey(self.piece.prev_col, 'Left')
        self.scr.onkey(self.piece.next_col, 'Right')
        self.scr.onkey(self.piece.drop, 'Down')
        self.scr.onkey(self.reset, 'r')

        self.scr.listen()

    def play(self):

        self.piece.showturtle()
        self.piece.goto(0, self.board.board_height/2)
        self.playing = True

    def check(self):
        "Check if there are 4 pieces in a line horizontally, vertically or diagonally"

        if self.moves == self.board.rows * self.board.columns:
            self.game_over()

        if self.check_horizontal():
            self.game_over()

        if self.check_vertical():
            self.game_over()

        if self.check_diagonal():
            self.game_over()

    def check_horizontal(self):
        print("Checking horizontally")

        # implement this correctly

        return False

    def check_vertical(self):
        print("Checking vertically")

        # implement this

        return False

    def check_diagonal(self):
        print("Checking diagonally")

        # implement this

        return False

    def reset(self):

        self.playing = False

        self.board.reset()
        self.piece.clear()

        self.moves = 0
        self.play()

    def game_over(self):
        self.playing = False
        self.pen.penup()
        self.pen.goto(0, self.board.board_height/2 + 20)
        self.pen.pendown()
        self.pen.write("Black wins!", align='center', font=('Arial', 24, 'normal'))
        self.pen.penup()
        self.pen.goto(0, self.board.board_height/2 + 10)
        self.pen.write("Play Again?", align='center', font=('Arial', 24, 'normal'))

class Connect4Board:
    def __init__(self, pen):
        # Used to create the board
        self.square_size = 60
        self.rows = 6
        self.columns = 7
        self.pen = pen
        self.frame_color = 'blue'
        self.board_length = self.square_size * self.columns
        self.board_height = self.square_size * self.rows
        self.squares = [[] for _ in range(self.columns)]

        self.pen.speed('fastest')
        self.pen.hideturtle()

    def _draw_square(self, x, y):
        self.pen.penup()
        self.pen.goto(x - self.square_size/2, y - self.square_size/2)
        self.pen.pendown()
        self.pen.fillcolor(self.frame_color)

        self.pen.begin_fill()
        for _ in range(4):
            self.pen.forward(self.square_size)
            self.pen.left(90)
        self.pen.end_fill()

    def _draw_circle(self, x, y):
        self.pen.penup()
        self.pen.goto(x, y)
        self.pen.pendown()
        self.pen.fillcolor('white')

        self.pen.begin_fill()
        self.pen.circle(self.square_size/2)
        self.pen.end_fill()

    def draw_board(self):
        for row in range(self.rows):
            for col in range(self.columns):
                x = col * self.square_size - self.board_length/2 + self.square_size/2
                y = row * self.square_size - self.board_length/2
                self._draw_square(x, y)
                self._draw_circle(x, y - self.square_size/2)

    def reset(self):
        self.squares = [[] for _ in range(self.columns)]

class Connect4Piece(Turtle):

    def __init__(self, board, game):
        super().__init__(shape='turtle', visible=False)
        self.board = board
        self.game = game
        self.speed('fastest')
        self.penup()
        self.cnum = 3

    def prev_col(self):
        "Moves the piece to the left and updates it's column number"

        if self.xcor() - self.board.square_size > -self.board.board_length/2:
            self.setx(self.xcor() - self.board.square_size)
            self.cnum -= 1

    def next_col(self):
        "Moves the piece to the right and updates it's column number"

        if self.xcor() + self.board.square_size < self.board.board_length/2:
            self.setx(self.xcor() + self.board.square_size)
            self.cnum += 1

    def drop(self):
        "Make sure the column isn't full. If it's not then move the turtle to the next available space in the row."

        if len(self.board.squares[self.cnum]) != self.board.rows:
            self.sety(len(self.board.squares[self.cnum]) * self.board.square_size - self.board.board_height/2 - self.board.square_size/2)

            # Stamp an image of the turtle to represent placing a piece
            self.stamp()
            self.board.squares[self.cnum].append(self.color())

            # Move the piece back above the middle column and set it's column back to 3
            self.goto(0, self.board.board_height/2)
            self.cnum = 3

            # Change the piece's color
            self.color('black' if self.pencolor() == 'red' else 'red')

            self.game.moves += 1
            print(self.game.moves, "moves")

            self.game.check()

screen = Screen()

game = Connect4(screen)
game.play()

screen.mainloop()