我正在将Jupyter Notebook与python 3.7.1版一起使用,以使用tkinter软件包构建蛇游戏。好吧,这更像是从github复制其他人的代码,然后自己修改。目标是制作一个由系统玩10次的蛇游戏。因此,在完成第一个游戏后,tkinter框架将关闭,另一个将弹出并重复直到10次。问题在于,每次游戏结束并关闭框架时,系统都会发出警告,并且在进行5或6次迭代后,系统将强制停止并给出与警告相同的错误消息。
这是警告:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 749, in callit
func(*args)
File "<ipython-input-18-b0768e06fac0>", line 132, in tick
self.render()
File "<ipython-input-18-b0768e06fac0>", line 95, in render
self.canvas.delete(tkinter.ALL)
File "C:\Users\user\Anaconda3\lib\tkinter\__init__.py", line 2514, in delete
self.tk.call((self._w, 'delete') + args)
_tkinter.TclError: invalid command name ".!frame.!canvas"
这是使系统强制停止进程的错误消息:
TclError Traceback (most recent call last)
<ipython-input-22-d3ce3af75353> in <module>
1 bots = []
2 for i in range(0, 10):
----> 3 bots.append(snake_bot((i + 1), 10))
<ipython-input-18-b0768e06fac0> in __init__(self, bot_id, speed)
75 self.direction = random.choice(availabel_directions)
76
---> 77 self.start()
78
79 def draw_rect(self, x, y, color='#00f'):
<ipython-input-18-b0768e06fac0> in start(self)
134
135 def start(self):
--> 136 self.tick()
137 self.window.mainloop()
138
<ipython-input-18-b0768e06fac0> in tick(self)
130 self.move_snake(self.direction)
131 self.check_food()
--> 132 self.render()
133 self.window.after(int(1000 / self.speed), self.tick)
134
<ipython-input-18-b0768e06fac0> in render(self)
93
94 def render(self):
---> 95 self.canvas.delete(tkinter.ALL)
96
97 for x in range(0, self.X):
~\Anaconda3\lib\tkinter\__init__.py in delete(self, *args)
2512 def delete(self, *args):
2513 """Delete items identified by all tag or ids contained in ARGS."""
-> 2514 self.tk.call((self._w, 'delete') + args)
2515 def dtag(self, *args):
2516 """Delete tag or id given as last arguments in ARGS from items
TclError: invalid command name ".!frame.!canvas"
这是我修改过的代码:
from tkinter import Tk, Canvas, Frame, BOTH
import tkinter
from collections import deque
from random import randint
import random
from IPython.display import clear_output
class snake_bot():
def __init__(self, bot_id, speed):
#
self.bot_id = bot_id
self.speed = speed
self.X = 30
self.Y = 20
self.BLOCK_SIZE = 20
self.window = Tk()
self.window.geometry('{}x{}'.format(self.X * self.BLOCK_SIZE, self.Y * self.BLOCK_SIZE))
self.window.resizable(False, False)
self.frame = Frame(self.window)
self.frame.master.title('Snake Bot - ID - ' +str(self.bot_id))
self.frame.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self.frame)
self.canvas.pack(fill=BOTH, expand=1)
self.VALID_DIRECTIONS = {
'Left': set(('Up', 'Down')),
'Right': set(('Up', 'Down')),
'Up': set(('Left', 'Right')),
'Down': set(('Left', 'Right'))
}
self.MOVEMENTS = {
'Left': lambda x, y: (x - 1, y),
'Right': lambda x, y: (x + 1, y),
'Up': lambda x, y: (x, y - 1),
'Down': lambda x, y: (x, y + 1)
}
self.score = 0
randX = randint(0, (self.X - 2))
randY = randint(0, (self.Y - 2))
coin_flip = randint(1, 2)
if(coin_flip == 1):
#X
coin_flip = randint(1, 2)
if(coin_flip == 1):
#-
self.snake = deque(((randX, randY), ((randX-1), randY)))
else:
#+
self.snake = deque(((randX, randY), ((randX+1), randY)))
else:
#Y
coin_flip = randint(1, 2)
if(coin_flip == 1):
#-
self.snake = deque(((randX, randY), (randX, (randY-1))))
else:
#+
self.snake = deque(((randX, randY), (randX, (randY+1))))
in_s = True
while(in_s == True):
self.food = (randint(0, (self.X - 1)), randint(0, (self.Y - 1)))
if self.food not in self.snake:
in_s = False
self.moves = deque()
availabel_directions = ['Down', 'Up', 'Right', 'Left']
self.direction = random.choice(availabel_directions)
self.start()
def draw_rect(self, x, y, color='#00f'):
self.x1 = x * self.BLOCK_SIZE
self.y1 = y * self.BLOCK_SIZE
self.x2 = self.x1 + self.BLOCK_SIZE
self.y2 = self.y1 + self.BLOCK_SIZE
return self.canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill=color)
def draw_background(self, x, y):
self.x1 = x * self.BLOCK_SIZE
self.y1 = y * self.BLOCK_SIZE
self.x2 = self.x1 + self.BLOCK_SIZE
self.y2 = self.y1 + self.BLOCK_SIZE
return self.canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill='white')
def render(self):
self.canvas.delete(tkinter.ALL)
for x in range(0, self.X):
for y in range(0, self.Y):
self.draw_background(x, y)
for self.x, self.y in self.snake:
self.draw_rect(self.x, self.y, color='#00f')
self.x, self.y = self.food
self.draw_rect(self.x, self.y, color='#f00')
def create_food(self):
self.s = set(self.snake)
while True:
self.food = randint(0, self.X - 1), randint(0, self.Y - 1)
if self.food not in self.s:
return self.food
def check_food(self):
self.s = set(self.snake)
if self.food in self.s:
self.increase_score()
self.food = self.create_food()
else:
self.snake.popleft()
def random_direction(self):
self._direction = self.moves[-1] if self.moves else self.direction
availabel_directions = ['Down', 'Up', 'Right', 'Left']
self.key = random.choice(availabel_directions)
if self.key in self.VALID_DIRECTIONS[self._direction]:
self.moves.append(self.key)
def tick(self):
self.random_direction()
self.direction = self.moves.popleft() if self.moves else self.direction
self.move_snake(self.direction)
self.check_food()
self.render()
self.window.after(int(1000 / self.speed), self.tick)
def start(self):
self.tick()
self.window.mainloop()
def increase_score(self):
self.score += 1
if not self.score % 5:
# increase speed after the snake eats 5 times
self.speed += 2
clear_output()
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
def move_snake(self, direction):
self.x, self.y = self.snake[-1]
self.next_point = self.MOVEMENTS[self.direction](self.x, self.y)
self.s = set(self.snake)
if self.next_point in self.s:
self.window.destroy()
clear_output()
print('You just ate yourself')
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
if self.x < 0 or self.x >= self.X or self.y < 0 or self.y >= self.Y:
self.window.destroy()
clear_output()
print('You crashed into a wall')
print('ID - ', self.bot_id, 'score:', self.score, 'speed:', self.speed)
self.snake.append(self.next_point)
bots = []
for i in range(0, 10):
bots.append(snake_bot((i + 1), 10))
我试图找到解决方案,但直到现在我仍然被困住。我希望有人可以帮助我找到解决该问题的方法。提前谢谢你
答案 0 :(得分:0)
我认为问题在于您无法真正控制self.windows和
self.canvas存在。
我做了两个更改,现在脚本显然可以工作了。。。显然是!!
SELECT SUM(trans_value) total, bectrn_id, becat_id
FROM brvo_bemrc_transactions
WHERE year = p_year
AND trn_type = p_trntype
AND doc_type = p_doctype
AND company = p_company
AND bedfn_id = p_bedfn_id
AND bectrn_id = v_bectrn_id
AND becat_id = v_becat_id
AND extract(year from last_update_date) = p_year - 1
AND mod(to_number(to_char(last_update_date, 'q')), 4) + 1 = to_number(to_char(sysdate, 'q'))
GROUP BY bectrn_id, becat_id
ORDER BY bectrn_id, becat_id;
在这里
def render(self):
try:
self.canvas.delete(tkinter.ALL)
for x in range(0, self.X):
for y in range(0, self.Y):
self.draw_background(x, y)
for self.x, self.y in self.snake:
self.draw_rect(self.x, self.y, color='#00f')
self.x, self.y = self.food
self.draw_rect(self.x, self.y, color='#f00')
except:
pass
我明白了
你只是吃了饭
ID-1分:0速度:10
你只是吃了饭
ID-2分:0速度:10
你撞到墙上
ID-3分:0速度:10
你撞到墙上
ID-4分:1速度:10
你撞到墙上
ID-5分:0速度:10
你撞到墙上
ID-6得分:0速度:10
你撞到墙上
ID-7分:0速度:10
你撞到墙上
ID-8分:1速度:10
你只是吃了饭
ID-9得分:0速度:10
你撞到墙上
ID-10分:0速度:10