<p>这种逻辑对于一个基本的扫雷揭示算法来说似乎是杀伤力过大。一些想法:</p>
<ul>
<li>扫雷艇网格是有状态的,由多个变量和函数组成。类是将所有这些逻辑连接的变量和函数封装在单个实体中的典型构造。可以使用<code>__str__</code>方法打印电路板,并将网格传递给初始值设定项。不需要为了算法的目的而将网格字符串化,只在内部将其作为一个列表。你知道吗</li>
<li>在可见和不可见的两个单独列表中保留正方形是不可伸缩的。如果需要添加第三个属性,则必须创建另一个二维列表。考虑一个<code>Tile</code>类/recordtype/dict,其属性为<code>visible</code>,<code>status</code>/<code>contents</code>。这允许您将所有必需的网格数据存储在一个数据结构中。你知道吗</li>
<li>变量名始终不清楚。<code>wl</code>必须是board size,但这是多余的信息,因为列表已经有了一个<code>len</code>属性,该属性保证了一致性并具有语义意义。你知道吗</li>
<li>对所有变量和函数使用<code>snake_case</code>而不是<code>camelCase</code>。<code>UpperCamelCase</code>类名称。见<a href="https://www.python.org/dev/peps/pep-0008/" rel="nofollow noreferrer">PEP-8</a>。你知道吗</li>
<li>缩进4个空格;Python没有<code>end</code>关键字或大括号,因此任何小于4个空格的块都很难消除歧义。你知道吗</li>
<li>不要将<code>try</code>/<code>except</code>块用于易于转换为条件的逻辑,尤其是在使用<a href="https://wiki.c2.com/?PokemonExceptionHandling" rel="nofollow noreferrer">Pokemon exceptions</a>时。您可能无意中抑制了非预期的错误,这是对不是为通用控制流设计的构造的滥用。你知道吗</li>
<li>使用iterables和loops,而不是长序列的手工输入的条件句,这些条件句很难理解,而且容易出错。你知道吗</li>
<li>使用<code>yReal = y-1; xReal = x-1</code>在1索引“人类”坐标和0索引坐标之间进行转换可能会导致混淆,因为它是在每一帧上递归执行的。如果必须这样做,请将逻辑移出算法,并尽可能靠近IO接口进行规范化/反规范化。你知道吗</li>
</ul>
<p>这里有一个重写建议:</p>
<pre><code>class Minesweeper:
class Tile:
def __init__(self, mark, visible=False):
self.mark = mark
self.visible = visible
def __str__(self):
return self.mark if self.visible else "-"
neighbors = [(x, y) for x in range(-1, 2)
for y in range(-1, 2) if x or y]
def __init__(self, field):
self.field = [[self.Tile(x) for x in row] for row in field]
def in_bounds(self, x, y):
return y >= 0 and y < len(self.field) and \
x >= 0 and x < len(self.field[y])
def reveal(self, x, y):
if self.in_bounds(x, y) and not self.field[y][x].visible and \
self.field[y][x].mark == "0":
self.field[y][x].visible = True
for dx, dy in self.neighbors:
self.reveal(x + dx, y + dy)
def __str__(self):
return "".join("".join(map(str, row)) + "\n" for row in self.field)
if __name__ == "__main__":
field = [
"00000",
"12210",
"1XX10",
]
board = Minesweeper(field)
print board
board.reveal(3, 0)
print board
</code></pre>
<p>输出:</p>
<pre class="lang-none prettyprint-override"><code> -
-
-
00000
0
0
</code></pre>