我正在用Python开发Minesweeper。我已经完成了所有代码并可以正常工作,但是我想补充的一个功能是,当您打开附近有零个地雷的瓷砖时,它会打开周围的所有方块。问题源于以下事实:如果我打开的任何一个盒子也都是零,那么他们还需要打开它们周围的所有盒子。我相信我可以执行此操作,但是总是可以达到最大递归深度。我试图将限制提高到可能比我应有的更高,但仍然出现错误。我想知道他们是否是无需太多递归的另一种方式。感谢您的帮助,这是我当前的代码:
def open_zero(x):
# For opening the boxes with no nearby mines
# First, opens the box the user clicked on
button_list[x].config(bg="#90949b")
# Then opens all nearby boxes through the box_open function
# I need to run these values through the function so that if they are
# zero, they will open all nearby tiles as well.
# This causes too much recursion.
box_open(x+1)
box_open(x-1)
box_open(x+width)
box_open(x+width+1)
box_open(x+width-1)
box_open(x-width)
box_open(x-width-1)
box_open(x-width+1)
def box_open(x):
if box_list[x] == "M":
# Checks if the block is a mine
button_list[x].config(image=photo_mine, relief = SUNKEN)
# Stops if it was a mine
button_frame.destroy()
all_code()
elif box_list[x] == 0:
# If there are no nearby mines, open all nearby tiles.
open_zero(x)
else:
# If not a mine, change button text to the amount of nearby mines.
button_list[x].config(text=box_list[x], bg="#90949b")
希望您可以从此代码片段中了解我的代码。用我的编码方式可能是不可能的,但是如果有人有任何想法,我很想听听他们的想法。谢谢您的帮助!
答案 0 :(得分:3)
您可以使用 queue 。在Python中,这可能以list
的形式出现。使用.append()
使项目入队,使用.pop()
使项目出队。 (请注意,您不需要使用队列。您可以使用堆栈或普通列表,但是队列将模拟从点击中心散布的单元格,如果您想到一些简洁的动画,这可能会有所帮助。)
## TODO check over this implementation
def is_open(x):
return button_list[x].bg == "#90949b"
def open_zero(x):
button_list[x].config(bg="#90949b")
queue = [x] ## init
while queue:
curr = queue.pop(0) ## dequeue cells here
if is_open(curr): ## STOPPING CONDITION [1]
continue
box_open(curr)
if box_list[curr] != 0: ## checks if curr is a zero-cell, you've already implemented this previously
continue
## enqueue nearby cells here
# if curr >= width: ## STOPPING CONDITION(s) [2]
queue.append(curr+1) ## TODO check curr isn't on the right edge
queue.append(curr-1) ## TODO check curr isn't on the left edge
queue.append(curr+width) ## TODO check curr isn't on the bottom edge
queue.append(curr+width-1) ## ...
queue.append(curr+width+1) ## ... the rest has been left as an
queue.append(curr-width) ## ... exercise for the reader
queue.append(curr-width-1)
queue.append(curr-width+1)
## NOTE: without STOPPING CONDITION(s), recursion or the while-loop
## will never terminate
## except for the max-recursion depth
请注意,Python会对代码中的递归感到不满的原因之一是,您没有提供任何停止或终止条件。我无法强调这些的重要性。我已经部分实现了其中一个条件(is_open(x)
,它检查单元格x
是否打开)。
由于这是扫雷器,我假设您正在矩阵/网格上进行此操作(但将按钮存储在列表中)。不过,您仍然需要检查网格的边界,否则您的递归会跳过网格壁或做其他奇怪的事情。
(想法实验:想象一下,单击网格的左下角单元。这将触发box_open(x)
。这又将触发box_open(x-1)
或queue.append(curr-1)
。 ,但是它们会打开位于底部第二行中的最右边的单元格。这是意外的。您需要检查该单元格不在左侧...执行{{1 }}。)
我高度确信您的原始代码可以工作,但是递归(或任何循环)的重要关键要素之一就是提供停止/终止条件。除了队列的实现,这应该是每个人的主要收获。