我在为我正在制作的扫雷游戏做一个函数。此函数的目的是显示给定x和y的元素(元素所在的位置)。这可能不是实现它的最优雅的方法,但是我为每个标题为newField
的tile创建了一个['-']列表。一个“-”代表一个隐藏的块(你不知道它是不是一个炸弹或者它周围有多少炸弹)。然后,我将newField
中的一个元素更改为等于listField
(列表列表)中相应的块。其中的每个列表表示一行)。一个X代表一颗炸弹,数字代表有多少颗炸弹环绕在这个区域。你知道吗
在扫雷艇中,当一个周围没有炸弹的街区被发现时,它周围的街区也会被发现。我做了一个名为revealSurroundings
的函数来实现这一点。当我像下面那样在函数revealElement
中运行revealSurroundings
时,它会冻结我的计算机。但是,如果我在函数revealElement
之外运行revealSurroundings
,它就可以正常工作。你知道吗
如果有人对如何解决这个问题和/或提高效率有任何建议(因为我知道我使用的方法非常昂贵),请告诉我。你知道吗
wl = 10
listField =
[['1', '1', '0', '0', '0', '0', '0', '0', '1', 'X'],
['X', '2', '2', '2', '2', '2', '2', '1', '1', '1'],
['1', '2', 'X', 'X', '2', 'X', 'X', '2', '2', '2'],
['1', '2', '3', '2', '2', '2', '3', '4', 'X', 'X'],
['1', 'X', '1', '0', '0', '1', '3', 'X', 'X', '3'],
['1', '2', '2', '1', '0', '1', 'X', 'X', '4', '2'],
['2', '3', 'X', '1', '0', '1', '2', '2', '2', 'X'],
['X', 'X', '2', '1', '1', '1', '1', '0', '1', '1'],
['4', '5', '4', '3', '3', 'X', '2', '1', '0', '0'],
['X', 'X', 'X', 'X', 'X', '3', 'X', '1', '0', '0']]
hiddenField = ['-' for i in range(wl*wl)]
def removeN(ls, n, iterations):
items = ls
try:
for i in range(iterations):
items.remove(n)
except:
pass
return items
def revealElement(wl, x, y, userField):
yReal = y-1
xReal = x-1
newField = list(userField)
removeN(newField, '\n', wl-1)
newField[yReal*wl + xReal] = listField[yReal][xReal]
if newField[yReal*wl + xReal] == '0':
revealSurroundings(wl, x, y, userField)
for i in range(wl-1, 0, -1): # go backwards
newField.insert(wl*i, '\n')
return "".join(newField) # make it a string
def revealSurroundings(wl, x, y, userField):
yReal = y-1
xReal = x-1
newField = userField
try:
newField = revealElement(wl, x+1, y, newField)
except:
pass
#right
try:
if xReal != 0:
newField = revealElement(wl, x-1, y, newField)
except:
pass
#left
try:
if yReal != 0:
newField = revealElement(wl, x, y-1, newField)
except:
pass
#up
try:
newField = revealElement(wl, x, y+1, newField)
except:
pass
#down
try:
if yReal != 0:
newField = revealElement(wl, x+1, y-1, newField)
except:
pass
#upper-right
try:
if yReal != 0 and xReal != 0:
newField = revealElement(wl, x-1, y-1, newField)
except:
pass
#upper left
try:
newField = revealElement(wl, x+1, y+1, newField)
except:
pass
#bottom-right
try:
if xReal != 0:
newField= revealElement(wl, x-1, y+1, newField)
except:
pass
#bottom-left
return newField
print revealSurroundings(10, 7, 2, hiddenField)
问题似乎是,当您在
revealElement
中运行revealSurroundings
时,您正在创建一个永无止境的循环。你知道吗运行
revealElement
时,如果元素为0,则运行函数revealSurroundings
。在revealSurroundings
内运行revealElement
。如果显示的新元素也是零,它将再次运行revealSurroundings
,并从revealElement
的第一次迭代中检测零。你知道吗这开始了一个无限循环,永不结束。我建议在
revealSurroundings
中添加另一个条件,比如检查是否已经通过简单的if语句显示了它旁边的字符。我还建议完全重新编写代码,因为@gorlen所说的。你知道吗这种逻辑对于一个基本的扫雷揭示算法来说似乎是杀伤力过大。一些想法:
__str__
方法打印电路板,并将网格传递给初始值设定项。不需要为了算法的目的而将网格字符串化,只在内部将其作为一个列表。你知道吗Tile
类/recordtype/dict,其属性为visible
,status
/contents
。这允许您将所有必需的网格数据存储在一个数据结构中。你知道吗wl
必须是board size,但这是多余的信息,因为列表已经有了一个len
属性,该属性保证了一致性并具有语义意义。你知道吗snake_case
而不是camelCase
。UpperCamelCase
类名称。见PEP-8。你知道吗end
关键字或大括号,因此任何小于4个空格的块都很难消除歧义。你知道吗try
/except
块用于易于转换为条件的逻辑,尤其是在使用Pokemon exceptions时。您可能无意中抑制了非预期的错误,这是对不是为通用控制流设计的构造的滥用。你知道吗yReal = y-1; xReal = x-1
在1索引“人类”坐标和0索引坐标之间进行转换可能会导致混淆,因为它是在每一帧上递归执行的。如果必须这样做,请将逻辑移出算法,并尽可能靠近IO接口进行规范化/反规范化。你知道吗这里有一个重写建议:
输出:
相关问题 更多 >
编程相关推荐