- 最后登录
- 2026-2-9
- 在线时间
- 330 小时
- 阅读权限
- 40
- 注册时间
- 2014-8-25
- 积分
- 1689
- 帖子
- 182
- 精华
- 1
- UID
- 1333517
- 性别
- 保密
- 兴趣爱好
- 推箱

- 积分
- 1689
- 帖子
- 182
- 精华
- 1
- UID
- 1333517
- 性别
- 保密
- 兴趣爱好
- 推箱
|
本帖最后由 cjcjc 于 2025-12-12 16:36 编辑
200期比赛开始前4天,群里在讨论《百花齐放》。那关是100期比赛时,an版主所作的特别关卡,挂在推箱子网站主页8年,还没有人解开,也包括我。我对这种orimaze关卡一直没找到窍门,研究了几次都没有进展,所以就丢下了。书归正传,an版主问我要不要做一个200期的特别关卡?我当时什么想法都没有,何况按我的经验,如果编一个主关级别难度的关卡,少说要几个星期,多了几个月可能都不止,而且白天需要工作,只有晚上几个小时用来编关,所以我只是说试一试,没觉得能做出一个像样的关卡。
之后我在思考,怎么样才能做出一个有意思的特别关卡呢?当天晚上,我突然想到了0空位腾挪,0空位腾挪顾名思义就是在一个局部的腾挪里,不仅没有整位,连一个半位也没有。在03大师、xian兄、伞兄等人的一些关卡中,就有0空位腾挪的局部,不过只是作为关卡中很小的一个元素,这部分的腾挪通常也不复杂,我自己也研究过0空位腾挪,有一点经验,但是没有应用到编关中。半位关卡中,经常会“天然”地出现一些0空位腾挪,就是并非作者故意设计,而是凑巧出现这样的局部。不过我当时还没有见过一个大关卡中,从头到尾整体都是0空位的(后面我问了下an版主,他说他之前也没见过类似的关卡)。那如果能设计出这么一个大关卡,关卡整体没有空位,全程都是0空位腾挪,岂不是很有意思?
因为时间紧迫,手动设计肯定是来不及了,于是我想到,可以用电脑,随机生成一个规整的0空位初始盘面,在不死锁的前提下随机乱推若干步,说不定就可以生成一个比较难的关卡了,后期我也可以在此基础上手动做一些调整,增加点难度(实际上生成的关卡太大了,想要手动做调整增加难度不知道该如何下手,所以最后就把这步省掉了:p)。于是我立刻开始动手,在DeepSeek辅助下,于比赛开始前3天完成了代码。为了方便实现随机生成关卡的功能,我加了一些限制:初始盘面是正方形,关卡内部的墙都是1*1大小的,墙与墙的距离都是1。生成初始盘面,我用的算法是:从左上角C3内墙开始,找到相邻的内墙,然后随机挑其中一个用箱子连起来,直到把所有内墙都连起来为止,就好像有很多河流,最后汇在一起,形成了一张复杂的网络一样。于是,我就给当时还未成型的关卡先定好了名字——《百川归海》。后面随机打乱时,也用了类似的算法,这里就不具体说了,有兴趣的朋友可以看看代码。
这样随机生成一个初始局面,再随机打乱若干步,把打乱后的局面作为结束局面,就得到了一个随机的0空位关卡。这个关卡一定是有解的,随机打乱的步骤就是关卡的答案,我又抄袭了一下愉翁兄推箱快手的代码,写了一个把打乱步骤翻译成lurd格式答案的功能,经过一番调试之后开始第一次运行,生成了一个99个箱子,随机打乱10万步的关卡,发给了an版主。这个关卡随机打乱的步骤翻译成lurd之后有400万步,当时我手边的电脑内存比较小,优化不下去,我估计那关的最优步数在10000步以内,甚至可能只有一两千步。我手动推了一下这个关卡,当时没什么经验,又比较晚了,脑袋转不动了,觉得这关难的离谱,转来转去完全找不到过关的方法。推起来的感觉有点像orimaze关卡,又有点像以前出现过的moves=pushes关卡,还有点像魔方,总之是挺有意思的。于是决定就这样,生成一个尺寸更大的、打乱步骤更多的关卡作为最终的版本。
我设置成48*48-1=2303个箱子,随机打乱100万步,开始运行程序,跑了一天一夜,到比赛前2天晚上还没跑完。经过一番调试发现是把打乱步骤翻译成lurd的代码运行太慢了,于是后面改成把打乱步骤保存成点推,运行快了很多。我的代码还是效率太低了...
同时,我又有了一个新的想法。按上面的规则生成的《百川归海》类型的0空位关卡(简称b型关卡),箱子只能在同一行或者同一列中运行,这一点群里的朋友关山月也指出来了。如果把内墙改成两个1*1的墙对角摆放,整体还是0空位,但是箱子就可以运行到相邻行列了,变化的可能性增加很多。于是我按新的想法修改了代码,在比赛前1天晚上完成了修改,生成了《万丈深渊》型0空位关卡(简称w型关卡)。当时我以为这样生成的关卡会比《百川归海》难度高一个档次,《百川归海》已经难的离谱了,那这关岂不是压根不是人类能解开的关卡?我觉得《百川归海》如果是100,那这关至少也是10000吧,所以取名叫《万丈深渊》。
于是我有点得意忘形了,批量生成了一大堆关卡,也就是分享在群里的《百川归海集合》,分享给了an版主。其中:《潭池》是24箱子,随机打乱1000次生成的,这20关难度基本都是0;《溪流》是48箱子,随机打乱1万次生成的,这20关有一点难度,但是经过思考还是能过关;《湖泊》是99箱子,随机打乱1万次生成的,这20关已经很难了,我当时试推了一关,完全没找到方法;《江河》是224箱子,随机打乱1万次生成的;《海洋》是399箱子,随机打乱10万次生成的;《百川归海》是899箱子,随机打乱100万次生成的,这一关就是最终的版本,这关的关卡尺寸和箱子数量都和100期的特别关卡《百花齐放》差不多;《百川归海(恐怖版)》是2303箱子,随机打乱100万次生成的;《万丈深渊(轻松版)》是99箱子,随机打乱10万次生成的;《万丈深渊》是399箱子,随机打乱300万次生成的,这关和《百川归海》的尺寸保持一致;《万丈深渊(恐怖版)》是1023箱子,随机打乱300万次生成的。随后比赛开始当天,我把这个关卡集分享在了群里。
完成比赛关卡后,我开始推《百川归海集合》。虽然这个集合中的关卡在生成时把答案也保存下来了,但是我没有实际推过。推了一上午搞定了前40关和《湖泊》中的一关,基本了解了关卡的特点,也掌握了这类关卡的腾挪方法,发现没有我想象中的那么难,完全达不到“难的离谱”这个级别,不过我觉得难度可以达到9.0分。我也试推几个了w型关卡,也发现比想象中简单很多,之前的评价“压根不是人类能解开的关卡”过于夸张了。因为虽然箱子可以运行到相邻行列,变化的可能性提高了一个数量级,可是相应的腾挪也更加自由了,有的时候打乱的步骤很复杂,但是可以用简单的方式还原回去。另外,因为内墙形状比较复杂,所以相同尺寸的w型关卡比b型关卡箱子数量少很多。不过w型关卡还有一个特点,就是结构太花了,对人类眼睛不太友好,总之我觉得难度大概也是9.0分。虽然这两关难度没有我想象的那么高,不过至少是创新的,而且是有趣的,作为特别关卡也挺合适,至于名字,也懒得重新起了,将错就错吧。
最后把随机生成关卡的程序分享给大家,用java写的,运行时需要有java环境。运行命令是 java -jar sokoban.jar w 10 1000,其中第一个参数是生成关卡的类型,w是生成w型关卡,b是生成b型关卡,第二个参数代表关卡尺寸,生成关卡的箱子数量等于第二个参数的平方减去一,第三个参数代表关卡的随机打乱步数。生成关卡的尺寸不能超过100*100,换言之w型关卡第二个参数最大是32,b型关卡第二个参数最大是48(也就是恐怖版两关的尺寸)。理论上,随机打乱的步数越大,生成的关卡就越难,但是到一定步数之后再打乱难度就变化不大了,所以第三个参数也不需要设置太大。参数数量和参数值不对会提示错误,如果正常运行会生成一个文本文件,里面有关卡的xsb格式和点推格式答案。这一系列的关卡就到此为止了,以后我不再用程序随机生成这种关卡了,感觉没什么意义了。
| 关卡类型 | 参数1 | 参数2 | 参数3 | | 《百川归海》型(b型) | b | 不大于48,生成关卡尺寸为(2n+3)*(2n+3) | 打乱步数 | | 《百川归海-扩展版》型(e型) | e | 不大于48,生成关卡尺寸为(2n+3)*(2n+3) | 打乱步数 | | 《万丈深渊》型(w型) | w | 不大于32,生成关卡尺寸为(3n+3)*(3n+3) | 打乱步数 | | 《百舸争流》型(g型) | g | 不大于32,生成关卡尺寸为(3n+3)*(3n+3) | 打乱步数 | | 《百川归海-特别版》型(s型) | s | 不大于47,不小于7,建议选择8-15,生成关卡尺寸为(2n+3)*(2n+5) | 打乱步数 |
4.7 关卡生成器v1 + 百川归海集合.xsb
4.10 关卡生成器v2 + 百舸争流.xsb
4.13 关卡生成器v3
4.17关卡生成器v4 + 百川归海集合.xsb
sokoban.zip
(55.4 KB, 下载次数: 44)
5.8关卡生成器v5 + 百川归海集合.xsb(上传日期12.12) |
-
总评分: 经验 + 40
查看全部评分
|