
作为一名自学的数独解谜者,我确实喜欢自己解决谜题,但真正的挑战是制定解决谜题所需的策略。 有时,我可能会陷入一个谜题,仅仅通过所有策略来尝试找到下一个数字可能会有点无聊。 这可能是显而易见的,但我只是看不到它。 这就是我写这个程序的原因。 我已经将我所知道的所有策略转换为代码,永远不会感到无聊和犯错误。
有些谜题我无法解决。 我非常确定我缺少一个策略,而这个程序将证实它。
程序结构遵循最小的 MVVM 设计模式。
该模型包含所有求解策略和 81 个单元的一维数组。 解决数独谜题的技巧不是找出数字直接去向的地方,而是找出数字不能直接去向的地方,以及何时只剩下一种可能性,那就是它。 为此,每个单元格都包含可能的单元格值列表,然后由策略更新该列表。 该列表实际上是一个位字段,它允许使用布尔代数来帮助所需的模式匹配。 另一个值得注意的点是,我没有编写两个函数来实现策略,一个用于行,另一个非常相似的版本用于列,我只需编写行版本,旋转拼图,然后再次调用 rows 函数。 拼图实际上并未旋转,代码只是更改了每个单元格的 [x, y] 坐标转换为数组索引的方式。
ViewModel 还包含一个包含 81 个单元格的列表,这次存储在 ObservableCollection 中。 当用户更改拼图时,将执行 ViewModel 中的回调。 它确定需要执行哪个操作并调用适当的模型函数,无论是添加、编辑、删除等,以便可以重新计算拼图。 当模型函数返回时,将比较两个单元列表,并根据需要更新视图模型列表,从而重绘单元。
该视图包含一个自定义布局面板 SudokuGrid,用于排列单元格和网格线。 我在网上找不到太多有关编写布局面板的信息,因此我使用 ILSpy 对 UniformGrid 进行了逆向工程。 事实证明它们非常简单,如果您以前编写过自定义控件,那么其中很多内容都会很熟悉。 网格包含在提供自动重新缩放功能的视图框中。 |