作为一名自学的数独解谜者,我确实喜欢自己解决谜题,但真正的挑战是制定解决谜题所需的策略。 有时,我可能会陷入一个谜题,仅仅通过所有策略来尝试找到下一个数字可能会有点无聊。 这可能是显而易见的,但我只是看不到它。 这就是我写这个程序的原因。 我已经将我所知道的所有策略转换为代码,永远不会感到无聊和犯错误。
有些谜题我无法解决。 我非常确定我缺少一个策略,而这个程序将证实它。
SudokuSolver 用户界面
这是一个简单的 WPF 程序。 它使用 MahApps 库提供无图标窗口以及深色模式的轻松实现。
请注意,没有解决按钮。 每次用户更改代码时,代码都会尝试即时解决难题。
代码
程序结构遵循最小的 MVVM 设计模式。
该模型包含所有求解策略和 81 个单元的一维数组。 解决数独谜题的技巧不是找出数字直接去向的地方,而是找出数字不能直接去向的地方,以及何时只剩下一种可能性,那就是它。 为此,每个单元格都包含可能的单元格值列表,然后由策略更新该列表。 该列表实际上是一个位字段,它允许使用布尔代数来帮助所需的模式匹配。 另一个值得注意的点是,我没有编写两个函数来实现策略,一个用于行,另一个非常相似的版本用于列,我只需编写行版本,旋转拼图,然后再次调用 rows 函数。 拼图实际上并未旋转,代码只是更改了每个单元格的 [x, y] 坐标转换为数组索引的方式。
ViewModel 还包含一个包含 81 个单元格的列表,这次存储在 ObservableCollection 中。 当用户更改拼图时,将执行 ViewModel 中的回调。 它确定需要执行哪个操作并调用适当的模型函数,无论是添加、编辑、删除等,以便可以重新计算拼图。 当模型函数返回时,将比较两个单元列表,并根据需要更新视图模型列表,从而重绘单元。
该视图包含一个自定义布局面板 SudokuGrid,用于排列单元格和网格线。 我在网上找不到太多有关编写布局面板的信息,因此我使用 ILSpy 对 UniformGrid 进行了逆向工程。 事实证明它们非常简单,如果您以前编写过自定义控件,那么其中很多内容都会很熟悉。 网格包含在提供自动重新缩放功能的视图框中。
解决策略
这些对于数独求解者来说可能非常熟悉,但由于是自学,它们会有不同的名称和术语。 81 个单元格也排列成 9 个立方体,每个立方体包含 9 个单元格。 行和列就是您所期望的。
1. 简单的立方体、行和列消除
如果用户在红色单元格中键入一个数字,则该数字将从蓝色区域中的所有单元格的可能值中删除。 如果这导致单元格只剩下一个可能的剩余单元格,则将其添加到堆栈中,并且代码循环处理单元格,直到堆栈上不再有单元格为止。
2、方向消除
如果单元格的可能值仅限于立方体中单行 3 个单元格,则拼图行的其余 6 个单元格中的任何单元格都不能包含这些排他的可能值。 这是一行,因此独占值的影响方向是水平的。 对于立方体中的柱(垂直方向)使用相同的过程。 如果方向是水平的,可能的值将显示为红色,如果是垂直的,则可能的值将显示为绿色。
另外,如果一个单元格有一个可能的值,同时具有垂直和水平方向,那么它一定是该单元格的值。
3. 单一可能值
虽然行或列中的单元格可能有多个可能的值,但如果只有一个单元格具有特定值,则该值一定是该单元格的值。
4. 模式匹配消除
这个策略有点复杂。 下面显示的彩色单元格都没有值,只有可能值。
两个立方体中的四个绿色单元格的可能值列表中将有六个。 这六个可以出现在不同列的顶部和底部或底部和顶部单元格中,两种排列都可以有效。 这意味着我们可以推断剩余立方体中的红色单元格的可能值必须有 6 个,因此可以从蓝色区域中的单元格可能值中删除 6 个。 显示的绿色单元格的模式是 Pattern.Lower2,立方体列中两个单元格的其他可能模式是 Pattern.Upper2 和 Pattern.TopAndBottom。
四个绿色单元格不需要位于同一列中,它们可以是任意组合。 结果是一样的。 为了适应这种情况,代码聚合了三个多维数据集中三个单元格的所有行的可能值。 这给出了三列的结构,每个立方体一列包含三组可能的值。 这个结构随后用于模式匹配。
此策略适用于拼图中的所有三行立方体以及三个立方体的每一列。
5. 简单的试错
我知道我总是必须实施这个策略,因为你偶尔会发现一个难题,其中两行和两列交叉处的四个单元格可以有两个可能的值,但它们的排列是不确定的。 该谜题可以有多个正确的解决方案。 您只需选择一个值,插入它,然后让逻辑策略解决其余的问题。
事实证明,这可能是我一直以来所缺失的策略。 虽然逻辑策略足以单独解决更简单的问题,但添加此策略也可以解决更困难的难题。 专业的解谜者也许能够在头脑中做到这一点,跟踪谜题的状态,但这超出了我的能力范围。 这也是我下棋不擅长的原因; 我无法计划未来那么多的行动。
SudokuSolver 确实不需要再介绍了。 正如它的名字所暗示的那样,它的目的非常明确。 其机制背后的主要思想是使用策略。 用户将输入一些已知的数字,应用程序将显示完成整个游戏的可能方式。 请记住,开发人员已经表示,通过使用试错和策略方法,应用程序仍然有可能无法解决这个难题。
虽然更多的是一种工具,但事物的美学方面似乎并不平淡,甚至无聊。 相反,虽然简单,但似乎有一定程度的打磨,提供了完整的产品感觉。 您添加到游戏中的数字以黑色显示,而建议的组合以浅蓝色显示。 选定的空间以蓝色突出显示,而整个拼图是可见的。 级别的准确表示使复制和粘贴现有数字变得更加容易。
尽管数独背后的主要思想及其基本规则都很明确,但学习寻找正确的组合可能需要一些时间。 通过使用该程序作为老师,您可以提高完成数独游戏的能力。 该应用程序还可以用来检查您提交的解决方案,以防您没有时间或精力再次完成整个谜题。
SudokuSolver 是一款可靠的应用程序,所有数独爱好者都应该考虑。 想要通过记笔记和观察该应用程序所采用的策略来提高技能的初学者也可以使用它。