<p>我不确定它是如何工作的,因为<code>placeQueen</code>从未被调用。因此,我不认为添加一个打印建议提出了一个成品板(我认为它是空的)。<em>[注意:最新更新修复了此问题]</em></p>
<p>使用受限正方形的思想可以工作,但是这里实现它的方式(没有撤销选项)是低效的;为每个内部循环复制一个全新的<code>Board</code>对象是非常昂贵的。尽管有这么多麻烦,我们还是可以在每次移动时执行一次迭代冲突检查,这样至少可以节省新堆对象的分配和垃圾收集成本。你知道吗</p>
<p>至于返回完成的线路板结果,在失败时使用返回值<code>self</code>或<code>self.board</code>和<code>None</code>,而不是<code>True</code>和<code>False</code>。你知道吗</p>
<p>其他几点:</p>
<ul>
<li>因为解决一个难题不需要状态,而且我们可以(希望)同意复制电路板是低效的,所以我不确定允许<code>__init__</code>方法是否有多大意义。这个类作为一个封装构造很好,我们应该在<code>Board</code>类中隐藏静态变量,比如<code>EMPTY</code>、<code>QUEEN</code>,等等,不管这个类是静态的还是实例化的。你知道吗</li>
<li>如果您决定保持类有状态,<code>printBoard</code>不应该产生<a href="https://en.wikipedia.org/wiki/Side_effect_(computer_science)" rel="nofollow noreferrer">side effects</a>重写<code>__str__</code>。你知道吗</li>
<li>不要在整个代码中<a href="https://en.wikipedia.org/wiki/Hard_coding" rel="nofollow noreferrer">hardcode</a>调整文本的大小,比如8;这会使类变得僵硬,难以维护,并且容易出现拼写错误和一个接一个的错误。改用<code>len(self.board)</code>,并自由地提供参数。你知道吗</li>
<li><code>fillDiagonal</code>不需要是递归的。考虑使用列表理解或numpy来简化这个矩阵遍历逻辑。你知道吗</li>
<li>每个<a href="https://www.python.org/dev/peps/pep-0008/" rel="nofollow noreferrer">PEP-8</a>使用<code>snake_case</code>变量名和<a href="https://www.python.org/dev/peps/pep-0008/#documentation-strings" rel="nofollow noreferrer">docstrings</a>而不是hashtag注释。如果您觉得必须编写类似<code># restricts column</code>的注释,请考虑将相关块移动到名为<code>restrict_column(...)</code>的函数中,并跳过注释。你知道吗</li>
</ul>
<p>下面是实现以下几点的初始重写:</p>
<pre><code>class Board:
EMPTY = 0
QUEEN = 1
DIRS = [(x, y) for x in range(-1, 2) for y in range(-1, 2) if x]
def __init__ (self, size=8):
self.board = [[Board.EMPTY] * size for _ in range(size)]
def __str__(self):
return "\n".join(map(str, self.board))
def legal_from(self, row, col, dr, dc):
while row >= 0 and row < len(self.board) and \
col >= 0 and col < len(self.board[row]):
if self.board[row][col] != Board.EMPTY:
return False
row += dr; col += dc
return True
def legal_move(self, row, col):
return all([self.legal_from(row, col, *d) for d in Board.DIRS])
def solve(self, row=0):
if row >= len(self.board):
return self
for col in range(len(self.board[row])):
if self.legal_move(row, col):
self.board[row][col] = Board.QUEEN
if self.solve(row + 1):
return self
self.board[row][col] = Board.EMPTY
if __name__ == "__main__":
for result in [Board(i).solve() for i in range(9)]:
print(result, "\n")
</code></pre>
<p>输出:</p>
<pre class="lang-none prettyprint-override"><code>[1]
None
None
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 1, 0]
[1, 0, 0, 0, 0]
[0, 0, 1, 0, 0]
[0, 0, 0, 0, 1]
[0, 1, 0, 0, 0]
[0, 0, 0, 1, 0]
[0, 1, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 0, 1]
[1, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 0, 0, 1]
[0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
</code></pre>