作为本周的 Hint,我先从我更喜欢的而且可以做得更好的战士类型开始,那就是复制者(replicator)或纸(paper);这类战士依靠数量优势来战胜敌人。 纸战士,和其他战士一样,从游戏开始到现在已经发展了很多;目前他们几乎都使用所谓的“丝绸(silk)”风格,即在复制之前进行分裂。这只能在 94 规则下完成,因为它需要后增量和 a 字段寻址。现在让我们来看一个非常简单的家伙。
start spl 1
mov -1, 0 ;生成 3 个并行进程
1 silk spl.a @0, 100 ;拆分
2 mov.i }silk, >silk ;复制
3 jmp.a silk, {silk ;重复此操作并重置指针
前两行代码会生成 3 个进程,它们依次执行同一行代码,然后再执行下一行。第一行代码会创建另一个进程来执行从 start+1 开始的行,然后进程 1 将 start 行复制到 mov 行,进程 2 进行拆分,并添加另一个进程来执行 silk。生成精确数量的并行进程的更简单方法是将所需数量转换为二进制 3 -> 11,再减去 1 -> 10,对于每个 1 使用一个spl 1,对于每个 0 使用一个mov -1, 0。实际操作比解释要简单得多。为了让战士工作,我们需要的进程数量至少要与要复制的行数一样多。
让我们回到我们的战士;现在我们有三个进程正在执行 line1,它们在此处发生分裂,即在 a 字段地址,即第 0 行 b 字段所指向的地址,它们正在执行的行的 b 字段,相隔 100 个位置。当所有这三个进程都执行完这一行时,另外三个进程准备好执行第 silk+100 行,这里没有可执行的行,但我们还有一些时间,因为新生成的进程会在那些执行分裂的进程之后排队。
现在,前三个进程执行 line2,它们将 line1 的 a 字段所指向的内容移动到 line1 的 b 字段所指向的位置,然后它们同时递增 line1 的 a 和 b 字段。第一个进程将 line1 移动 100 个单元格,并使 line1 变为:1 silk spl.a @1, 101,这样它(译注:进程 2)就在上一行之后,将 line2 复制到距离“silk”101 个单元格的位置。
进程 3 执行的操作与复制 line3 相同。
现在轮到由 line1 创建的新进程来执行了,它们不再坐在一个空单元上,而是坐在由 line2 创建的 line1 的副本上,它们执行该副本并开始创建第三代副本。
前三个流程现在已到达 line3,现在战士已经以这种方式进行了修改
1 silk spl.a @3, 102
2 mov.i }silk, >silk
3 jmp.a silk, {silk
line3 的 a 字段是跳转的地址,而 b 字段会递减第 1 行的 a 字段,以便战士可以继续分裂和复制。
这个并不是真正的战士,它的攻击潜力太小,只是为了理解丝绸复制器的工作原理。简单的改进是增加一条附加行,这样副本就不会一个挨着一个地打包,并添加一些爆炸效果,让它变得稍微棘手一些。接下来的战士是 Paperone,它是我第一个进入 94 号山的战士,几个月前它曾在初级山称霸一时。 这与常见问题解答中的示例很相似(确实非常相似:-)),但为了让它运行良好,我必须对许多常量进行调整。
;redcode-94
;name Paperone
;author Beppe Bezzi
;strategy Silk replicator
;kill Paperone
;assert CORESIZE == 8000
start spl 1, <300 ;\
spl 1, <150 ; 生成7个连续的进程
mov -1, 0 ;/
silk spl 3620, #0 ;分裂为新副本
mov.i >-1, }-1 ;将自身复制到新位置
;这是使用多个进程进行复制的另一种方法,另一种方法稍微好一些,因为我们可以减少要拆分的单元格数量,如果幸运的话,甚至可以消灭一个“小鬼”。
mov.i bomb, >2005 ;线性轰炸
mov.i bomb, }2042 ;A-间接轰炸,用于反吸血鬼
;放置的第一枚炸弹作为后续流的指针,铺设地毯。
add.a #50, silk ;计算新副本的距离
jmp silk, <silk ;重置源指针,制作新副本
bomb dat.f >2667, >5334 ;反imp炸弹
这对三段式的 imp 环非常有效。在执行过程中,一次幸运的命中可以杀死许多其他的;至于其他类型的炸弹,至少就我而言,我们下次再讨论。
下次我们会讨论更高级的问题:另一种比这个更好的复制引擎,以及其他与纸相关的主题,如扩散常数、炸弹、策略等…
如有疑问,请发邮件至bezzi@iol.it,或者,如果你认为这会引起普遍兴趣,请发至 rec.games.corewar
欢迎任何有 hint 或战士要发布的人。