【发布时间】:2018-06-19 23:40:19
【问题描述】:
我正在使用 Python 海龟图形创建一个 Connect 4 游戏。出现的主要问题是,当您使用onkey 或onclick 之类的事件时,会立即检查它们,然后是其余代码。有没有办法暂停代码,直到事件发生,然后继续,循环后,等待另一个事件发生?
在下面的代码中,游戏设置完毕,然后运行play() 函数。在play() 函数中,程序侦听onkey() 事件,这些事件允许用户更改它在哪一列结束,并在准备好时放下该片段。然后,它开始在水平、垂直或对角线上连续检查 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()
【问题讨论】:
-
请尝试做一个最小的例子,例如如果您要询问对事件的反应,请制作一个仅执行此操作的应用程序 - 如果这是重现问题的最低限度,则仅对一个事件或两个事件做出反应。然后问这个问题,这可能已经简单得多了。见How to create a Minimal, Complete, and Verifiable example。
标签: python event-handling turtle-graphics