这是对《核心战争》的改编,《核心战争》可追溯到20世纪。更具体地说,它使用的是一种非常简化的指令集,主要是基于原始提案。
背景
在《核心战争》中,有两个程序争夺对计算机的控制权。每个程序的目标是通过定位和终止相反的程序来取胜。
战斗发生在计算机的主内存中。该内存称为核心,它包含8192个地址。当战斗开始时,每个竞争对手(称为战士)的代码都会放在随机的内存块中。程序执行在战士之间交替,每个战士执行一条指令。每条指令都可以修改Core的一部分,从而有可能自行修改程序。
目的是终止相反的程序。程序在尝试执行无效指令(即任何DAT
指令)时会终止。
指令集
每个程序由一系列低级指令组成,每个指令都有两个字段,称为A和B字段。
该指令集极大地借鉴了原始规范。主要的更改是1)澄清了添加/减去命令的问题,以及2)更改了#
寻址模式以使其可以在任何地方使用。Core Wars的大多数完整版本都有20多个操作码,8种寻址模式和一组“指令修饰符”。
操作码
每个指令必须具有七个不同的操作码之一。
DAT A B
-(数据)-仅保存数字A
和B
。重要的是,进程在尝试执行DAT指令时会死掉。MOV A B
-(移动)-将存储位置的内容移动A
到存储位置B
。这是前后的演示:MOV 2 1 ADD @4 #5 JMP #1 -1
MOV 2 1 JMP #1 -1 JMP #1 -1
ADD A B
-(添加)-将存储位置的内容添加A
到存储位置B
。两者的前两个字段被添加,第二个字段被添加。ADD 2 1 MOV @4 #5 JMP #1 -1
ADD 2 1 MOV @5 #4 JMP #1 -1
SUB A B
-(减)-从存储位置中减去存储位置的内容A
(并将结果存储到其中)B
。SUB 2 1 MOV @4 #5 JMP #1 -1
SUB 2 1 MOV @3 #6 JMP #1 -1
JMP A B
-(跳转)-跳转到locationA
,它将在下一个周期执行。B
必须为数字,但不执行任何操作(不过,您可以使用它来存储信息)。JMP 2 1337 ADD 1 2 ADD 2 3
跳转意味着
ADD 2 3
将在下一个周期执行。JMZ A B
-(如果为零则跳转)-如果line的两个字段B
均为0,则程序跳转到locationA
。JMZ 2 1 SUB 0 @0 DAT 23 45
由于指令1的两个字段均为0,因此DAT命令将在下一轮执行,从而导致死亡。
CMP A B
- (比较和跳过,如果不相等) -如果指令的领域A
和B
不相等,则跳过下一条指令。CMP #1 2 ADD 2 #3 SUB @2 3
由于指令1和2的两个字段的值相等,因此ADD命令不会被跳过,而是在下一回合执行。
当两个指令相加/相减时,两个字段(A和B)成对相加/相减。寻址模式和操作码不变。
寻址方式
有三种寻址方式。一条指令的两个字段中的每个字段都具有这三种寻址模式之一。
立即
#X
-X
是直接在计算中使用的行。例如,#0
是程序的第一行。负行是指程序开始之前内核中的行。... //just a space-filler ... ADD #3 #4 DAT 0 1 DAT 2 4
这会将两个DAT行中的第一个添加到第二行,因为它们分别在第3行和第4行中。但是,您不希望使用此代码,因为DAT将在下一个周期杀死您的机器人。
相对
X
-该数字X
表示目标内存地址相对于当前地址的位置。此位置上的数字用于计算。如果line#35
正在执行并包含-5
,则使用line#30
。... //just a space-filler ... ADD 2 1 DAT 0 1 DAT 2 4
这会将第二条DAT行添加到第一条。
间接的
@X
-数字X
代表相对地址。该位置的内容被临时添加到数字X中,以形成一个新的相对地址,从该地址中检索该数字。如果#35
正在执行line ,并且它的第二个字段是@4
,并且line的第二个字段#39
包含number-7
,那么#32
将使用line 。... //just a space-filler ... ADD @1 @1 DAT 0 1 DAT 2 4
这会将第一个DAT添加到第二个DAT中,但是会更加复杂。第一个字段是@ 1,它从该相对地址获取数据,该相对地址是第一个DAT的第一个字段,即0。这被解释为该位置的第二个相对地址,因此1 + 0 = 1得出总数与原始指令的偏移量。对于第二个字段,@ 1从该相对地址(第一个DAT的第二个字段中的1)获取值并将其添加到自身中。则总偏移为1 + 1 = 2。因此,该指令的执行方式与相似
ADD 1 2
。
每个程序最多可包含64条指令。
一轮开始时,这两个程序被随机放置在具有8192个位置的存储库中。每个程序的指令指针从程序的开头开始,并在每个执行周期后递增。一旦程序的指令指针尝试执行DAT
指令。
核心参数
核心大小为8192,超时值为8192 * 8 = 65536个ticks。内核是循环的,因此写入地址8195与写入地址3相同。所有未使用的地址均初始化为DAT #0 #0
。
每个参赛者不得超过64行。整数将存储为32位带符号整数。
解析中
为了使竞争对手更容易编程,我将向解析器添加行标签功能。操作码之前一行上出现的任何单词都将被解释为行标签。例如,tree mov 4 6
具有线标签tree
。如果程序中的任何地方都有一个包含tree
#tree
或的字段,@tree
则将替换一个数字。同样,大写也被忽略。
这是如何替换行标签的示例:
labelA add labelB @labelC
labelB add #labelC labelC
labelC sub labelA @labelB
在这里,标签A,B和C位于第0、1和2行。的实例#label
将替换为标签的行号。实例label
或被@label
标签的相对位置代替。寻址模式被保留。
ADD 1 @2
ADD #2 1
SUB -2 @-1
计分
对于每对参赛者,将进行所有可能的战斗。由于战斗的结果取决于两个程序的相对偏移量,因此会尝试每个可能的偏移量(其中大约8000个)。此外,每个程序都有机会在每个偏移量中首先移动。赢得大部分补偿的程序是该对的赢家。
勇士每赢得一对配对,将获得2分。对于每条领带,战士都会获得1分。
您可以提交多个战士。适用多个提交的典型规则,例如不进行标签团队合作,不进行合作,不做国王等。反正在《核心战争》中实际上没有任何空间可以这样做,因此这没什么大不了的。
控制器
控制器的代码以及两个简单的示例bot 都位于此处。由于此竞赛(使用正式设置进行比赛)是完全确定性的,因此您创建的页首横幅将与官方排行榜完全相同。
机器人例子
这是一个示例bot,演示了该语言的某些功能。
main mov bomb #-1
add @main main
jmp #main 0
bomb dat 0 -1
该机器人通过用“炸弹”代替它来缓慢擦除内核中的所有其他内存,从而进行操作。由于炸弹是DAT
指令,因此到达炸弹的任何程序都将被销毁。
有两个线标签,“ main”和“ bomb”,用于替换数字。经过预处理后,程序如下所示:
MOV 3 #-1
ADD @-1 -1
JMP #0 0
DAT 0 -1
第一行将炸弹复制到程序上方的行。下一行将炸弹(0 -1
)的值添加到move命令中,并且还演示了@
寻址模式的用法。此添加使move命令指向新目标。下一条命令无条件地跳回到程序的开始。
现任排行榜
24-Turbo
22-DwarvenEngineer
20-HanShotFirst
18-Dwarf
14-ScanBomber
10-偏执
10-FirstTimer
10-Janitor
10-Evolved
6-EasterBunny
6-CopyPasta
4-Imp
2-Slug
成对结果:
Dwarf > Imp
CopyPasta > Imp
Evolved > Imp
FirstTimer > Imp
Imp > Janitor
Imp > ScanBomber
Slug > Imp
DwarvenEngineer > Imp
HanShotFirst > Imp
Turbo > Imp
EasterBunny > Imp
Paranoid > Imp
Dwarf > CopyPasta
Dwarf > Evolved
Dwarf > FirstTimer
Dwarf > Janitor
Dwarf > ScanBomber
Dwarf > Slug
DwarvenEngineer > Dwarf
HanShotFirst > Dwarf
Turbo > Dwarf
Dwarf > EasterBunny
Dwarf > Paranoid
Evolved > CopyPasta
FirstTimer > CopyPasta
Janitor > CopyPasta
ScanBomber > CopyPasta
CopyPasta > Slug
DwarvenEngineer > CopyPasta
HanShotFirst > CopyPasta
Turbo > CopyPasta
CopyPasta > EasterBunny
Paranoid > CopyPasta
Evolved > FirstTimer
Evolved > Janitor
ScanBomber > Evolved
Evolved > Slug
DwarvenEngineer > Evolved
HanShotFirst > Evolved
Turbo > Evolved
EasterBunny > Evolved
Paranoid > Evolved
Janitor > FirstTimer
ScanBomber > FirstTimer
FirstTimer > Slug
DwarvenEngineer > FirstTimer
HanShotFirst > FirstTimer
Turbo > FirstTimer
FirstTimer > EasterBunny
FirstTimer > Paranoid
ScanBomber > Janitor
Janitor > Slug
DwarvenEngineer > Janitor
HanShotFirst > Janitor
Turbo > Janitor
Janitor > EasterBunny
Janitor > Paranoid
ScanBomber > Slug
DwarvenEngineer > ScanBomber
HanShotFirst > ScanBomber
Turbo > ScanBomber
ScanBomber > EasterBunny
ScanBomber > Paranoid
DwarvenEngineer > Slug
HanShotFirst > Slug
Turbo > Slug
EasterBunny > Slug
Paranoid > Slug
DwarvenEngineer > HanShotFirst
Turbo > DwarvenEngineer
DwarvenEngineer > EasterBunny
DwarvenEngineer > Paranoid
Turbo > HanShotFirst
HanShotFirst > EasterBunny
HanShotFirst > Paranoid
Turbo > EasterBunny
Turbo > Paranoid
Paranoid > EasterBunny
最新更新(新版本的Turbo和Paranoid)在旧笔记本电脑上运行大约需要5分钟。我要感谢Ilmari Karonen对控制器的改进。如果您有控制器的本地副本,则应更新文件。