This is the collection of my hints as published on Core Warrior. It's just as it was, without any editing. I hope You'll find it useful

-Beppe Bezzi

----------------------------------------------------------------

The hint

Replicators (part 1)

Having to make the hint of the week, I start with the kind of warriors I like more and I can do better, replicators, or paper; the sort of warrior that use the sheer number to overcome the enemy.
Paper warriors, like every other, have evoluted a lot from the beginnings of the game; presently they use almost all the so called 'silk' style, i.e. splitting before copying. This can be done only under 94 rules because requires post increment and a-field addressing. Now let's give a look at a very simple guy.


start   spl     1
        mov     -1,     0       ;generate 3 parallel processes

1 silk  spl.a   @0,     100     ;split 
2       mov.i   }silk,  >silk   ;copy 
3       jmp.a   silk,   {silk   ;repeat the thing resetting pointer

First two lines generate 3 processes that execute the same line one after the other, before executing the next. First line creates another process to execute line start+1, then process 1 copy start line over the mov and process two splits, adding another process to execute silk. The simpler way to generate an exact number of parallel processes is converting the number required in binary 3 -> 11, subtract one -> 10, use a spl 1 for every one and a mov -1,0 for every zero. Much simpler to do than to tell. For the warrior to work we need at least as many processes as we have lines to copy.
Let's go back toour warrior; now we have three processes executing line 1 they split, where, at the a-field address i.e. the address pointed by b-field of line 0 locations away, the b-field of the line they are executing, 100 locations away. When all three process executed this line we have three others process ready to execute line silk+100, there is nothing to execute here but we have some time because new generated processes are queued after those executing the split.
First three processes now execute line 2, they move what's pointed by a-field of line 1 to the location pointed by b-field of line 1 then they increment both a and b field of line 1. First process moves line 1 100 cells away from line 1 and leaves line 1 changed such a way:
1 silk  spl.a    @1,    101
so it copyes line 2 101 cells away from silk, just after the previous line. Process 3 does same thing copying line3.
Now it's the turn of the new processes, those created by line1, to execute, they are not more sitting on an empty cell but over the copy of line1 created by line2, they execute it and begin creating third generation copy.
First three processes now reach line3, now the warrior has modifyed in such way

1 silk  spl.a   @3,     102
2       mov.i   }silk,  >silk
3       jmp.a   silk,   {silk 
The a-field of line 3 is the address of the jump while b-field decrements a-field of line 1 so that the warrior can go on splitting and copying.

This one is not a real warrior, his offensive potential is too small, it's just to understand how a silk replicator works. Simple improvements are adding an add line so as copies are not packed one near the other, and adding some bombing to make it a bit nastier. The warrior following is Paperone, my first warrior to enter 94 hill, it was on top of beginner hill for some time a few months ago.
It's similar to the example in the FAQ (very similar indeed :-) but to make it run well I had to work on the many constants.

;redcode-94
;name Paperone
;author Beppe Bezzi
;strategy Silk replicator
;kill Paperone
;assert CORESIZE == 8000

start   spl     1,      <300    ;\
        spl     1,      <150    ;  generate 7 consecutive processes
        mov     -1,     0       ;/

silk    spl     3620,   #0      ;split to new copy
        mov.i   >-1,    }-1     ;copy self to new location

;this is another way to copy using multiple processes, the other one is a bit better because we can decrement the cell we are splitting to and, if we are lucky, kill an imp.

        mov.i   bomb,   >2005   ;linear bombing
        mov.i   bomb,   }2042   ;A-indirect bombing for anti-vamp
;The first bomb laid down acts as a pointer for the following stream, laying down a carpet.

        add.a   #50,     silk    ;distance new copy    
        jmp     silk,   <silk   ;reset source pointer, make new copy
bomb    dat.f   >2667,  >5334   ;anti-imp bomb

This is very effective against 3 points imp rings. A lucky hit on the executing process can kill many others; other kinds of bombs are used, by me at least, we'll discuss them another time.

Another time we'll discuss more advanced questions: another replicating engine, that is better than this one, and some other paper related topics like spread constants, bombs, strategies... 

---

Replicators (part 2)

Hi, happy to see you again.

Last time we spoke of basic replicator concepts, now I'll try to speak of some advanced topics.
To begin let's give a look at another replicating engine, the best one in my opinion, first introduced by Jippo Pohjalainen in its warrior Timescape.
We report slightly simplified, the way it has been proposed as White warrior by Nandor and Stefan in the tournament.

warrior
	spl	1,		<-200
	mov.i	-1,		0           ;this block generates 6 processes
	spl	1,		<-300

	
tim2	spl	@tim2, }TSTEP      
tim2a	mov.i	}tim2,	>tim2 

cel2	spl	@cel2,	}CSTEP  ;these four lines are the main body
cel2a	mov.i	}cel2,	>cel2
                                ;here you can insert some bombing line
ncl2a	mov.i	{cel2,	<ncl2
ncl2	jmp	@ncl2,	>NSTEP

All you know, having read part 1, how the first four lines work, they split away and copy the warrior body where the processes are going to execute, is worth noting that the lines cel2, cel2a don't copy  the warrior from the beginning but copy two blank lines in the bottom, after ncl2.
Line ncl2a copies again the warrior, fron cel2 to ncl2+2, backward because of the pre decrements and last line jumps to the beginning of this copy resetting the pointer.
The main advantage of this structure is that all the code is executed but once, to be left as a decoy to foul scanners; this is a great advantage compared with the older structure of the first hint. Another advantage is that the warrior will continue to work, slowed, even if wounded by a bomb in its last two lines.
This guy was the harder thing to kill before Paul Kline created Die Hard.
With this structure have been made some others replicators of success, worth mention are Nobody special by Mike Nonemacher and Marcia Trionfale by...me.

Now we have a solid structure to work on, to make it deadlier we can add some other form of attack than overwriting our opponent. The original Timescape has this single bombing line inserted after cel2a:

	mov.i	<-FSTEP,{FSTEP

how it works, remember we have some processes working in papallel: 
every process takes the cell -FSTEP away, decrements its b-field, take the cell pointed by and moves it in the position pointed by the decremented a-field of the cell FSTEP cells away. Simple? NO! :-)
OK. From the beginning:

        dat     0,0
-FSTEP  dat     0,0             ;will became dat 0,-1
...
        mov.i   <-FSTEP,{FSTEP  ;here we are
...
begin   mov     bomb,   nearme 
...     [enemy code]            ;Our enemy is here, we are lucky :-)             
end     jmp     begin           
        dat     0,0
FSTEP   dat     0,0             ;will became dat -1,0

Now 1st process takes the cell -FSTEP and decrements its b-field, takes the cell pointed by the decremented b-field (in the example the cell before) and moves it; where? It takes the cell FSTEP and decrements its a-field thake the cell pointed by it, here he hits. Missed, don't worry we have process 2 taking cell -FSTEP-2 and moving it at FSTEP-2 and so on till we have processes executing the bombing line. At the end the enemy is no more, in the example at least.

Bombing is useful not only to get rid of our enemy but also to get rid of ourself ... yes, enemy scanners have the bad use to cover our poor replicators with carpets of spl 0 and similar nasty things. Those bombs don't kill, but cause us to generate unuseful processes slowing down our spread. If we bomb with dat our old copies, that have a chance to be infected, we can reduce this effect; should happen we hit a good copy don't worry, we are so many that we can withstand a few losses.

Others warriors use different kind of bombs, more useful to kill our enemies, the drawback is that we have to carry the bomb with us. The bombing line will beacme:

        mov     bomb,   <target ;or > or { or }

now the first bomb laid down will become the pointer for the following carpet.
Most used bomb is the anti imp bomb
        dat     <-2666, <2667
this bomb is very good at killing 3 points imp ring, otherwise difficult to kill by replicators.
Another bomb I used with some success, in Jack in the box, is this simple one:
        dat     1,      1
This bomb is targeted against djn streams and forward clears, two forms of attack often used by paper enemies. The effect on streams is to make the process go ot of the loop, wasting time; the effect on forward clears is deadly, look at a simple forward clear

gate    dat     100,    1000    ;the clear is running 1000 cells away
....
clr     mov     bomb,   >gate   ;what's bomb don't matter, sure nothing with
        jmp     clr             ;a b-field of 1

If we hit gate with a dat 1,1 the clear will begin running inside itself, till it reaches  clr line and self destructs, very effective and very funny :-)

Like the bombing/scanning step for stones and scanners the spread constants can make the difference beetween a good and a bad warrior. You have to choose them so as to assure a good spread of the copies in the core. Corestep.c by Jay Han and Mopt by Stefan Strack, available at the FTP site, can give you a starting point, but for replicators the job is, far more complex because they change their constants in the spread process; let me explain with an example, same structure 4 parallel processes:

a       spl     @0,     100
b       mov     }-1,    >-1
c       mov     {d,     <d
d       jmp     @0,     >1000

First time lines a-b are executed they splits and copy 100 locations away but, when lines c-d copy them the value of b-field is 104, and so on. 
I don't know any mathematical method or optimization program to find best values and I look at what happens using pmarsv. If I notice that modules don't spread well I change something and so on, art more than science.
In the replicator I'm working at now I use a step modulo 200 for first constant (anything beetween 100 and 400 is good) a mod 20/40 for second one and ... my nose :-) for the last one.
Stefan Strack suggested a method using Pmars macros to automatize, in part at least, the search; here is what he says:

----------
A better way to optimize constants
is to run your warrior with pmars and use cdb macros that change code
sections and record the result. Suppose we want to optimize a slighly
"un-optimized" version of T.Hsu's Ryooki:

nxt_paper   equ     100 ;chosen with room for improvement

boot_paper  spl     1 ,>4000
            mov.i   -1,#0
            mov.i   -1,#0

paper       spl     @paper,<nxt_paper   ; A-fld is src, B-fld is dest
copy        mov.i   }paper,>paper
            mov.i   bomb  ,>paper       ; anti-imp
            mov.i   bomb  ,}800         ; anti-vampire
            jmn.f   @copy ,{paper
bomb        dat     <2667 ,<2667*2

and we want to find a better offset between copies than the "100" in the
nxt_paper EQU. First we need to come up with some good
ways to measure an even spread between paper bodies in core. Here's an
approximation that cdb can easily provide:

	after a few thousand cycles, a paper with a good offset
	1) has more processes
	2) covers more core locations
	than a paper with a bad offset

Now the idea is simply to run multiple rounds, systematically changing the
silk offset at the beginning of each round, and having cdb report process
number and number of covered core locations after 5000 cycles or so. This can
all be automated with macros, so you can have pmars find optimal constants
while you get coffee (jolt? :). Once you have a few candidate offsets, you
should make  sure they're working as you expect by looking at the core
display. You can than go on to find optimal bombing constants for your
set of optimal offsets in pretty much the same manner. As an example using
Ryooki above:

pmars -br 1000 -e ryooki.red
00000   SPL.B  $     1, >  4000
(cdb) 0,7
00000   SPL.B  $     1, >  4000
00001   MOV.I  $    -1, #     0
00002   MOV.I  $    -1, #     0
00003   SPL.B  @     0, < 100
00004   MOV.I  }    -1, >    -1
00005   MOV.I  $     3, >    -2
00006   MOV.I  $     2, }   800
00007   JMN.F  @    -3, {    -4
(cdb) calc i=99
99

This sets a variable "i" to our starting constant.

(cdb)@ed 3~spl @0,<i=i+1~@sk 5000~@pq~ca i,$+1~@pq off~m count~@go~@st
100,987
1830
(cdb)

This is a bit complicated. The "@ed 3~spl @0,<i=i+1" sequence edits address
3 and writes to it the instruction "SPL  @     0, <   100", having incremen-
ted the "i" variable by 1. "@sk 5000" executes 5000 cycles silently, "@pq"
then switches into "process queue" display/edit mode. "calc i,$+1" echoes
the current value of the "i" variable, followed by the number of processes
("$" is the number of the last process). The output is seen on the next line:
"100,987". "@pq off" then switches back into core display/edit mode.
"macro count" executes a macro that is already defined in pmars.mac; the
"count" macro simply echoes the number of core locations that have anything
other than "dat 0,0" in them (here: 1830). Finally, "@go~@st" advance to the
end of this round and to the first cycle of the next round.

When you now press <Enter>, the command sequence is repeated with an offset
value of 101:
(cdb) <Enter>
101,1058
1971
(cdb)
The 101 offset results in a greater number of processes (1058) and more 
addresses written to (1971). If you want to run the whole thing automated,
just inclose the command sequence in a loop (!!~...~!) and send the
results to a file like so:

(cdb) ca i=99
99
(cdb) write ryooki.opt
Opening logfile
(cdb) !!~&ed 3~spl @0,<i=i+1~&sk 5000~&pq~ca i,$+1~&pq off~m count~&go~&st~!

To avoid sending _a_lot_ of garbish output to the log file, we have to use & in stead of @ in this macro and in the macro count in pmars.mac; just edit it.

count= &ca z=.~m w?~&ca x=.,c=0~!!~m w?~&ca c=c+1~if .!=x~!~ca c~&l z
w?= &search ,
 
You can easily make this more complicated by only echoing
#processes/locations if the values are larger than anything so far (left as an
exercise to the reader), but at this point you are probably ready
to save yourself some typing by defining your own macros. Remember that
you can add macros from within the cdb session using the "@macro ,user"
command (a shorthand is "m="). You could even replace the rather simplistic
check for #processes/locations with a more elaborate macro that calculates
the variance of intervals between papers.

----------
Now we are ready to start making a paper warrior, what we have to do is putting things together and begin working.

First the structure, we'll make a mid-size warrior, 8 lines, so we need 8 processes.

start   spl     1,      <300    ;so we make 8 parallel processes
        spl     1,      <400    ;the <### are not needed to make it work
        spl     1,      <500    ;but may damage something and cost nothing

silk    spl     @0,     {dest0
	mov.i   }-1,    >-1 
silk1   spl     @0,     <dest1  
	mov.i   }-1,    >-1     
	mov.i   bomba,  }range
	mov     {silk1, <silk2
silk2   jmp     @0,     >dest2
bomba   dat     <2667,  <1

Now the constants: dest0 is the less used, let's take a modulo 200 value, for dest1 we take a mod 20 one. Now we begin optimization using Stefan method. I have a rather slow computer so I choosed to analyze but values ranging from -2000 to -1000. Before doing so I changed the mov bomb line in a nop instruction, optimizing bombing will come later.

Running Stefan's macro I got -1278 as best value.

Then I replaced the nop with a mov and runned again the macro, choosing a range for bombing beetween 500 and 1000. Best value 933

I put values in the warrior and submitted it to 94 hill: score: 125.98
Not bad, a little better than hand made one.

For you to enjoy here is the code to play with.

Boyz on the hill, ready your scanners. They are coming :-)

;redcode-94
;name paper01o
;author Beppe Bezzi
;strategy paper module, partially optimized with pmars

;assert CORESIZE == 8000

dest0   equ     2200
dest1   equ     3740
dest2   equ     -1278   ;pmars optimized
range   equ     933     ;pmars optimized

paper
	spl     1,      <300    ;\
	spl     1,      <400    ;-> generate 8 consecutive processes
	spl     1,      <500    ;/

silk    spl     @0,     {dest0
	mov.i   }-1,    >-1 
silk1   spl     @0,     <dest1  
	mov.i   }-1,    >-1     
	mov.i   bomba,  }range
	mov     {silk1, <silk2
silk2   jmp     @0,     >dest2
bomba   dat     <2667,  <1

end     paper

For next hint I would like a little input from you about the argument to be treated; my first choice is p-space followed by bombers, two arguments I know at least a little, having made some successful warriors, but I wish to hear from you.



The hint

P-space

Hi, 
this time we'll speak of p-space, the last tool, implemented by pmars08,
that allows our warrior to change strategy according to the history of the
match.
P-space is a protected area of memory, i.e. every warrior has its own
p-space and cannot read or write opponent's one. P-space hold but values,
not whole instructions, and is accessed by two specific instructions LDP and
STP load and store Pspace.
At the beginning of every round p-space cell 0 holds the result of previous
round, -1 at the very beginning, others cells hold the value they had at the
end of previous round, 0 at the start of the match. The value is 0 if we
lose, and the number of alive warriors if we survive; in standard one
against one matches those values are 1 for the win and 2 for the tie.

Warriors using p-space are called p-warriors or p-switchers; they store in a
location of p-space informations on the strategy they are using, at the end
of the round they evaluate the result of prvious round and, according to it
and, sometimes, the result of others rounds, continue with current strategy
or change to another, in the hope of doing better. In practice, if you are a
general, planning long term strategies, the switcher is your colonel,
deciding on battlefield what to use against your opponent.
It's important to say that even the best switching routine is worthless if
you don't have sound combat routines; if all you components lose against
your enemy, the mix will lose too, sometimes even worst because you lose
some time at the beginning to pplan the round, and to boot components away
from the big warrior body. 
P-space is a tool for intermediate players, not for beginners; until you
don't have at least two average level different warriors, a stone and a
paper for example, you cannot get anyhing good from it.

Now let's see how to assemble a p-warrior; first we need good components,
able to score points against different kind of enemies; we have them:
Paper01, to score against enemy bombers, juliet storm, to kill enemy
scanners; against enemy paper we are not defenceless, a paper usually cannot
beat another paper, so we should score:
Well against bombers, thanks Paper01
Well against scanners, thanks juliet
Ties against replicators, thanks Paper01.

Once chosen our hands, we have to assemble the brain; unless you want to do
something very complex, the switcher is not a difficult thing to do. Let's
give a look at a very simple one, and BTW successful, the switcher of Jack
in the Box, for three main reasons: it's one of my warriors, is doing well,
is the only one published :-)
Jack's has two components, a very heavy replicator, four times Paper01, and
a very fast bomber, Tornado. 
Its strategy is simple: the replicator scores lots of points against enemy
bombers but, because of the size, is rather vulnerable to scanners; well if
we are winning or tieing all right, we continue with the same strategy; if a
bad scanners happens to kill the paper, BOOH, Tornado pop up and with its
high speed and colored bombs kill him.
Here it's, very simple indeed.

        _RES    equ 0           ;here pmars loads results
        _STR    equ 1           ;here I store my strategy 

res     ldp.ab  _RES,   #0      ;load result last match
str     ldp.a   _STR,   str1    ;load strategy in use
	sne.ab  #0,     res     ;check result, win or tie OK
lost    add.a   #1,     str1    ;lost change
        mod.a   #2,     str1    ;secure jump     
win     stp.ab  str1,   _STR    ;save strategy
str1    jmp     @0,     juliet
        dat     0,      paper

We load in res.b the result of last match, in str1.a the strategy we used,
then we compare res to 0, if it's zero we add one to the strategy, if it's
different, tie or win, we don't. The mod instruction assure us to have a
value of 0 or 1.
At last we save new strategy for the round, and we jump at bomber or paper,
according to str1.a 
In 7 cycles we have finished, so even a Qscan has hard times to hang on.
Now the code, nothing more than taking the waariors, the switcher an putting
all together.

Last note, near to forget it, P-space has a 'dark side', brainwashing.
You cannot access your opponent p-space, but if you mage to force your
opponent, with a vampire attack, to execute these lines of code, or
something similar:

bwash   spl     0,>1                  
        stp.ab  #0,#0 
        jmp     -2,{-1
(usually this code is together with others spl and a core clear)

its p-space will soon fill of garbish and it's rather difficult that, in the
following round, its switcher will found what it needs to make a correct
decision. So, when you make your switcher, don't forget to think at what
will happens if something goes wrong in your p-space, and, _most_important_,
never forget to mod you STR value before executing the jump.

        mod     #2, 1
str     jmp     @0, paper       ;a field holds strategy
        dat     0,  juliet

If you forget it, may happens your warrior will have to execute something like

str     jmp     @1234,paper

and you will score something like 0/249/1 :-(

Here is the code. I submitted the warrior at both -94 and beginners hill, if
you have any question, or you are interested in results, mail me <bezzi@iol.it>
------------------------------
;redcode-b quiet
;name juliet and paper
;author M R Bremer, B. Bezzi
;strategy p-warrior for C.W. n.5 hint
;strategy switches juliet storm and Paper01
;kill juliet and paper
;assert CORESIZE == 8000

ptr     EQU 	-1333
dest0   equ     2200
dest1   equ     3740
dest2   equ     -1278   
range   equ     933

        RES    	equ 0           ;here pmars loads results
        STR    	equ 1           ;here I store my strategy 

imp_sz  equ     2667

org 	start

gate    dat <-445, <-446
s       spl #445, <-445
	spl #0, <-446
	mov {445-1, -445+2
	add -3, -1
	djn.f -2, <-2667-500
	mov 32, <-20
go      dat 	#0, 	#ptr
juliet	mov 	{-1, 	<-1
	mov 	{-2, 	<-2
	mov 	{-3, 	<-3
	mov 	{-4, 	<-4
	mov 	{-5, 	<-5
	mov 	{-6, 	<-6
	mov 	gate, 	ptr+24 
	mov 	gate,	ptr+24
	spl 	@go, 	<4000
	jmp 	boot, 	<4013
start

res     ldp.ab  RES,   	#0      ;load result last match
str     ldp.a   STR,   	str1    ;load strategy in use
	sne.ab  #0,     res     ;check result, win or tie OK
lost    add.a   #1,     str1    ;lost change
        mod.a   #2,     str1    ;secure jump     
win     stp.ab  str1,   _STR    ;save strategy
str1    jmp     @0,     juliet
        dat     0,      paper



paper
	spl     1,      <300    ;\
	spl     1,      <400    ;-> generate 8 consecutive processes
	spl     1,      <500  

silk    spl     @0,     {dest0
	mov.i   }-1,    >-1 
silk1   spl     @0,     <dest1  ;split to new copy
	mov.i   }-1,    >-1     ;copy self to new location
	mov.i   bomba,  }range
	mov     {silk1, <silk2
silk2   jmp     @0,     >dest2
bomba   dat     <2667,  <1

for MAXLENGTH-CURLINE-9
	dat	0,0
rof

boot    spl     1      ,#0
	spl     1      ,#0
	spl     <0     ,#vector+1
	djn.a   @vector,#0

imp     mov.i   #0,imp_sz

	jmp     imp+imp_sz*7,imp+imp_sz*6   
	jmp     imp+imp_sz*5,imp+imp_sz*4   
	jmp     imp+imp_sz*3,imp+imp_sz*2   
vector  jmp     imp+imp_sz  ,imp

	end
The Hint

Hello folks, last week Myers introduced the bomber topic with two classic
stones, Blue Funk and juliet storm; these guys are four-five lines long, and
found their effectiveness on their small size and resilience more than on
speed, they are both at 33% c, one bomb every three cycles, and
effectiveness of their bombs, simple dat 0,0.
There is another category of more complex bombers that balance the increased
size with a greater speed and/or deadlier bombs.

Who better than Paul Kline, Torch's author, can speak of this argument.

----------

Your basic 'stone' bomber is based on this fragment:

incr     spl  #step,#-step   <- self-splitter
         add  incr,1         <- step up the pointers
         mov  <0,0           <- decrement one and bomb the other
         djn  -2,<-10        <- loop and sequential decrement
         
Steven Morrell's discussion last issue showed how to optimize this for
maximum bombing duration, but his comment about Emerald is too generous.
I never realized or designed Emerald's pattern, it was just the best
of a large number of step sizes I tried.

Anyway, the above delivers one decrement and one bomb in three cycles.
However it is possible for the opponent to immunify part of his code to
decrements, and thereby reduce this bomber to something much less
than 66% effective speed.  A search through old programs (still a gold
mine!) turns up this one by Paul Kilroy:

;name Ike v.21
;author Paul S. Kilroy
;strategy A bomber with a cool twist

bomb	   spl 0   ,jump
ptr        dat #0  ,#0
inc        add #468,b
start      jmz inc ,@b
b          mov bomb,@464
           mov bomb,@b
jump       jmp inc
           mov 10  ,<-2
           end start

Which is your basic spl-bombing b-scanner with, as he says "a cool twist".
When he finds a non-zero location he uses it as a pointer and bombs through
it, then bombs the found location.  In other words, bombing two locations
without an intermediate ADD.

I was wanting to make this a pure non-scanning bomber, which is easy enough.
But the results were not exceptional.  With this code you get a nice 50%
hard bomber:

bomber   add   #step+step,2
         mov   bomb,@1
         mov   bomb,@0
         jmp   bomber
bomb     dat   #0,step
         
Unfortunately it is a little bigger than the 4-line version and not quite
as fast, even though it delivers real bombs instead of decrements.  It
becomes a little more durable with a leading SPL which keeps single
dat-bombs from killing it.  And it still loses completely to paper.

Anders Ivner's HeremII uses similar code to drop alternating spl and
dat-bombs that are very widely spaced in core.  HeremII works somewhat
against old style paper, but is helpless against Silk.

To kill paper requires some kind of spl-bomb that slows it down enough
to give a sequential clear time to wipe the whole core.  A split-carpet
like Agony's works very well, but this bombing routine won't accomodate
one.  A spl-jmp could be delivered by alternating spl's and jmp's, with
an eventual wrap-around to match spl's to jmp's.  But single spl's and
single jmp's are not only useless against today's paper, they are
actually dangerous, since they can mutate the opponent into a whole
lot of sequential core-clear/bombers.

Enter the mov-spl ('incendiary') bomb, which is a little two-line
program that you drop on the opponent causing him to write and
execute his own spl-carpet.  The important feature of this bomb is that
the components can be well separated - hence alternating bombs.  

Here is the working part of Torch 18, which bombs extensively with
mov-spl bombs, does one core wipe with a spl, then goes into a repeating
forward core-clear with dat.  It also has a nice feature in that if
it is overrun with a djn-stream it immediately starts the forward
dat-clear process, usually killing the nasty opponent.         
         
gate     dat   0,0
     for 3
         dat   0,0
     rof
w2       dat   -7,cp-gate+3
         dat   0,0
wipe     dat   -7,cp-gate+3
sp       spl   #-1-step,-step    ; spl half of the incendiary
in       sub   #step+step,@msp
msm      mov   sm,*tgt+(step*count)-17228
msp      mov   sp,@msm           ; bomb alternately with spl & mov
tgt      jmz   in,#0             ; bombed with spl to start clear
clr      mov   @cp,>gate
cp       djn.b clr,{wipe+1
     for 2
         dat   0,0
     rof
sm       mov   step+1,>step+1    ; mov half of the incendiary

Notice that in the inner loop the instructions are reversed from the
example - instructions following a SPL execute in reverse order.

Torch is bigger than a 4-line stone and will lose most of those battles.
However, those stones are paper-bait even with supporting imps while
Torch has the punch to stay on the Hill.  The current version also
uses a decoy to foil programs like Withershins Thrice and Porch Swing.

Questions for thought:
   What is the best 1-line bomb?
   What is the best 2-line bomb?
   What is the best 3-line bomb?

Answer correctly and you could go straight to the top of the heap .. uh Hill!
  
Paul Kline
pk6811s@acad.drake.edu

----------

Let's speak a bit of bombs; what is the best possible bomb?
The answer to this question is another question: who are you shooting at?

If our enemy is a single process, long warrior like a scanner the answer is
easy, no bomb at all... yes no bomb, taking a cell from somewhere in the
core, usually a dat 0,0 and throwing it in the middle of our enemy is enough
to kill him, and we have no need to include the bomb in our code, reducing
our size. This is the approach of Blue Funk and juliet.

If our enemy is a replicator this is pointless; we have no chance to kill
all paper bodies at the rate they spread. To kill them we have to slow them
first and, at the end deliver our deadly blow at wounded enemy, yes a very
evil act :-) This can be accomplished with more complex bombs either spl 0
followed by jmp -1, as Iron gate does when it finds a target, or with the so
called incendiary, 

        mov   step,  >step    ;alternated with
        spl   0,     -step+1

when the mov is executed it take the spl, step cells away, and moves it
immediatly after the mov itself; if the mov is executed by a multiprocess
paper the effect is creating a spl carpet. Devastating indeed.

If our enemy is a coreclear, something with a very reduced footprint like:

gate    dat     -20,20
wipe    spl     #-20,20

..

split   spl     0,0
move    mov     @1,>gate
jump    djn     -1,{wipe

A dat 0,0 hit at the gate, split or jump instruction won't stop the clear
running, we need something more effective like Tornado's bomb, (I have not
invented it, it's due to Paul Kline if I'm not wrong, I just used it)

        mov     step,1  ;step away there is another one

Using this bomb we have added to our target the 'split' line and the 'gate'
line, increasing our chances to kill.

To finish bombers argument I'll introduce now Tornado, the faster pure
bomber and, BTW, one of my favourite babies. It has never had a great
success alone, its best version stayed on hill little more than 200
challenges, never climbing higher than 10th position, but proved very
effective as component of successful warrior like Jack in the box.

Tornado pushes the indirect bombing one step farther, he lays down two bombs
and uses the second one as pointer for the third reaching a speed of 60% c,
three bombs in a five instruction loop.
This is the version included as scanner/clear killer in the p-warrior Jack
in the box

step    equ     95
count   equ     533

bomber  mov     bd,     *stone
	mov     bm      @stone
stone   mov     *step+2,*(2*step)+2 

stone line is the hearth of the bomber. It can be changed slightly if we
want to use bombs with fixed a or b fields of values different from the step
What's important is that the bomb addressed by b field of stone had one of
its fields with the value step
        
	add     incr,   stone           
jump    djn.b   bomber, #count

Three bombs in a 5 instructions loop means 60% c speed, comparable with that
of a cmp scanner (66%c) and without any problem of being delayed by decoys
and bomb's color. In fact Tornado easily kills any scanner and clear

incr    spl     #3*step,#3*step        
clr     mov     -12,    }bomber+1
djmp    jmp     clr,    <bomber-5

This is not the best clear, giving no imp protection, is those with the
smallest footprint using the bombs as pointers.

..[some empty lines]

bm      mov     step,   1       ;have care that bm be overwritten by another bm
bd      dat     #step, #1

Tornado drops a dat, then a mov step cells away, then takes this mov and
drops it step cells away from it before adding and jumping.
Once finished the run there is a dat bombs 12 cells before the clr line,
this is used to clear core.
This is not the most effective all purpose version of Tornado, v1.8
alternate spl and mov and uses a multipass clear to better resist paper
attacks and a > clear to try catching imps, but is the best fit for the role
of 'scanners/clears killer' in the p-warrior.
Tweaking a litle the code Tornado can be armed with incendiary bombs too;
the incendiary version has been submitted to the hill as Firestorm, and was
included in the p-warrior Brain Wash.

The hint
How to improve your beginner's warrior.

This week hint is again an how to improve a warrior; having received no
warrior I was able to improve :-), I toke a warrior of a six months ago
beginner, good in the -b hill but unable to enter 94: Provascan 2.0 by ...
me :-)

Here is Provascan code, 'prova' in italian means test, a tweaking of XTC a
very successful warrior of a few years ago, and a classic sample of
beginner's coding (Provascan not XTC :-)

;redcode-94
;name Provascan 2.0
;author Beppe Bezzi
;strategy B-scanner
;strategy a six months ago beginner's warrior :-)
;kill Provascan
;assert CORESIZE == 8000 
;  
step    equ #3364
loop    add.ab step,    ptr ;scanner modulo 4
ptr     jmz loop,       trap
	mov ptr,        dest
cnt     mov #17,        cnt     ;0
kill    mov @trap,      <dest
	djn kill,       cnt
	jmn loop,       trap    
	jmp cocl                ;0
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0                  ;0
	dat 0,0
dest    dat 0,0
	dat 0,0                  
	dat 0,0                  ;0
	dat 0,0
	dat 0,0
	dat 0,0
trap    dat #1                  ;0
bomb    spl 0
	dat 0,0
	dat 0,0
	dat 0,0                  ;0
	dat 0,0
	dat 0,0
gate    dat 0,0
	dat 0,0                  ;0
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0                  ;0
cocl    sub #15,       cont    
	mov cocl-4,    <cocl-4
	djn -1,        cont
cont    spl 1 ,<0               ;0
	spl 0,<gate    
	mov mark,<cocl-1
	jmp -1,<gate
	dat 0,0                 ;0
mark    dat <-11, <-11
void    for 35                  
	dat 0,0
	rof
esca    for 4
	dat 0,2
	dat 0,2
	dat 0,2
	dat 0,0
	rof
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0
	dat 0,0
end loop

lines with ;0 must have a zero b-field to avoid self bombing.

It's a classic b-scanner that covers nonzero locations with a wide carpet of
spl 0,0 until it covers the label trap; at such point it begins a coreclear
with spl and then dats, ugly indeed, but I was a beginner :-)

I resubmitted it to 94 hill and I scored a nice 109, just what I needed to
start with. The idea of a carpet bombing b-scanner isn't that bad, the
implementation is really nasty, we can cut it _a lot_ and have it make the
same work, 17 is a too big number for the carpet, a smaller one, 7, is sure
better, so we are not delayed too much by decoys. Another improvement is
using the post increment for bombing, better with imps and allowing us
another trick we'll speak of later, and adding a forward running perpetual
clear; 
The new code:

name author blah blah ...
;  
step    equ 	#3364

trap	dat	0,	1	;0
	dat	0,	0
dest	dat	0,	0
	dat	0,	0
	dat	0,	0	;0

;the use of postincrement allow us to put dest before our code

loop    add.ab 	step,   ptr
ptr     jmz 	loop,	trap
	mov.b 	ptr,    dest
cnt     mov 	#7,	0	;0
kill    mov 	bomb,	>dest
	djn 	kill,	cnt
	jmn 	loop,	trap    
bomb	spl	#0,	0	;0
	mov	2,	>ptr
	djn.f	-1,	{ptr
	dat 	-5,	#15
end loop

Much better, isn't it, now we are but 10 lines long plus two dats nonzero.
We have not to worry of self bombing when we bomb dest to end scanning,
because moving a spl 0,0 at a cell addressed with > is uneventful, the cell
is overwritten with zero after the increment, because of 'in register'
evaluation.

With a bit more confidence I resubmitted it to pizza 94 to score a 121,
better but not enough, something is still going wrong. 
We lose a lot from Frontwards, Porch Swing and others once through scanners,
and we cannot stop Impfinity and Night Train's imps. To solve the first
problem the solution is simple, boot away and leave a decoy behind; for
second problem the solution is more subtle. Let's give a look at our clear:
we are using 'ptr' as clear pointer, when imps get incremented and attacked,
they stop being imps but begin executing our code, so we cannot kill them;
to do so we must have a dat after the clear pointer; we can use the line
'dest', it will be split covered but it's goo for our job.

New version:

;redcode-94
;name Provascan 2.0d
;author Beppe Bezzi
;strategy B-scanner
;strategy a six months ago beginner's warrior :-)
;strategy trying to improve it for the hint
;kill Provascan
;assert CORESIZE == 8000 
;  
step    equ 	#3364 
away	equ	3198

trap	dat	0,	0	;0
	dat	0,	0       ;we can use equs for those dat 0,0 they are left
dest	dat	0,	0       ;for clarity
	dat	0,	0
	dat	0,	0	;0
loop    add.ab 	step,   ptr 	;
ptr     jmz 	loop,	trap
	mov.b 	ptr,    dest
cnt     mov 	#7,	0	;0
clear	mov 	bomb,	>dest
	djn 	clear,	cnt
	jmn 	loop,	trap    
bomb	spl	#0,	0	;0
	mov	2,	>dest
	djn.f	-1,	{dest
kill	dat 	-5,	#kill-dest+2
	dat	0,	0	;0

boot	mov	kill,	away
for 10
	mov	{boot,	<boot          ;the faster way to boot away
rof
	mov	#0,	boot+3         ;we have to set those b-fields to zero
	mov	#0,	boot+7         ;to save time later
	mov	#0,	boot+11
jump	jmp	@boot,	>away-29       ;> is to set trap b-field non zero

a for (MAXLENGTH-CURLINE)/4
	dat	jump,	0              ;this decoy doesn't have two equal cells
	dat	bomb,	boot           ;and still has all fourth b-field at zero
	dat	boot,	kill
	dat	clear,	boot
rof
end boot

Results are good now: 136.5 and 11th place in 94 hill, yuppee :-)

We beat Frontwards and La Bomba, we tie Impfinity, Porch Swing2, and Torch
and we score an high nuber of wins that boost our score, it's better losing
45/55/0, as we did against Derision, than scoring 100 ties. We are still
losing bad against quiz, solving this problem is left as an exercise for the
reader :-)
BTW it's my best ever result with a scanner, were it not the hint test I'm
not sure I had published it. ;-)

The hint
Steps

Bombing and scanning steps are an important choice to make when coding a warrior; the right choice may be the thing that change your score of many positions in the hill, and require a bit of wisdom.
Having to bomb, for example, every fourth cell of core (modulo 4) we can choose any number with 4 as greater common divisor with Coresize, but results are greatly different if we choose a bad or a good one.
Using four as step against a twelve lines long opponent, makes us bomb it thrice every time we bomb it once, a sort of overkill that's not needed in most cases; our oponent instead, using a smarter step and better spreading its bombs may bomb us but once three times as often. Result: 75/25 for him :-(

Number theory help us in our choice, even if, as usual in corewar, there is not a best choice but a sort of tradeoff.

Steven Morrell so speaks in its book:
----
One factor that could mean the difference between a top-rate stone and an
unsuccessful stone is the choice of step size.  The program that manages to
bomb the enemy first has a decided advantage, and some bombing step sizes
are more efficient at scanning for the enemy than others.  So what makes a
good step size?

Ideally, it ought to hit every location in 8000 bombs, every other location
in 8000/2=4000 bombs, every third location in 8000/3=2667 bombs, etc.
Unfortunately, this is impossible, especially with a single step size, but
it suggests a basic strategy -- go for the biggest programs first and then
fill in the gaps.

One way of rating the efficiency of a step size is to find the length of
the largest unbombed section of code after each bomb is dropped.  By adding
up all of these lengths, we get a number that tells us how big an average
gap is.  (Indeed, by dividing this number by the number of bombs dropped,
we get the average gap size.)  If we minimize this number over all step
sizes, we get the "Optima Numbers."  For a coresize of 8000, these optima
numbers are:

    mod-1  3359/3039  under-100 -> 73
    mod-2  3094/2234  under-100 -> 98
    mod-4  3364/3044  under-100 -> 76
    mod-5  3315/2365  under-100 -> 95
    mod-8  2936/2376
    mod-10 2930/2430

Another common rating is how closely to in half the new bomb subdivides the
old gap when it is dropped.  By taking the differences between where the
bombs fall and the middle of each gap and adding these distances up, we get
an alternate method for testing efficiency.

Both of these methods are useful for finding general-purpose step sizes.
But suppose you wanted to find a step size optimized for killing other
stones.  Since stones usually have four or five instructions, you would
want a step size that would bomb every 4th and 5th instruction quickly,
regardless of how it does in general.

Fortunately, there is a program in the public domain that calculates all
of these things quicky:
Corestep by Jay Han can be found as
misc/corestep.c, and calcutates optima numbers and optimal step sizes.
You will need a C compiler to use it, but it is otherwise self-contained.
For more infromation, FTP a copy and read through it.  The classic formula
calculates optima numbers, the alternate formula calculates the sum of the
distances between bombs and midpoints, and find-X calculates optimal step
sizes against a specific program length.

If you don't have access to a C compiler or want this for some other
reason, P. Kline has compiled a list of all 8000 step-sizes with their mod,
find-4, find-5, find-10, and find-13 numbers, along with imp-killing
constants and imp-numbers.  This table is designed for use in spreadsheets
or databases. It is available in the misc/ directory under the name num8000.txt
---

If you look at the steps of published warriors you can notice that the optima numbers are not always used and smaller steps are usually preferred; the reason of this  is mainly because there is no nedd to quickly find a 500 lines long target and a small step can be used as a gate, or as pointer in the clear, saving some space.

How to choose, beetween some good number, the one to use is often a matter of choice. The modulo has to be chosen according to the size of our warrior, in such a way as not to bomb ourself; once chosen it we have to select a target size: tiny (5 lines), small (around 10 lines), average (around 13/15) and select a number with a good find for our target, and an average one for the others. In our choice we have to consider the mod 1 numbers with a good find for our selected modulo. They have bombing patterns a
pproximating closely the one we want, and usually end bombing the cell immediately before or after the one we start with.

The Hint 
Spiral and Stargate

It's not Science Fiction, it's still corewar; Spiral is an imp spiral and
Stargate is my nickname for the clear:

gate    dat     stun,   100
..
stun    spl     #kill-gate, 100
clr     mov     *gate,      >gate
        djn     clr,        {nnn
kill    dat     kill-gate,  100

this come from the instuction mov *gate,>gate; being 'asterisk' too long, I
like to call it 'star'
This clear is simple and very good against silk, with his djn.f stream; I
always considered it good against imps too, but I had to change my mind.
Forward running clears are usually good against spirals because, when an imp
instryction overwrites gate it transfers the attack to the next process, it
works with imp instructions like Blue Funk's one

        mov.i   #3044,  2667

but if we use an instruction of the form:

        mov.i   #-5,    2667    ;any small negative value is good

the clear will copy an imp instruction over the next imp instruction, and
this is not the best way to kill a spiral.:-)

To be effective we have to use this other clear I used in my last Tornado.

gate1

..
   
gate	dat     -25,    last-gate1+3
bombs   spl     #-step, step
..
jump    spl     #nn,    #nn
clr     mov     @djmp,  >gate1
djmp    djn.b   clr,    {bombs
last

Being sure to have some space beetween gate1 and our code. In this way we
are sure to move a dat instruction over the next process and avoid the
spiral crashing our gate.

The increase in performances is real, against Impfinity for example:

Tornado 2.0 h1 wins: 25 ;uses Stargate clear
Impfinity v4g1 wins: 91
Ties: 84

Tornado 2.3 wins: 75    ;uses new clear
Impfinity v4g1 wins: 61
Ties: 64

It right to say that the clear used by Tornado 2.3 is the same used by
Torch, another code snippet I have stolen from Paul, and that the
improvement against Impfinity is not all thanks the clear, new code is
stronger, more decrement resistant, and one line shorter; I'll post it but
not today. ;-)

The drawback, there is always a drawback, is that the djn.b is less
effective against silk and, if we use djn.f instead we'll end jumping to our
spl, and this will reduce the anti imp effectiveness having some delays
beetween executions of the mov that the imp can use to slip through.

Again the last hint is: test this one and the other one against some
published warrior, looking when one is better and when the other one. 
Stepping while the imp is overwriting the clear is a good exercise, you can
use sk 500 till the spiral is near, then use sk 1 to position in the leading
process of the spiral and ctrl-t to advance the spiral step by step.


The Hint 
The defence.

What is the defence ? it's using part of your resources not to damage you
enemy but to avoid it damage you; in soccer and basketball the defence is as
much important as attack is, if not more, same in Corewar even if the
scoring system gives some advantage to attack.

A defence only warrior, even if a perfect one, has no chances to make the
hill being an all ties score too low, but some form of defence is needed and
the right balance can help you score better and live longer on the hill.

Let's give a look at some forms of defence, how well they work and how much
they cost in terms of resources expended.

-------
Self splitting

If we add a spl 0 instruction on top of a stone we have some advantages:

A hit in the first or the last line don't stop it working, we accumulate
processes so as an imp spiral won't kill but only tie us, we can use a djn
stream because a process falling off it won't kill us and we can couple an
imp spiral to our bomber

This is payed somewere because:
We have larger footprint for a scanner to find and there is slight speed
reduction.

The sum of advantages is more than those of disadvanages so, in practice,
every stone is self splitting and some use even more process eating
structure to accumulate processes even faster, see Cannonade, Impfinity and
juliet storm for examples.

---
Adding imps

In 94 imps are used more for survival than for attack; adding imp spirals to
stones and replicators my get them much harder to kill for a replicator,
without reducing too much their offensive potential. The drawback is that a
stun attack on the spiral can have a negative effect on the stone, so the
number of wins is reduced.

---
Boot and decoy

Booting away from a decoy is a common form of defence against scanner, very
effective against one shoot like Frontwards and Porch Swing if you have a
good way to attack a core clear of course. There are very little negative
effects for bombers, apart the time spent booting away, but it's difficult
to make a decoy invisible to your own scanner, Agony II is the only cmp
scanner I know using this tecnique.

Some warriors now use a decoymaker instead of booting, i.e. they add at the
beginning some lines like
mov     <xx,    <yy
creating a pattern of dat 0,1 good to trigger one shot scanners; another
advantage is that, in the meantime, you drop some bombs. The drawback is
that this decoy is less effective against opponent cmp scanners, the colored
cells are not many, and that a qscan can find the decoymaker and from it
bomb the warrior too.

---
Active decoys

It's a tecnique I use from long and I always kept secret, but having Robert
published it in his warrior Mason I have to unveil my secret ;-)
There is no nedd to use dats to make your decoy, if you use spl #xx,yy
instructions instead you can sometimes manage to stun wounded silk modules
that happen to land here; the cost is nothing and you can gain a few points.
I f you like you can insert a few stp instruction, to try brainwashing a
pspacer, or even some mov -10,<3000 instruction to make your enemy create a
spl #0 carpet somewere in core; just be careful not to be here :-)

Is a good thing if you insert some $$$ 1,1 line to stop djn streams and
erase your boot pointer, a mov bomb, >xx hitting it can have devastating
effects.

---
Pspace

Should your warrior score very good against one opponent class but be
useless against another, you can switch it with something else, able to
score against your enemy; obviously using pspace has its weaknesses:
brainwash and slow startup.

---
djn defence

It's sometimes good to have a jmp clear+1 line leading your warrior; should
it be decremented by a stream it will jump to the core clear that, if well
made, will work even if decremented.


The Hint
Memories

Memories is my first cmp scanner of success, having climbed, in one of its previous versions, up to the top position. I started it as a 94 improvement of the classic Iron gate, but, tweaking here and there, it's now like my old knife I changed three times the blade and twice the handle but it's always my old knife. :-)

The article is a bit long, but shows how to, or better how I, work to make a warrior. Prepare your coffee, Italian of course, and be sure to have cigarettes for the night. 

Scanners are the kind of warriors that look at core and attack it only when they find something. They can be divided in two big subclasses, according to the instruction they use to scan the core: cmp scanners and jmz (most usually jmz.b) scanners.

Scanner's code is composed by three parts: scan, attack and clear. The clear is a must because usually scanners don't kill the enemy with their attacks but drop bombs that make it generate many processes, the so called stun attack; so we have to kill them filling core with dats once finished our scan routine.

Wishing to make a cmp scanner I started with Wayne Sheppard's Iron Gate, an 88 classic scoring more than 900 age in the 94 hill too. Here is is code:

;redcode-94
;name Iron Gate
;author Wayne Sheppard
;strategy cmp scanner-SPL/JMP-Gate

dist 	equ 73
scan 	equ dist*2     
     
     	add 	off,	@x      ;Scan block. It exits the b-field of the cmp
loc  	cmp 	dist-1,	-1      ;instruction if the lines pointed by the cmp 
     	slt 	#14,	@x      ;itself are different
     	djn 	-3,	<7000

     	mov 	j,	@loc    ;Attack block. Drops a spl 0/ jmp -1 bomb and
x    	mov 	s,	<loc    ;restore value of b-field
     	sub 	new,	@x
     	jmn 	loc,	loc-1   ;attacking loc-1 line starts the core clear

s    	spl 	#0,	<1-dist ;core clear that end in an imp gate
     	mov 	2,	<-2
j    	jmp 	-1
new  	dat 	<0-dist,<0-dist-1
off  	dat 	<scan,	<scan
end

Worth noting is the use of indirect addressing @x every time we have to refer to label 'loc' That's because doing such way, should any of those @x be decremented, the warrior will continue working unhindered because the line x-1 is pointing 'loc' too

Iron Gate hs been very successful in 88 and early 94, before silk paper come in use, but now it has to be enhanced some way to compete with newer warriors. First step was changing the bomb, from spl/jmp to spl/spl/jmp for a better stunning of enemy (see previous number hint) another improvement was changing the clear from backward running to continual forward running using > addressing.
Having a jmp -2 line to be used for the bomb I added a mov in the clear, making it faster, even if more vulnerable. Here is first Memories version:

[header omitted]


dist    equ     229     ;not the real one
scan    equ     dist*2     
safe    equ     (kill-first+2)
stun    equ     kill+30

	jmp     s+1             ;jmp to clear if hit by djn stream
first   add     off,    @x      ;scan part is the same as Iron Gate
loc     cmp.f   dist-1, -1      ;Only removed the djn stream to keep core clean
	slt     #safe,  @x      ;mostly for lazyness :-)
	jmp     first          

	mov     j,      @loc   ;attack block drops a wider bomb
x       mov     stun,   <loc   ;notice that we are protected from increment
	mov     stun,   <loc   ;not only decrement
	sub     s,      @x
	jmn.b   loc,    loc-1  

s       spl     #-dist, <-dist-2
	mov     kill,   >first-1  ;forward running dat clear
	mov     kill,   >first-1
j       jmp     -2,     #0
off     dat     <scan,  <scan
kill    dat     <2667,  kill-first+6

for 5
	dat     0,0
rof
for MAXLENGTH-CURLINE-12
	spl     #0,#0          ;Active decoy; gain with paper lose with qscan
rof

The use of one of the spl #0 of the decoy as stun is needed to avoid self triggering.
Memories is bigger than Iron gate and has the same speed, this is balanced by better bombs and clear. It made the 94 hill in the top 10 positions.

Second evolution was increasing the scan speed. Being 16 lines long with a speed of .66 c we have a size speed ratio of 24, very bad compared with those of bombers like Tornado. Big we are, why not being bigger but faster? adding two lines we can scan at .8 c and reduce our size/speed ratio to 22.5 I also added a decoymaker for Frontwards pleasure :-) Here is the enhanced version:

org     dmake

dist    equ     509
scan    equ     dist*2     
safe    equ     (last-first+1) ;decoy maker is protected
clzone	equ     (stun-first+1)
decoy   equ     -2000
dst     equ     13*4

	jmp     s+1
first   add     off,    @x      ;80%c scan engine
loc     sne.f   dist-1, -1
	add     off,    @x
	seq.f   *loc,   @loc
	slt     #safe,  @x
	jmp     first
	mov     j,      @loc
x       mov     stun,   <loc
	mov     stun,   <loc
	sub     s,      @x
	jmn.b   @x,     loc-1
s       spl     #-dist, <-dist-2
	mov     kill,   >first-1
	mov     kill,   >first-1
j       jmp     -2,     #0
off     dat     <scan,  <scan
kill    dat     <2667,  clzone

for 7
	dat     0,0
rof
stun    spl     #0,     0
for MAXLENGTH-CURLINE-12
	spl     #0,     #0
rof

dmake           ;half the decoy is reflected at dist and invisible for me
a for 11
	mov    <decoy+a*dst, <decoy+dist+a*dst
rof
last
	jmp     first
end

This version scored King, but then come Clisson and Paul's 'Spirals and Harmony' posting. While this version is very good against 3 pts continual imps like Night Train it's powerless against Clisson that includes a paper imp with 7+ pts So, to keep pace I had to fit a spiral clear in it, increasing imp killing power at expense of being even more fragile. The clear is like the one published by JKW in SETI, slightly modified.
Other enhancement are one more spl in the bomb, to better contrast paper, and the use of jmn at the end of the scan loop, not to jmp if 'first' is zero. All those details added 1.5 points to total score. The jmp to clear if decremented line is pointless now, the spiral clear is suicidal if decremented :-(

This is Memories as is now on the hill, as you can see it doesn't look like Iron Gate, or first Memories version anymore, but it's still the same warrior :-)

;redcode-94
;name Memories
;author Beppe Bezzi
;strategy cmp scanner like Iron Gate
;strategy with spl spl jmp bombs and 94 improvements
;strategy v06 changed to sne/seq scan engine
;strategy v a01 spiral clear; v b* c* super clear
;strategy v d08 details
;assert 1
;kill Memories

org     dmake

dist    equ     239             :not true
scan    equ     dist*2     
safe    equ     (last-first+1)
clzone  equ     (stun-first+1)
decoy   equ     -2345           ;not true
dst     equ     13*4
ISTEP   equ     381

first   sub     off,    @x
loc     sne.f   dist-1+scan, -1+scan
	sub     off,    @x
	seq.f   *loc,   @loc
	slt     #safe,  @x
	jmn.f   first,  first
	mov     j,      @loc
x       mov     stun,   <loc
	mov     stun,   <loc
	mov     stun,   <loc
	sub     s,      @x
	jmn.b   @x,     first
	add.a   #ISTEP+1,cpt
	mov     @-1,    {cpt
j       jmp     -2,     #0
off     dat     -scan,  -scan
cpt     spl     #2,     #3
kill
s       spl     #-dist, -dist-3

for 7
	dat     0,0
rof
stun    spl     #0,     0

for MAXLENGTH-CURLINE-12
	spl     #0,     #0
rof

dmake
a for 11
	mov     {decoy+a*dst,   {decoy+dist+a*dst
rof
last
	jmp     loc
end

