我正在尝试为游戏算法创建一个可解性函数。基本上是一个函数,它为给定的游戏返回真或假,如果它是可解的。
该游戏是 Buttonia.com(尚未实现算法),一种熄灯游戏。基本上你有一个按钮网格,每个按钮在按下时都会改变它的一些邻居的状态。目前我生成一个随机游戏配置,然后尽可能应用启发式方法。其余的由蛮力搜索决定。
到目前为止,我的进展是创建了一个方程组来模拟游戏。由于每个按钮都需要改变状态奇数次才能最终处于向下状态,所以它的等式是这样的:
button_A = 1 - (button_1 + button_2 + ... + button_X) % 2
其中 button_1 到 button_X 是对 button_A 有影响的按钮的状态。如果某些按钮不依赖于其他按钮,它们可能会立即解析。其余的,我尝试一种配置,直到我遇到冲突,然后返回轨道。
目前,该算法适用于较小的游戏配置。我已经从 3x3 游戏到 10x10 的大小对其进行了测试。其中 6x6 接近实际游戏的上限。
这些方程极大地减少了搜索空间的蛮力,使其变得实用。可能有一种纯粹的数学方法来求解方程组。
ASCII 格式的 3x3 游戏示例(来自buttonia.com/?game=2964):
||#
-o-
+#|
Legend:
o = affect only self
- = affect left and right neighbors
| = affect above and below neighbors
+ = affect left, right, above and below neighbors
# = affect all 8 surrounding neighbors
解决方案,按这些:(0,0), (2,0), (1, 2), (0, 1), (1, 1), (2,1)
这场比赛的方程式:
Button_0_0 = 1 - (0) % 2
Button_1_0 = 1 - (Button_2_0) % 2
Button_2_0 = 1 - (0) % 2
Button_0_1 = 1 - (Button_0_0 + Button_0_2 + Button_1_2) % 2
Button_1_1 = 1 - (Button_1_0 + Button_2_0 + Button_0_1 + Button_2_1 + Button_1_2) % 2
Button_2_1 = 1 - (Button_2_0 + Button_1_2 + Button_2_2) % 2
Button_0_2 = 1 - (Button_1_2) % 2
Button_1_2 = 1 - (Button_0_2) % 2
Button_2_2 = 1 - (Button_1_2) % 2
潜在的解决方案:
更改数学函数以避免对模的需要使我们可以将左侧的项移到右侧,从而创建高斯方法所需的简洁矩阵设置。所以前两个方程将分别转换为:
-1 = -1*B00 + 0*B10 + 0*B20 + 0*B01 + 0*B11 + 0*B21 + 0*B02 + 0*B12 + 0*B22
-1 = 0*B00 + -1*B10 + -1*B20 + 0*B01 + 0*B11 + 0*B21 + 0*B02 + 0*B12 + 0*B22
此处讨论的解决方案:使用自定义运算符的高斯消除
越来越近。几乎准备好发布完整的解决方案:反转二进制网络