再战墨盘游戏

之前写了几篇关于墨盘游戏的求解程序,但是由于对盘面的点的编码方式使用了行,列表示,使得代码逻辑复杂,又不能很好的去除对称的状态,以及该游戏不容易构造有效的估值函数,导致搜索空间太大,有些关卡内存溢出都不能找到解

当我看到六边形网格这篇译文后,大有所益,决定对之前的墨盘游戏求解程序重写一遍,鉴于之前的程序找到了少于官方提示步数的解法,新的程序不再依赖官方提示步数,既然没有好的估值函数,又要找到最优解,那就使用双向广度优先搜索吧,比起广度优先搜索,可以显著减少搜索空间,时间

盘面表示

不多说,看这篇译文六边形网格

有效的点击点

for (int x = -(this.layer - 1); x < this.layer; x++) {
	for (int y = -(this.layer - 1); y < this.layer; y++) {
		for (int z = -(this.layer - 1); z < this.layer; z++) {
			if (x + y + z == 0) {
				......
			}
        }
    }
}

循环次数: ( l a y e r ∗ 2 − 1 ) 3 (layer * 2 - 1) ^ {3} (layer21)3,实际有效点击点: 3 ∗ l a y e r ∗ ( l a y e r − 1 ) + 1 3 * layer * (layer - 1) + 1 3layer(layer1)+1,先将可点击的点坐标保存到数组,减少大量的无效循环次数

去除对称状态

看过译文就知道,使用立体坐标对盘面的点进行编码,使得整个六边形具有完美优雅的对称性
这样就可以找到六条对称轴,一个对称中心(六条对称轴交点)
对称轴,对称点
这样就可以将起始状态和终止状态相同的对称性的对称节点剪枝,减少搜索量

代码

GitHub

测试结果一

对比墨盘游戏 算法求解-测试结果墨盘游戏 算法求解 改进版-测试结果,搜索时间,空间都有显著的减小

int[] startStatus = {
           0,0,0,0,
          1,0,0,0,1,
         0,0,0,0,0,0,
        0,0,0,1,0,0,0,
         0,1,0,0,1,0,
          0,0,1,0,0,
           0,0,0,0
};
int[] endStatus = {
           0,0,0,0,
          0,0,0,0,0,
         0,0,1,1,0,0,
        0,0,0,1,0,0,0,
         0,0,1,0,0,0,
          0,1,1,0,0,
           0,0,0,0
};

开始队列长度854 结束队列长度1237 开始树节点2725 结束树节点1284
搜索时间: 91
step:1 x:-1 y:2 z:-1 action:C
   ○ ○ ○ ○ 
  ○ ○ ○ ○ ● 
 ○ ○ ○ ○ ○ ○ 
○ ○ ● ● ○ ○ ○ 
 ○ ● ○ ○ ● ○ 
  ○ ○ ● ○ ○ 
   ○ ○ ○ ○ 

step:2 x:2 y:-1 z:-1 action:C
   ○ ○ ○ ○ 
  ○ ○ ○ ○ ○ 
 ○ ○ ○ ○ ○ ○ 
○ ○ ● ● ● ○ ○ 
 ○ ● ○ ○ ● ○ 
  ○ ○ ● ○ ○ 
   ○ ○ ○ ○ 

step:3 x:1 y:-1 z:0 action:L
   ○ ○ ○ ○ 
  ○ ○ ○ ○ ○ 
 ○ ○ ○ ● ○ ○ 
○ ○ ● ○ ● ○ ○ 
 ○ ● ○ ● ○ ○ 
  ○ ○ ● ○ ○ 
   ○ ○ ○ ○ 

step:4 x:-1 y:0 z:1 action:L
   ○ ○ ○ ○ 
  ○ ○ ○ ○ ○ 
 ○ ○ ○ ● ○ ○ 
○ ○ ● ○ ● ○ ○ 
 ○ ● ○ ● ○ ○ 
  ○ ○ ● ○ ○ 
   ○ ○ ○ ○ 

step:5 x:0 y:0 z:0 action:R
   ○ ○ ○ ○ 
  ○ ○ ○ ○ ○ 
 ○ ○ ○ ● ○ ○ 
○ ○ ● ● ● ○ ○ 
 ○ ○ ○ ○ ○ ○ 
  ○ ● ● ○ ○ 
   ○ ○ ○ ○ 

测试结果二

以下10关解法均比官方提示步数快一步

关卡关卡关卡关卡关卡
VII-3VII-6VII-7X-5XI-11
VII-3VII-6VII-7X-5XI-11
XIII-8XIV-6XIV-9XV-2XVI-2
XIII-8XIV-6XIV-9XV-2XVI-2
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值