My first Corewar Webpage: book of stones


Carbonite by Ian Sutton

Carbonite is <0.33 stone which covers the core with real dat bombs and after a bombing raid it turns into a coreclear (the source given below is a slight hack of original Sutton's Carbonite):

;redcode-94nop
;name Carbonite
;author Ian Sutton
;assert CORESIZE==8000

stone   spl     #0	    , <-1151+3
        mov     197	    , inc-(197*3500)
inc     add.ab  {0	    , }0
        djn.f   -2	    , <-1151
bomb    dat     >-1	    , >1
boot	mov	-2	    , @bptr
	mov	{boot	    , <bptr
	mov	{boot	    , <bptr
bptr	mov	bomb	    , *1000
	mov	{boot	    , <bptr
	jmp.b	@bptr	    , 0
	
	end     boot

How it works

When booted, Carbonite looks like this:

1005   SPL.B  #     0, < -1148 (1)
1006   MOV.I  $   197, $ -1499
1007   ADD.AB {     0, }     0
1008   DJN.F  $    -2, < -1151
...
1203   DAT.F  >    -1, >     1     
Process (1) splits another process (2):
1005   SPL.B  #     0, < -1148 (2)
1006   MOV.I  $   197, $ -1499 (1)
1007   ADD.AB {     0, }     0
1008   DJN.F  $    -2, < -1151
...
1203   DAT.F  >    -1, >     1     
Process (2) splits another process while (1) throws a DAT bomb -1499 cells behind MOV line:
7507   DAT.F  >    -1, >     1   ; bomb thrown by (1)
...
1005   SPL.B  #     0, < -1148 (3)
1006   MOV.I  $   197, $ -1499 (2)
1007   ADD.AB {     0, }     0 (1)
1008   DJN.F  $    -2, < -1151
...
1203   DAT.F  >    -1, >     1     
Now the process (1) modifies cell no. 1006. This is a bit complicated so let's have a closer look how it really works:
1006   MOV.I  $   197, $ -1499
1007   ADD.AB {     0, }     0 (1)

The general idea of ADD.AB {0, }0 is that it works like ADD.AB -1, -1.

After "first half" of the cycle, A-field of 1007th cell is decremented: the instruction looks like ADD.AB {-1, }0, but acts like ADD.AB $-1, *0 (we don't care about postincrement addressing mode in B-field of 1007th cell, let's assume for a while that there's * instead of }):
1006   MOV.I  $   197, $ -1499 <--------------------------------------\
1007   ADD.AB $    -1, *     0 --- both A and B fields point to 1006 -/
The .AB modifier means that the ADD takes A-value from 1006th cell (197) and adds it to the cell that is pointed by the B-field (via indirection it points 1006th cell). As the output one receives
1006   MOV.I  $   197, $ -1302
Now, let's get back to proper addressing modes in 1007th line
1007   ADD.AB {    -1, }     0 (1)
The "second half" of a cycle is executed: the A-field is incremented and the instruction looks as at the beginning of a cycle:
1007   ADD.AB {     0, }     0
1008   DJN.F  $    -2, < -1151 (1)
The warrior looks now like:
1005   SPL.B  #     0, < -1148 (3)
1006   MOV.I  $   197, $ -1302 (2)
1007   ADD.AB {     0, }     0
1008   DJN.F  $    -2, < -1151 (1)

The second process throws a DAT bomb, third one splits another process.

Following pictures presents Carbonite working in different phases:

Carbonite bombs the core

Figure 1. Carbonite bombs the core

Carbonite bombs the core

Figure 2. Carbonite enters the clear phase

After 10644 cycles the stone itself had started and after it had generated 146 processes the 1007th cell is hit by DAT.

1005   SPL.B  #     0, < -1148     
1006   MOV.I  $   197, $     1        <------- this line is executed
1007   ADD.AB {     0, }     0     
1008   DJN.F  $    -2, < -1151     
and after next cycle warrior looks like:
1005   SPL.B  #     0, < -1148 (1 process in this address)
1006   MOV.I  $   197, $     1 (48 processes)
1007   DAT.F  >    -1, >     1 (49)   
1008   DJN.F  $    -2, < -1151 (48)
Now the warrior (1006th line, namely) works as a simple coreclear. Notice that the process executing DAT >-1, > 1 instruction modifies the B-field of 1006th cell:
1006   MOV.I  $   197, $     1
1007   DAT.F  >    -1, >     1        <------- this line is executed
which outputs
1006   MOV.I  $   197, $     2
1007   DAT.F  >    -1, >     1
and the B-field is incremented thus clear pointer is shifted. Since the coreclear stream goes forward (and there's no trick used) Carbonite suicides after next 23898 cycles.

Carbonite's stone was designed to kill clears; a classic d-clear may be an example

;redcode-94nop
;assert 1
;name d-clear

gate	dat 0,100
	
	dat 0,0
	
clear	spl #0,#0
	mov bomb,>gate
	djn.f -1,>gate
bomb	dat <2667,15
	end clear
The DAT >-1,>1 bomb is very effective against such a clear. Provided the clear code is loaded into core as below:
00000   DAT.F  $     0, $   100     
	; some empty core
00011   SPL.B  #     0, #     0     
00012   MOV.I  $     2, >   -12     
00013   DJN.F  $    -1, >   -13     
00014   DAT.F  <  2667, $    15     
If DAT >-1,>1 hits 0th cell (the gate) the clear would overwrite its code with DAT.F <2667, 15 executing itself, for the clear pointer, situated in B-field, would be equal 1. If bomb hits SPL instruction clear is wounded but, in general, it runs (maybe slowed down a bit). Hitting MOV lines disables the clear (does not kill it, however). When the clear is bombed over DJN it looks as below:
00000   DAT.F  $     0, $   100     
	; some empty core
00011   SPL.B  #     0, #     0     
00012   MOV.I  $     2, >   -12     
00013   DAT.F  >    -1, >   1
00014   DAT.F  <  2667, $    15
13th line constantly alters preceding line and makes it point to SPL and MOV itself, eventualy. Finally, when the bomb itself is hit, clear finilizes its run and then is disabled, with SPL #0, #0 being the only remaining line.
Top

Check HTML