0% found this document useful (0 votes)
205 views20 pages

Core War Hints

The document provides hints for improving replicator warriors and core clearing strategies. It examines the code of the warrior "Mutagen" as a case study, identifying areas that could be made more efficient. These include shortening scanning code, spreading out scans, and implementing multi-pass core clearing by reusing movement instructions and changing the bomb and pointer over multiple passes through core memory.

Uploaded by

hisohiso
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
205 views20 pages

Core War Hints

The document provides hints for improving replicator warriors and core clearing strategies. It examines the code of the warrior "Mutagen" as a case study, identifying areas that could be made more efficient. These include shortening scanning code, spreading out scans, and implementing multi-pass core clearing by reusing movement instructions and changing the bomb and pointer over multiple passes through core memory.

Uploaded by

hisohiso
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

hints.

txt Mon May 27 17:44:18 2002 1


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 lets 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.
Lets 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 whats 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 its 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, its
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.
Its 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
hints.txt Mon May 27 17:44:18 2002 2
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, well discuss them another time.
Another time well discuss more advanced questions: another replicating
engine, that is better than this one, and some other paper related topics
like spread constants, bombs, strategies...
For questions mail me <[email protected]> or if you think its of general
interest post to rec.games.corewar
Anyone with hints or warriors to publish is welcome.
The hint
Do you often ask yourself: Why do my warriors do well on the beginners
and get thrashed on the 94 draft hill? This hint should help all newcomers
in writing more viable code.
I have asked the 15th place author to send me his warrior so we can dissect
it as a case study. Thanks to Scott Manley for sharing his code. If you
are in 15th place around the end of the week, you could be getting mail from
me. Unfortunately, Mutagen has dropped off the hill, but I suspect that
Scott will have a brand new version real soon.
;redcode-b
;name Mutagen
;author Scott Manley
;strategy Scan -> SPL/JMP bomb -> split to Imp gate / 2 pass forward
;strategy travelling core clear
;assert CORESIZE==8000
plength EQU 35
inc EQU 6
carpet EQU (CORESIZE-MINDISTANCE)/inc
adds DAT #inc , #inc
begin SPL clear2
start SEQ.I *scan, @scan
JMP scan1
cont ADD.F adds , scan
DJN start , count
JMP clear3
scan1 MOV sbomb , * scan
scan2 MOV sbomb2 , @ scan
hints.txt Mon May 27 17:44:18 2002 3
JMP cont
scan DAT MINDISTANCE-10 , MINDISTANCE-9
target1 DAT 23 , -23
target2 DAT 22 , -22
target3 DAT -1 , -21
target4 DAT -2 , -20
DAT 0 , 0
DAT 0 , 0
DAT 0 , 0
JMP 0 , } cont
clear2 MOV.I sbomb , } target1
DJN clear2 , target1
JMP clear4
clear3 MOV.I target2 , } target2
DJN clear3 , target2
clear1 MOV.I target4 , { target4
DJN clear1 , target4
JMP 0 , > -10
clear4 MOV.I sbomb , { target3
DJN clear4 , target3
MOV 0,1
sbomb SPL 0 , 0
sbomb2 JMP -1
count DAT #carpet-1,#carpet-1
END begin
The basic concept is to scan and spl coreclear simultaneously. Once
the scan is finished (one pass through core), jump to a dat coreclear to
follow the spl clear. There are other startegies involved but well just
focus on the scan engine and multi-pass coreclear.
Mutagens scan is 11 lines long--13 lines if the stun bomb is included in
the count. We can reduce the length a bit without affecting the behavior
too much by using the following code:
add.f split, scan
scan sne.i loc1, loc+1
djn.f -2, <DJNSTREAM1 ;djn.f will decrement both the a and b field.
mov.i split, *scan
mov.i jump, @scan
djn.f -5, <DJNSTREAM2 ;need to have a trigger so this falls thourgh
jmp clear ;after scan is complete.
split spl #step, #step ;try to find other uses for these
jump jmp -1 ;can be anywhere in code
Remember that the bigger your executing code is, the more inviting target
you make to the enemy. The split and jump lines can be moved away from the
executing code to provide the smallest possible profile. Also: the scanning
step is not optimal. If an enemy instruction is at location N, most likely
there will be another instruction at N+1. So there is no need to scan there.
There are two basic ways to spread the scan out. One is to scan N and N+step
then bomb every location in between. Another is to bomb N and then check
N+step in a separate step. Check out Agony and Irongate for good examples
of these two methods.
Next lets talk multi-pass coreclears. Muatagens clear is lengthy and easy
prey for scanners. In a multi-pass coreclear, only a few things change--the
bomb being swept through core and the pointer that does it. We can reuse
the movement instructions and just change the bomb and pointer with this
code:
org a1
ptr1 dat a1, end+100
a4 dat 0, end+2+1
a3 dat 1, end+2+2
a2 spl #2, end+2+3 ; spl #X, <-Y acts like a split 0.
a1 spl #3, end+2+4 ; you can use x and Y as step values
mov *ptr1, >ptr1 ; and use the decrement in the b-field
mov *ptr1, >ptr1 ; as part of an imp gate.
mov *ptr1, >ptr1 ; > (post-increment) keeps adding 1 to
hints.txt Mon May 27 17:44:18 2002 4
end djn.f -3, <4000 ; the b-field of ptr1 to move the bomb
; through core.
The clear starts with a1 being swept forward through core. Notice that the
move instructions use a pointer (ptr1) to determine which bomb to sweep with.
ptr1s b-field is also used to do the actual clearing. When the clear wraps
around the core, it will eventually overwrite ptr1 with a1. Now the move
instructions will look where the old ptr1 used to be to find what they should
move through core. The new ptr1 (a1) points towards a2, so the move
instructions will move a2 through core. The new pointer also has a new
b-field. The value of this b-field ensures that the clear skips over the
core clear code. Then a2 overwrites the pointer. The pointer is now
points to a3. And so on. This code will continue to clear until time run
out.
7 44/ 38/ 18 Hint Test M R Bremer 151 5
A simple version of these improvements has been submitted to the beginner
hill. The code does reasonably well against bombers and replicators, but
its large size makes it vulnerable to scanners. A good project would be
to pspace it with a small fast bomber.
______________________________________________________________________________
Extra Extra:
P.Kline usually publishes his warriors fairly quickly. However Die Hard has
been a mystery for quite some time. Magnus Paulsson is one of the few
authors who has had some success against the many interations of Die Hard.
Paulsson has been kind enough to share his thoughts ( along with his newest
program--theMystery ) with us:
How does Die Hard work?
That thought came to mind when some version of myVamp didnt score more than
1% wins! It was double disturbing as myVamp has a coreclear spl/spl/dat and
a djn stream at the same time, no normal imp could survive it (nothing else
either if lucky).
Why is that?
If you get the other program in such a clear it will fast spl it self to 8000
processes. No you have about 8000 cycles and then the imp spiral will
execute. In my coreclear I change a location in core every cycle which means
that when the imp-spiral execute it is (should be) overwritten/djned already.
What then?
Now if you place two spirals on top of each other, and plan in which order
they and the rest of the code will be in the execution. In the coreclear the
spl processes will be like 4000 processes, spiral, 4000 processes, spiral.
That means the clear has to kill spiral in 4000 cycles which isnt possible
in a clear.

Is that how Die Hard works?
(Actually I dont know :-) But Ill keep on guessing for a while.)
So, because there is a thing called gate which kills spirals. In order to tie
you have to have something like 100 processes in a spiral to slow it down as
much that it doesnt reach the gate. Now you cant launch such a monster
without getting killed before the launch is complete.
How then?
Have a look at theMystery!
It is three papers working together to launch imp-rings in such a way that
there will never be more that say 1500 cycles between a ring is executed.
What is the diffrence between Die Hard and theMystery?
Die Hard is a lot better :-(, I dont know how Paul did it but theMystery
doesnt kill anything! (Im totaly wortless on papers, I cant get the
constants right and its to bloody complicated to get a paper effective.)
Actually I dont belive that theMystery could ever beat anything 20%,
maybee Paul has taken the idea one step further? (stone?)
(Now I resubmitted theMystery1.5 to the hill and it wins 17% :-)
15 25/ 19/ 57 Die Hard P.Kline 131 3
hints.txt Mon May 27 17:44:18 2002 5
..
20 17/ 7/ 76 theMystery1.5 Paulsson 127 1
/Magnus Paulsson
(More fun to write this than to think about Peierls substitution)
(I should heve mentioned CottonDH (J.Wilkinson) but I wont :-) )
______________________________________________________________________________
Paul responds:
Magnus approach is intriguing. Lots of ties but not many wins, which
is about where Die Hard was until I worked in some bombing. Not much but
enough to pump up the score and move him up the Hill. Die Hard doesnt
look much like theMystery, but his kernel is based on something I published
a looong time ago.
Another tidbit about Die Hard. He starts with a very brief quick-scan
and vamp. The pit does a one-pass suicidal clear incorporating a brainwash
which, when it works forces programs like Jack in the Box to revert from
paper to something which Die Hard can kill. Instead of going 1/0
he now goes about 12/0 against JitB :-)
theMystery sure does a lot better against myZizzor than Die Hard does :-(
(I have a pretty good idea what Magnus missing line in myZizzor might be!)
Paul
______________________________________________________________________________
;redcode-94
;name theMystery1.5
;author Paulsson
;strategy How does Die Hard work? (this way maybee?)
;strategy Looking gooood, could it be somthing that begins
;strategy with an i and ends with p?
;assert CORESIZE > 1
;kill theMystery
org start
step1 equ 1800
step2 equ -1922
start spl 1 ;\
mov.i -1,0 ;- make 7 processes
mov.i -1,0 ;/
mov {ptr2,<ptr2 ; move out second paper
mov {ptr1,<ptr1 ; move out first paper
spl 3
spl 4
jmp @ptr1 ; jump to 1
mov {ptr3,<ptr3 ; move out third paper
jmp @ptr3 ; jump to 3
jmp @ptr2 ; jump to 2
pap spl step1,0 ;\
mov.i >-1,}-1 ;\\ Normal paper, with bad constants
mov.i <-2,<1 ;// (I think I riped it from timescape :-) )
spl @0,}step2 ;/
mov.i #0,2667 ;Impy!
ptr1 dat 5+pap,pap+5+500
ptr2 dat pap+5,pap+5+2667+500
ptr3 dat pap+5,pap+5+2667*2+500
______________________________________________________________________________
Most losses:
Program "myZizzor" (length 58) by "Paulsson"
(contact address "[email protected]"):
;strategy Cissors (or whatever way you spell it)
;strategy Lets se how hard Die Hard is this time :-)
theMystery1.5 wins: 27
myZizzor wins: 55
hints.txt Mon May 27 17:44:18 2002 6
Ties: 168
Program "Anti Die-Hard Bevo (3c)" (length 76) by "John Wilkinson"
(contact address "[email protected]"):
;strategy I didnt have a single program on my HD that could beat
;strategy my Cotton-DH, so I made this. Lets see how it fares
;strategy against the real Die Hard. :)
theMystery1.5 wins: 60
Anti Die-Hard Bevo (3c) wins: 54
Ties: 136
______________________________________________________________________________
Questions? Concerns? Comments? Complaints? Mail them to:
Beppe Bezzi <[email protected]> or Myer R Bremer <[email protected]>
The hint
Replicators (part 2)
Hi, happy to see you again.
Last time we spoke of basic replicator concepts, now Ill try to speak of
some advanced topics.
To begin lets 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 dont 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
hints.txt Mon May 27 17:44:18 2002 7
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, dont 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
dont 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 dont
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 ;whats bomb dont 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
hints.txt Mon May 27 17:44:18 2002 8
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 dont know any mathematical method or optimization program to find best
values and I look at what happens using pmarsv. If I notice that modules
dont spread well I change something and so on, art more than science.
In the replicator Im 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.Hsus 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. Heres 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 theyre 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 3spl @0,<i=i+1@sk 5000@pqca i,$+1@pq offm count@go@st
100,987
1830
hints.txt Mon May 27 17:44:18 2002 9
(cdb)
This is a bit complicated. The "@ed 3spl @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 3spl @0,<i=i+1&sk 5000&pqca i,$+1&pq offm 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+1if .!=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, well 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, lets 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
hints.txt Mon May 27 17:44:18 2002 10
a nop instruction, optimizing bombing will come later.
Running Stefans 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.
_____________________________________________________________________________
For questions mail me <[email protected]> or if you think its of general
interest post to rec.games.corewar
Anyone with hints or warriors to publish is welcome.
The hint
P-space
Hi,
this time well 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 opponents one. P-space hold but values,
not whole instructions, and is accessed by two specific instructions LDP and
STP load and store Pspace.
hints.txt Mon May 27 17:44:18 2002 11
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.
Its important to say that even the best switching routine is worthless if
you dont 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
dont have at least two average level different warriors, a stone and a
paper for example, you cannot get anyhing good from it.
Now lets 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. Lets
give a look at a very simple one, and BTW successful, the switcher of Jack
in the Box, for three main reasons: its one of my warriors, is doing well,
is the only one published :-)
Jacks 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 its, 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 its zero we add one to the strategy, if its
different, tie or win, we dont. 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
hints.txt Mon May 27 17:44:18 2002 12
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 its 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, dont 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 <[email protected]>
------------------------------
;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
hints.txt Mon May 27 17:44:18 2002 13
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
______________________________________________________________________________
Planars corner:
Next week, youll get the sequel to my article about imp spirals.
Today, I have a short hint for beginners and a call for volunteers.
The short hint:
---------------
I have written the following program:
;redcode
foo equ 1+2
nop foo*2
Giving it to pMARS, I get this load file:
START NOP.F $ 5, $ 0
Hey ! Whats going on here ? If foo is 1+2 and the argument to NOP is
foo*2, then it must be 6, right ? Wrong. The argument is 1+2*2 = 5,
because EQU does a textual replacement of the label with its argument,
not a numerical evaluation of its argument (there is a good reason for
this).
The solution is the same as in the C language: use parentheses generously:
foo equ (1+2)
Now the argument to NOP is (1+2)*2 and Im happy. Maybe this was the
reason why my warrior failed on the hill. But then again, maybe not.
hints.txt Mon May 27 17:44:18 2002 14
The call for volunteers:
------------------------
I have started updating the ICWS94 draft standard. My new version
includes the new addressing modes and opcodes we are all using every
day. Who will add p-space into it ? We have missed the 94 deadline
by a long time now, and I think its time to turn the draft into a
standard (does the ICWS still exist, by the way ?) Or at least the
draft should describe the language that we are using.
Before we start discussing read/write limits, Stefan asked that I post
a summary of all the good arguments against them, so I have to find
the postings of one and a half year ago (does anybody know where to
find an archive of recent postings to r.g.cw ?) Please no flame war
before I declare the season open.
The new version of the ICWS94 draft standard is available at
http://pauillac.inria.fr/doligez/corewar/icws94.95
<[email protected]>
______________________________________________________________________________
Extra Extra:
Thermite
With impeccable timing I re-arrive on the internet just as Thermite is
knocked off the hill, appropriately enough by Michael Constant. I dont
think I ever published the code, so here it is with explanations as
accurate as the mists of time permit. Im not really sure why it worked
for so long, but I guess it was a lack of decisive weaknesses rather than
any single strength. Maybe P-space even helped, making targets bigger...
Thermite was standard quickscan, followed by a Torch-like incendiary bomber.
The quickscan was originally developed from Michael Constants Sauron (94
tournament) and ended up almost exactly like his Pyramid. I experimented with
various warriors to follow the scanning stage: a vampire, Midge, sadly couldnt
bite as fast as Silks could grow, and Queasy (4-word Mod-1 MOV <A,B bomber) was
good against scanners but otherwise weak.
Then Paul Kline published Torch which looked too good not to steal:
fast incendiary bombing, and multi-process -- so tending to draw if
damaged. The only constructive change I made removed the anti-scanner gaps
from the code, to make it more resistant to Silk-type strip bombing.
I called the result Phosphorus and it was modestly effective (somewhat
less so than Torch :) but it proved a great partner to the quickscan.
The Phosphorus code may appear puzzling if you dont know Torch. The key idea,
is that the instructions in the loop are executed in _reverse_ order because
the SPL #0 instruction keeps feeding new processes into the loop.
:( No-one "hides" near large decoys any more... :(
;redcode-94
;name Thermite 1.0
;kill Phosphorus
;author Robert Macrae
;strategy Quick-scan -> incendiary bomber.
;assert CORESIZE == 8000
; Since I dont launch phosphorus, vulnerable to carpet bombers. May
; pay to put it at start? I should make better use of DJN stream
; (nascent). Either use <, or else start it somewhere which gets bombed
; by mov fairly quickly. What happens if I fall through early, due to
; DAT 1,1s? Should check this doesnt hurt...

SPC equ 7700 ; (CORESIZE-MAXLENGTH-MINDISTANCE*2)
STP1 equ 81 ; (SPC / (RAM/2) / 2)
hints.txt Mon May 27 17:44:18 2002 15
Lookat equ look+237+8*(qscan-1)*STP1
; First scan at 237; last at -67?
traptr dat #0, #trap
bite jmp @traptr, 0 ; Vampire bite.
; Lots of pointers to these, so keep them away from trap!
look
qscan for 6
sne.i Lookat+0*STP1, Lookat+2*STP1
seq.i Lookat+4*STP1, Lookat+6*STP1
mov.ab #Lookat-bite-2*STP1, @bite
rof
jmn test+1, bite ; Save a few cycles
qscan for 6
sne.i Lookat+48*STP1, Lookat+50*STP1
seq.i Lookat+52*STP1, Lookat+54*STP1
mov.ab #Lookat-bite+46*STP1, @bite
rof
jmn test+1, bite ; Save a few cycles
qscan for 6
sne.i Lookat+1*STP1, Lookat+3*STP1
seq.i Lookat+5*STP1, Lookat+7*STP1
mov.ab #Lookat-bite-STP1, @bite
rof
jmn test+1, bite ; Save a few cycles
qscan for 6 ; Should be 7 if I had space...
sne.i Lookat+49*STP1, Lookat+51*STP1
seq.i Lookat+53*STP1, Lookat+55*STP1
mov.ab #Lookat-bite+47*STP1, @bite
rof
; Intention is to place points evenly through the target area.
test jmz.b blind, bite ; if no address stored, no hit.
add #STP1*2, bite ; Smaller than pyramid, as fast.
jmz.f -1, @bite ; find nonzero element.
mov spb, @bite ; Quick pre-bomb...
add #49, bite ; aim 51 past the hit
attack sub.ba bite, bite ; bite(b) contains target-bite
loop mov bite, @bite ; (a) contains the bite addr.
add.f step, bite
djn loop, #24 ; 6 spacing => 72 cycles...
; Incendiary bomber based on Phosphorus 1.0 (from Torch).
bstp equ 155 ; Mod 5, as too big for mod 4 to miss!
gap equ 15 ; Gap between mov and spl.
offset equ 130 ; Chosen with step and gap to give long bombing run.
count equ 1500
blind
spb spl #0, <-gap+1 ; spl half of the incendiary
add #bstp, 1
mov spb, @tgt-offset ; Gives longest run, given gap & step.
mov mvb, @-1
tgt djn.f -3, >300 ; gets bombed with spl to start clear
mov ccb, >spb-1 ; Uses copied mvb for CC.
djn.f -1, <spb-18 ; Aids clear.
hints.txt Mon May 27 17:44:18 2002 16
mvb mov gap, >gap ; mov half of the incendiary
ccb dat 0, 10 ; Core Clear.
; Bit worried about having trap so close to my code...

trap spl 0, >-200 ; Lackadaisical attempt at gates.
spl -1, >-200+2667 ; Each increments many times between
jmp -2, >-200+2*2667 ; imp steps, but then the whole imp
; moves! I only blow away rings...
step dat #6, #-6 ; QS step size. Up from 5 for speed.
end look

(Editor note: I had to change it a little, because Robert used STP as a
label, and now its not allowed being it an opcode. Just hope I didnt
introduce bugs; I tested it and all seems OK. - B.B.)
______________________________________________________________________________
Extra Extra Extra:
Phq
Well! I have received lots of requests about Phq so I have decided to publish
it... (in other words CoreWarrior staff has payed me enough ! ;-)
Phq is one of my first programs written in 94 standard (I have started
redcoding with the 86 standard...)
First of all two words about the name...
Phq recalls a formula of quantum mech: the original name had been
Emc2 (reference to 2c initial qscan) but Emc2 was also the name of another my
QScan-->Stone warrior that never worked very fine...
When I began making Phq, another program behaved very well:
Marcia Trionfale of our friend Beppe Bezzi; so I decided that my warrior
should contain a paper module!
At those times most of the programs on the hill reached the limit of 100
istructions, this made me choose for the initial QScan pass.
The initial QScan is also very useful to solve (without any PSpace routines)
the problem of papers in gaining points during self fighting:
QScan makes Phq able to kill itself in self fighting about 83% times.
So I took the decision: my program will have to be a Qscan --> Paper !
Well! At this point I had to decide what could I do if QScan found an enemy,
or simple a decoy :( !
The first attempt was to bomb the neighborhood of the cell differing from
dat.f 0,0 (blank) with simple dat bombs, using a series of "mov bomb,<ptr"
istructions.
The problem is finding the size of the neighborhood.
I had obtained just slight better results using incendiary bombing.
Id have liked to use spl 0 bombs but this wasnt possible for after bombing
I had to start with paper, and a paper isnt the best to kill lots of
processes executing a "spl 0 jmp -1" loop (or similar)!
Maybe I could have tried some vamp bombing, but I didnt do this...
I choosed to copy some suicide 3-instr core-clear routines "around", hoping
that the enemy executes one of them!
This solution was quite good: if even only one enemy task executes this
3-instr code it may kill other eventually (near) enemy tasks; note that its
bombing is harmless against my paper!
An interesting question is: ...and what about against Pspace programs?
Im mainly a paper and if the enemy switches on a scanner module, its a
slaughter for me! :(
So Id liked to have some brainwashing routines: I added to my core-clear a
brainwashing stp line (who fills enemy PSpace with non-sense values).
Well! This program worked quite fine but another little change made it
even better!
After bombing my initial strategy was simple to jump to paper routines...
...and what about using a spl to have in any case a task who executes my
core-clear?
Well! I added this spl line and results were 3 points more then previous
version!
Im not sure why this works better...
maybe because I bomb more wide around the non-blank cell and sometimes I
reach the enemy before the paper itself kills my own task.
hints.txt Mon May 27 17:44:18 2002 17
Note that Im brainwashing myself! (as you can read in the initial strategy
line;-), but this is unrelevant cos I dont use PSpace in "active mode",
meaning with "active mode" that I dont use PSpace for switching.
Thats all!
What?
The program?
Yeah! Of course! Here you are!
(Hoping that Phq will reach at least Thermite in old scored programs ;-)
Note that its quite full of bugs ;-)
I leave to find them out, to my "25 readers" as exercise (as my prof. of
geometry always said...)
For any questions, flaming etc. your mail is welcome!
Mail to pan0178.iperbole.bologna.it
-----------------------
;redcode-94
;author Maurizio Vittuari
;name Phq
;assert CORESIZE==8000
;strategy New version! This one likes brainwashes...
step1 equ 3743 ; unoptimized replicator costants
step2 equ 1567 ; see CoreWarrior issue 3
step3 equ 1349
; ****** QSCAN ROUTINES ******
start
s1 for 4
sne start+400*s1,start+400*s1+100
seq start+400*s1+200,start+400*s1+300
mov #start+400*s1-found,found
rof
jmn which,found
s2 for 4
sne start+400*(4+s2),start+400*(4+s2)+100
seq start+400*(4+s2)+200,start+400*(4+s2)+300
mov #start+400*(4+s2)-found,found
rof
jmn which,found
s3 for 4
sne start+400*(s3+8),start+400*(s3+8)+100
seq start+400*(s3+8)+200,start+400*(s3+8)+300
mov #start+400*(s3+8)-found,found
rof
jmn which,found
s4 for 4
sne start+400*(s4+12),start+400*(s4+12)+100
seq start+400*(s4+12)+200,start+400*(s4+12)+300
mov #start+400*(s4+12)-found,found
rof
; just missed a line... :(
s5 for 3
sne start+400*(s5+16),start+400*(s5+16)+100
seq start+400*(s5+16)+200,start+400*(s5+16)+300
mov #start+400*(s5+16)-found-100,found
rof
found jmz rabbit,#0
add #100,-1
which jmz -1,@found
add #10,found
for 4 ; bombing enemy
mov m3,<found
mov m2,<found
mov mp,<found
hints.txt Mon May 27 17:44:18 2002 18
mov m1,<found
rof
spl @found,{100 ; So... why not ?
; ****** REPLICATOR ******
rabbit spl 1, <200 ;create 11 processes
mov -1, 0
spl 1, <300
mov -1, 0
s1 spl step1, #0
mov.i >-1, }-1
mov.i bomb, }1942
s2 spl step2, #0
mov.i >-1, }-1
mov.i bomb, }1842 ;Ive changed > with } so many times
mov.i bomb, >1900 ;that I cant remember if this version
mov.i bomb, }2000 ;is the one actually on the hill...
mov.i <s2, <s3
s3 jmp @0, }step3
bomb dat <2667, <5334 ;anti-imp bomb
; ****** BRAINWASHING CORE-CLEAR ******
m1 mov m3, {m3
mp stp <0, #20 ; brainwashing instruction
m2 djn.f m1, }m3+1
m3 dat }bomb, <2667
end start
_____________________________________________________________________________
For questions and congratulations mail me <[email protected]>, flame Myer
<[email protected]> or if you think its of general interest post to
rec.games.corewar
Anyone with hints or warriors to publish is welcome.
The hint
How to improve your beginners 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
beginners coding (Provascan not XTC :-)
;redcode-94
;name Provascan 2.0
;author Beppe Bezzi
;strategy B-scanner
;strategy a six months ago beginners 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
hints.txt Mon May 27 17:44:18 2002 19
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.
Its 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 isnt 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 well speak of later, and adding a forward running perpetual
clear;
The new code:
hints.txt Mon May 27 17:44:18 2002 20
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, isnt 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 Trains 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. Lets 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 its goo for our job.
New version:
;redcode-94
;name Provascan 2.0d
;author Beppe Bezzi
;strategy B-scanner
;strategy a six months ago beginners 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
hints.txt Mon May 27 17:44:18 2002 21
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 doesnt 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, its 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 its my best ever result with a scanner, were it not the hint test Im
not sure I had published it. ;-)
Detailed 94 scores are available on request (mail me), I havent tested the
warrior against beginners hill, feel free to do it and make public domain
the results.
Next hint will be made by Maurizio <[email protected]>, mail him
with your requests.
______________________________________________________________________________
Extra Extra:
La Bomba
by Beppe Bezzi
La Bomba is the first program allowing me to become King of the Hill
and to remain in such position for some time, Jack in the box was King
for but few challenges. The reasons of its success was its very high
speed together with the very favourable environment it found; looking
at it now I can see some ways to improve it, like using the faster
decoding of Pyramid, but now its no time for La Bomba 2.
La Bomba is a qscan followed by a simple replicator, the same of the
hint of CW #3, the innovative part is the Tornado bombing engine used
to drop a cluster of dat bombs on the opponent, in the hope of
catching it during boot; this proved very effective against p-warriors
and stationary warriors using a decoy.
;redcode-94
;name La Bomba
;author Beppe Bezzi
;assert CORESIZE == 8000
;kill La Bomba
org start
qstep equ 5
qrounds equ 7
bigst equ 99
qst equ qstart -(4*bigst)
qstart equ start+145
hints.txt Mon May 27 17:44:18 2002 22
dest0 equ 2200
dest1 equ 3740
dest2 equ -1278
range equ 933
start
s1 for 5
sne.x qst+4*bigst*s1, qst+4*bigst*s1+bigst*1 ;check two locations
seq.x qst+4*bigst*s1+bigst*2, qst+4*bigst*s1+bigst*3
mov.ab #qst+4*bigst*s1-found, found ;they differ so set pointer
rof
jmn which, found
s2 for 5
sne.x qst+4*bigst*(s2+5), qst+4*bigst*(s2+5)+bigst*1
seq.x qst+4*bigst*(s2+5)+bigst*2, qst+4*bigst*(s2+5)+bigst*3
mov.ab #qst+4*bigst*(s2+5)-found, found
rof
jmn which, found
s3 for 5
sne.x qst+4*bigst*(s3+10), qst+4*bigst*(s3+10)+bigst*1
seq.x qst+4*bigst*(s3+10)+bigst*2, qst+4*bigst*(s3+10)+bigst*3
mov.ab #qst+4*bigst*(s3+10)-found, found
rof
jmn.b which, found
s4 for 5
sne.x qst+4*bigst*(s4+15), qst+4*bigst*(s4+15)+bigst*1
seq.x qst+4*bigst*(s4+15)+bigst*2, qst+4*bigst*(s4+15)+bigst*3
mov.ab #qst+4*bigst*(s4+15)-found, found
rof
jmn.b which, found
found jmz.b warr, #0 ;skip attack if qscan found nothing
add #bigst, -1 ;increment pointer till we get the
which jmz.f -1, @found ;right place
qattack ;found.b points target
mov bomba, @found ;in case small and dangerous
for 0
After decoding enemy position it checks the location found+32 and, if it
proves not to be empty, shifts 30 cells the bombing zone to the right
This added near 5 points to my score
rof
add.ba found, qstone
add.b found, qstone
seq *qstone,-100
add.f shift, qstone
qst1 mov qbomb, *qstone ;Tornado bombing engine the faster way
mov qbomb, @qstone ;to fill your enemy with hot lead
qstone mov 32, *32-qstep
sub.f qincr, qstone
djn.b qst1, #qrounds
warr ;Paper01 the hint warrior
paper spl 1, <300
spl 1, <400
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

qbomb dat #-qstep, #-qstep
qincr dat #3*qstep,#3*qstep
shift dat #30, #30
hints.txt Mon May 27 17:44:18 2002 23

for MAXLENGTH-CURLINE-9
dat 0,0
rof
for 9
dat 1,1
rof
end
______________________________________________________________________________
Extra Extra:
Armory - A5
by J.K. Wilkinson
Ok, Armory was my first succesful Hill challenge.
Its based on a simple idea: beat scanners/scissors with a stone,
beat stones with an imp-stone, and beat papers with scissors.
The only thing really new/interesting is the boot method and
pspace. All the components are highly standard and well-known
warriors.
In order to squeeze all this code in, (and do it fast, I wanted
to make a splash on the Hill!) I had to throw together some stuff
like this:
sboot: mov.a #cgate-2-tboot, tboot
mov.a #T+18-goboot, goboot
jmp 2
tboot: dat gate, T
tornado: mov }tboot, >tboot
djn -1, #8
That "jmp 2", for instance, is 100% pointless. :)
100%! I mean, Ive seen code where I thought something _could_
be trimmed down... but placing your own dats so your jumping
over them???
As you can see, theres much room for optimizing, but when A5
hit the big time, I decided to leave well enough alone. :)
As for the pspace, its perhaps the smartest one thats been
attempted on the Hill. You cant be too smart, or you get you
ass kicked while your trying to decide what to do. Heh.
I think I struck I happy medium with my system.
Basically, if Ive just been brainwashed, I reinitialize
pspace and just keeping going with what ever is in my NUM_STR
(my strategy pspace.) That means if Im washed with 0 I go
to scissors when I lose. Is that a good idea?
Well, think about this: If Im brainwashed and I dont lose
I go to tornado, because on a loss I add 1 to the strategy.
This means that q-brainwash->papers cant really lock on.
Ive still got a shot do bounce out of the "just lost, now
youre brainwashed->your screwed" cycle. :)
In retrospect, a better system might be just the opposite,
but its difficult to predict your opponents methodology.
It seemed to work fairly well though, until I went and killed
it. :( <g>
Oh, and if youre wondering what the "Major changes" were,
I removed a paper module. The paper just couldnt launch
in enough time, from that much space... so I redesigned all
the boots. Youll notice they arent in-line boots (they
use djn.b to loop the boot.)
Heres Armory...
hints.txt Mon May 27 17:44:18 2002 24
-----------c-u-t---o-n---t-h-e---d-o-t-t-e-d---l-i-n-e--:-)-----------
;redcode-94
;name Armory - A5
;kill Armory - A4a
;author Wilkinson
;strategy use pspace to go to battle
;strategy v 5 - well, Im still losing to Brain Wash... I may still
;strategy have a pcode bug. :/
;strategy Major changes. Hoping for more wins, and less ties...
;assert 1
i equ imp+100
NUM_STR equ #3
_RESULT equ #0
_LOSS equ #222
_STR equ #333
BOUND equ #800
CDIST equ 12
IVAL equ 42
FIRST equ scan+OFFSET+IVAL
OFFSET equ (2*IVAL)
DJNOFF equ -431
BOMBLEN equ CDIST+2
GATE equ tie-4000
stinc equ 190
d equ 2667
S equ stone+2537
T equ gate+5500
step equ 52
count equ 665
res: ldp _RESULT, #0 ;load last result into B-field
loss: ldp _LOSS, #0
jmz goloss, res ;a zero indicates a loss in the last round
djn tie,res
win: add #-1, loss
stp.b loss, _LOSS
tie:
go: ldp _STR, #0
slt BOUND-100, loss ;check for illegal _LOSS record
stp BOUND, _LOSS
mod.ab NUM_STR, go ; in case _STR ever gets screwed up
mov.ba go, case
gojmp: jmp case ;after this gojmp, we jump again from case
goloss: add #1, loss
slt loss, BOUND+2;if weve lost more than we won, then switch
jmp switch
slt BOUND-100, loss ;check for illegal _LOSS record
jmp switch
stp.b loss, _LOSS
jmp go
switch: ldp _STR, #0
add #1, -1
slt -2, NUM_STR
mov #0, switch
stp BOUND, _LOSS
stp.b switch, _STR
add.ba switch, case
case:
jmp @0, tornado ;3
hints.txt Mon May 27 17:44:18 2002 25
jmp @0, sboot ;3
jmp @0, stonespir ;3
;***Cannonade
stone: mov <1+5+(stinc*800),1
spl -1, <2
add 3, stone
djn -2, <5141+1
dat 0, 0
mov stinc, <-stinc
dat stone, S
stonespir: mov }-1, >-1
djn -1, #6
spl S+1
spir: mov.i imp, i
spl.a 1, <GATE-200
mov.i -1, 0 ;2
spl.a 1, <GATE-300 ;3
spl.a 1, <GATE-400 ;6
spl 2 ;12
jmp.a @imp-1, {0
jmp.a *imp-1, {0
dat #i+2*d+7, #i+1*d+7
dat #i+7, #i+2*d+6
dat #i+1*d+6, #i+6
dat #i+2*d+5, #i+1*d+5
dat #i+5, #i+2*d+4
dat #i+1*d+4, #i+4
dat #i+2*d+3, #i+1*d+3
dat #i+3, #i+2*d+2
dat #i+1*d+2, #i+2
dat #i+2*d+1, #i+1*d+1
dat #i+1, #i+2*d
dat #i+1*d, #i
imp: mov.i #1, 2667
sboot: mov.a #cgate-2-tboot, tboot
mov.a #T+18-goboot, goboot
jmp 2
tboot: dat gate, T
tornado: mov }tboot, >tboot
djn -1, #8
add.ab #10, tboot
mov }tboot, >tboot
djn -1, #4
goboot: jmp T+1, {0
;***Tornado
gate dat #step, #-step ;step equ 52
start mov bombd+10, *tstone
mov bombd+10, @tstone
tstone mov *(2*step)+1, *(3*step)+1
add incr+10, tstone
jump djn.b start, #count ;count equ 665
spl #step, #0
clr mov gate, }gate-5 ;jump ;gate-3
; 10 "dat 0, 0"s need to be inserted here
incr dat 3*step, 3*step
bombd dat #52 , #1 ;hit dat
dat 0, 0
dat 0, 0
;***Scissors
dat #cgate-10, clear-cgate+8+10 ; just in case clr is decremented
hints.txt Mon May 27 17:44:18 2002 26
cgate dat #4000, 3000
wipe4 dat #4000, clear-cgate+8+10
wipe3 dat #4000, clear-cgate+8+10
spl #6000, clear-cgate+8+10 ; redundant wipers
wipe2 spl #6000, clear-cgate+8+10 ; redundant wipers
wipe1 spl #3050, clear-cgate+8+10
; 10 "dat 0, 0"s need to be here
clear spl #0, >-20
mov @2, >cgate-10
mov @1, >cgate-10
djn.b -2, {wipe1-10
end
---------------------------------------------------------------------
As you can see from the Armory ;strategy lines, I thought I was losing
to brainwashes. It turns out that my scissors was so pitiful
that any decent paper could thrash me, and I dont think
Brainwashs brainwashing was really much of a factor. :/
_________________________________________________________________________
Planars corner
CDB tutorial, part 1
This is the first article of a long series that we will write, Stefan
Strack and I. We will start at the level of "I havent even read the
docs yet" and well hopefully end up at the level of "why dont we
have a CDB macro programming contest ?"
Because Stefan has written CDB itself, he probably wouldnt see much
difference between a three-line macro and a one-character command, so
I get to write this first article. Were writing this in the hope
that it will be useful to you, so your feedback is vital: tell us what
is missing, what is unclear, what you would like to see explained in
more detail, etc.
After this introduction, we can start learning CDB. The hardest step
is the first one: you must realize that CDB is at the same time
extremely powerful and quite easy to use. Ill take myself as an
example. I was reading the docs for the first time less than three
months ago. Have a look at Core Warrior 8 to see what kind of macros
I can write now. And Im still far from Stefans level.
So CDB is easy to use, and by learning it you can greatly speed up
your warrior development: once you master CDB, youll be able to do
such things as:
+ explore the functioning of a warrior in a single-warrior "fight" and
discover any unexpected problems (i.e. debug a program)
+ find the right set of constants for a stone to remove its suicidal
tendencies
+ optimize a papers constants to cover the most core locations in the
smallest time
+ gather statistics on how much of a spiral is still alive at the end of
a typical fight
+ automatically find the best constants for a warrior against a given
"White warrior"
+ many other things that I havent thought of yet: the only limit is your
imagination.
Lets go on to the technical stuff. We will use the following program
for the examples. Save it in a file named "fahr.red".
;redcode-94
;name Fahrenheit 0
;author Planar
hints.txt Mon May 27 17:44:18 2002 27
;assert CORESIZE == 8000
steps spl #2044, <3039
ptr mov.i <100, <1000
attack2 mov.i <-2000, *-1
add.f steps, ptr
djn.f -3, {attack2
end
This is a fast stone with a strong suicidal tendency. Well try to
find a good set of constants to replace those 100 and 1000.
General description
-------------------
CDB is a line-oriented debugger. CDB controls the pMARS simulator and
you control CDB by typing commands to the (cdb) prompt. The best way
to get this prompt is using the "-e" option to the pMARS command line.
We will use the following command line. Type this at your shell, or
(if you use a Macintosh) use the "command line" item in the "file"
menu:
pmars -e -b -r 100 fahr.red
This launches pMARS and immediately enters CDB. CDB displays the next
instruction to execute (i.e. the first instruction of the program),
and our good friend the (cdb) prompt. Now we get to decide what
happens next simply by typing a command.
You can also get the prompt by typing d (in the DOS version), or
control-C (in the Unix versions) or command-. (in the Mac version)
when pMARS is running. If youre looking at a battle and you see
something strange happen, you can stop the battle and use CDB to
investigate.
The best way to read this tutorial is to launch your pMARS on your own
computer and try the commands when you read their description. I was
going to show the example commands and CDBs answers in the following
format:
00000 SPL.B # 2044, < 3039
(cdb) echo coucou
coucou
(cdb)
CDB displays the first line when it is triggered by the "-e" option on
the command line. If you enter CDB with control-C, youll get a
different display. The (cdb)s are the prompts, "echo coucou" is what
I typed, and "coucou" is CDBs answer. After printing "coucou", CDB
is ready for a new command.
Because this tutorial is mostly useless if youre not trying the
commands on your pMARS, and because Beppe wont be happy if Planars
corner gets bigger than the rest of Core Warrior, Im not going to
show CDBs answers to my example commands. Try them and see. If you
cant view this file and use pMARS at the same time, print this file.
If you dont have a printer, contact me and Ill send you a paper
copy.
The first thing to learn is of course how to get out of CDB. Here is
one command to do that:
(cdb) quit
After this command, CDB is not ready for a new command because it has
exited, along with pMARS itself. Here is the other command to exit
CDB:
(cdb) continue
hints.txt Mon May 27 17:44:18 2002 28
With this command, CDB exits and lets pMARS run as if CDB had not been
invoked, until the end of the 100 rounds we specified on the command
line. If you type control-C again, you get back in control.
Displaying the current state
----------------------------
The most useful command of CDB is "list". It takes as argument a core
address or a range of addresses, and it displays the contents of the
core at that address or range of addresses. For example, you can get
a listing of Fahrenheit by typing:
(cdb) list 0,4
If you want to see the next core cell:
(cdb) list 5
This cell contains "DAT 0, 0", which CDB displays as blank, because it
is the default cell contents at the beginning of a battle.
You can abbreviate "list" to "l", or even nothing at all, like this:
(cdb) 1,3
Instead of numbers, you can use expressions as arguments to "list"
(this is true for all cdb commands that take numeric arguments). I
wont describe in detail the syntax of expressions, they are the same
as what you use in redcode programs. There are a few special values
that you can use in CDB expressions.
The most important of these special values is the dot address; it is
entered as a period, and it represents the address of the last core
cell displayed by CDB. For example, after the last example above, you
can type:
(cdb) .
And to see what the B-field of this instruction points to:
(cdb) .-2
The variables A and B contain the A-field and B-field of the
instruction at the dot address. And as a further shortcut, CDB
accepts "+expr" and "-expr" for ".+expr" and ".-expr", so the above
example could be entered as:
(cdb) 3
(cdb) +b
You can also type:
(cdb) +1,+10
Then press <Enter> at the CDB prompt. When you enter a null command
like this, CDB will repeat the previous command, so you can list the
whole core 10 cells at a time by simply pressing <Enter> repeatedly.
Thats all for the "list" command. It took a long explanation because
it is the most often used. With some graphical interfaces, you can
also activate it by clicking in the core with the mouse.
To get a general view of whats going on, type:
(cdb) registers
This will display a the number of the current round, the number of
cycles remaining before the end of this round, and a listing of each
hints.txt Mon May 27 17:44:18 2002 29
warriors with its name, its number of processes, and a summary of its
process queue and p-space.
The process queue is a list of core addresses. The process that
will execute next is in [brackets], and the following process is
pointed by the arrow.
Running the program
-------------------
To run the program until completion, just type:
(cdb) go
pMARS will run until the program dies or the cycles have run out.
While the program is running, you can still press control-C to get the
prompt back. To know which condition ended the "go", use "registers".
To execute one instruction and get back to the (cdb) prompt, type:
(cdb) step
To step again, just press <Enter>.
Executing one instruction at a time is useful, but youll often want
to go forward in time at a faster pace. To this end, CDB provides the
"skip" command, which takes an argument. Just type
(cdb) skip 999
The simulator will execute 1000 steps before giving back the (cdb)
prompt. Use "registers" to check the number of cycles left: 1000
fewer than before you used "skip". Note that "skip 0" is equivalent
to "step".
With "skip" commands, we can already zero in on the most interesting
parts of a fight. For example, let us find out when Fahrenheit bombs
itself. Use "go" to finish the current round, then "step" to get to
the first cycle of a new round. Now type
(cdb) skip 999
(cdb) 0,4
Youll see that Fahrenheit is still intact after 1000 cycles. Type
that sequence a second and a third time. Fahrenheit has bombed itself
between the 4000th and the 5000th cycle. Use "go" to skip the rest of
this round, skip to cycle 4000, and then 100 by 100 until the self-
bombing. Then 10 by 10, then just step until the self-bombing. If
you lose track of how many cycles have elapsed, "registers" will tell
you.
This is a bit tedious, and CDB provides much better ways for doing
this, but I have to keep something for next time, or Ill lose all my
readership. We already have a useful piece of information: after 4136
cycles, Fahrenheit destroys its own SPL instruction.
Use "go" to reach the end of the battle, step once to start a new
battle, and "skip 4135". Type "registers" and look at the process
queue. Between the brackets is the address of the instruction about
to execute: 1. type "1" and youll see how this instruction bombs the
SPL. (Note that the instruction at 1 was already displayed by CDB
right after your "skip".)
Exercise: change the constant 1000 in Fahrenheit to avoid self-
bombing at cycle 4136. Find out when the self-bombing occurs with
your new constant, and which instruction of Fahrenheit is bombed.
There is one more way to do big steps. You can step all processes
once by typing:
hints.txt Mon May 27 17:44:18 2002 30
(cdb) thread
CDB will step once for every process in the process queue, and youll
get right back at your current process, one step later. This is very
useful when youre debugging multi-threaded programs (which is not the
case of Fahrenheit, but you can try it on the bootstrap sequence of
Impfinity v3i, for example).
To conclude this first part, here is the great debugger classic,
breakpoints. Type:
(cdb) trace 0
CDB will place a breakpoint on the SPL instruction of Fahrenheit.
Every time a traced instruction is about to be executed, CDB will stop
and display the instruction. If you repeatedly enter
(cdb) go
(cdb) registers
youll notice how often the SPL injects a process into the loop.
Youll also notice that the listing of the traced instruction has a
"T" at its right. To remove a breakpoint, use "untrace".
For your homework, look up the "moveable" command in the docs, and
think up a use for moveable breakpoints, and one for non-moveable
breakpoints.
Abbreviations
-------------
CDB provides a good way of saving your fingers: you may abbreviate a
command to its first few letters. Here is a complete list of the
shortest abbreviations accepted by CDB. Each command is listed with
its optional part in (parentheses).
c(ontinue) g(o) r(egisters)
ca(lc) h(elp) res(et)
cl(ear) if s(tep)
cl(s) l(ist) se(arch)
clo(se) m(acro) sk(ip)
d(isplay) mo(veable) of(f) sw(itch)
d(isplay) c(lear) mo(veable) on t(race)
d(isplay) o(ff) p(rogress) th(read)
d(isplay) on pq(ueue) u(ntrace)
e(dit) pq(ueue) of(f) w(rite)
ec(ho) ps(pace) wq(ueue)
ex(ecute) ps(pace) of(f) wq(ueue) of(f)
f(ill) q(uit)
Next time, well yield much more power with ! !!@& and the commands
for changing the core.
-- Planar <[email protected]>
Many thanks to Stefan for the very useful remarks he made on a draft
of this text.
The hint
The very basics of Core War game strategy.
(How to improve your beginners warrior)
In this issue we shall try to discuss about improving warriors.
First of all a little preface for the beginner: we want to clarify the
meaning of the sentence "a warrior better than another one".
At the moment, as you know, our "work" is to try to make our warriors
enough powerful so that they can enter in a 25 warrior populed heap, that we
usually call hill ;-).
One of the first things that a novice (apart the redcode language ;-) should
hints.txt Mon May 27 17:44:18 2002 31
know about this game, is that for each given warrior, there exists a warrior
that can defeat it in the long distance.
Maybe one of the main differences between a beginners and a veterans program
is the range of enemy types it can succesfully face: this is often the reason
why a warrior going very well in the beginner hill, often finds many problems
if subscribed on the 94 hill.
Lets see some examples...
In the last number Beppe showed us how to improve a beginners scanner, and he
put it into the 94-hill (Provascan 2.0); then he modified again the warrior
and reached the second place (Provascan 3.0)!
I tried to make some changes to version 2.0, and even if I couldnt score as
high as Beppe (Provascan 3.0 is in the top ten, and it can be considered, as
his previous version, no more a beginners warrior!), I think its an useful
challenge for the beginner trying to improve it (not such an easy exercise!).
Now we discuss some basic and reasonable moves that can be attempted to
modify it succesfully.
I remind you that Provascan is a 50%c B-scanner with boot and relative decoy,
and spl0-dat core clear (for further details see Core Warrior 9); it plays
conventionally the role of scissors, in the well known
scissors-paper(replicators)-stone(bombers) analogy.
We start analizying some interesting results of Provascan 2.0:
Provascan 2.0d vs Frontwards 95/72/33 (one shot scanner)
Noboot vs Frontwards 55/129/16
Provascan 2.0d vs La Bomba 87/70/43 (QScan--> Paper)
Noboot vs La Bomba 97/76/27
Provascan 2.0d vs Impfinity4g1 93/93/14 (Imp stuffs! ;-)
Noboot vs Impfinity v4g1 90/88/22
Provascan 2.0d vs Torch t18 85/88/27 (incendiary bomber)
Noboot vs Torch t18 91/77/32
Provascan 2.0d vs Porch Swing 2 81/80/39 (one shot scan/bomber)
Noboot vs Porch Swing 2 59/111/30
Question: but booting is truly useful ?
Lets see the result!
Noboot (the same version but without boot) is faster, because doesnt
have to spend some initial cycles executing the copy, and can immediately
start scanning.
Its reasonable to think that Noboot will gain something against warriors
not scanning the core.
If we neglect fluctuations, we see that Noboot works quite better against
Torch (a bomber) and also against La Bomba (maybe Noboot can reach and hit,
with a spl0 carpet, the paper before it spreads away.
Against Impfinity we cant see any obvious difference.
But take a look of what happens with one-shot scanners!
Against these guys the boot is highly recommended, as you can see from
the scores: they stop scanning and start to fire from your decoy
(with the core clear), while you are safe in another part of the core,
scanning and ready to bomb them later.
Overally we understand that isnt a very good idea to take away the booting
section (at least in the current hill) from our 50%c scanner!
Now, extablished that booting is a quite pretty idea ;-), we want to try
another stuff: who of you, did never hate (maybe even for a while) those
little, ugly and hard-to-die imps ;-) ?
(answer: maybe only our dad_of_imp_Planar never hated his little
and *pretty* "creatures"...;-)
So what about on installing an anti-imp core clear on our favourite scanner ?
Lets take a look at this version of ProvaScan (I left the original comments
of Beppe and changed just the clear and very very other little things):
BTW Prova_and_Riprova means Try_and_Try_Again!
;redcode-94
;name Prova_e_Riprova
;author Maurizio Vittuari
hints.txt Mon May 27 17:44:18 2002 32
;strategy B-scanner
;strategy This is a personal defiance to Beppe ;-)
;strategy hoping to improve Provascan for the hint
;strategy on the New Years Day issue
;assert CORESIZE == 8000
step equ 3364
away equ 3198+1
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 #step, ptr
ptr jmz loop, trap+step
mov.b ptr, dest
cnt mov #7, 0 ;0
clear mov bomb, >dest
djn clear, cnt
jmn loop, trap
bomb spl #6, 0 ;0
mov kill, }bomb ;1st pass: spl0-dat carpet
mov kill-1, }bomb ;and then 2nd pass: only dat <2667,<-2666
jmp -2
spl #4, 0 ;0
kill dat <2667, <-2666
boot mov kill, away
for 12
mov {boot, <boot ;the faster way to boot away
rof
mov #0, boot+2 ;we have to set those b-fields to zero
mov #0, boot+6 ;to save time later
mov #0, boot+10
mov #0, boot+14
jump jmp boot+away-11,>away-34 ;> is to set trap b-field non zero
for (MAXLENGTH-CURLINE)/4
dat jump, 0 ;this decoy doesnt have two equal cells
dat bomb, boot ;and also has all fourth b-field at zero
dat boot, kill
dat clear, boot
rof
end boot
Prova_e_Riprova vs Impfinity v4g1 10/96/94 (AArgh!)
Prova_e_Riprova vs Torch t18 81/86/33
Prova_e_Riprova vs Provascan 3.0 93/94/13
Prova_e_Riprova vs Frontwards v2 86/74/40
Prova_e_Riprova vs La Bomba 58/85/57
Prova_e_Riprova vs Night Train 98/36/66
Prova_e_Riprova vs DoorMat 99/36/65
Provascan 2.0d vs Night Train wins: 44/39/117
Provascan 2.0d vs DoorMat v0.1 wins: 46/48/106
Two words about these results:
They follow our expectations when fighting against Torch and Provascan 3.0;
this version is quite better then 2.0d against imp stuffers as Doormat
and Night Train.
On the contrary I cant understand what actually happened against La Bomba
(at home my tests gave very different results...); against Frontwards the
performance was slightly worse than the one by version 2.0d, maybe for the
couple of istructions added for the clear (now P_e_R is no more so tiny,
and also a bit slower in core cleaning!).
What is quite unexpected is the score against Impfinity; maybe here the
bi-directional core clear is much better, and probably P_e_R is very often
stoned!
hints.txt Mon May 27 17:44:18 2002 33
Some interesting changes, left as an useful exercise to my twenty-five readers,
can be:
-try to change the scan step
-try to change the carpet dimension
-try to change the starting offset of the core clear
-try to change boot distance
-try to write a better coreclear: smaller than mine [not so hard] and possibly
bidirectional and anti-imp [not so easy]
-reengineer the program and reduce the number of istructions [quite hard]
-find the changes that make this version score better than Provascan 3.0 ;-)
Well, I think thats all for this issue, hoping to have been clear...
anyway you can mail me at [email protected]
Now I leave you with Planar and his interesting tutorial.
_____________________________________________________________________________
CDB tutorial, part 2
In the first part of this tutorial, we explored the most basic
commands of GDB. Now we are ready for much more powerful features,
features that give most of its power to CDB (and make its input look
like line noise). We wont write macros yet, but well write CDB
programs in the form of complex command lines.
Sequence
--------
Last time, we found the point where Fahrenheit bombed itself with the
"skip" command. It was a bit tedious because we were typing these two
commands over and over:
(cdb) skip 999
(cdb) 0,4
There is a better way. Just type:
(cdb) skip 999 0,4
CDB will execute the two commands and display their results before
giving the prompt back. So you can put a tilde instead of pressing
<Enter> between two commands. Big deal.
Indeed, this feature will save a lot of your time. Press <Enter> now,
and CDB will repeat the entire command line, not just the last
command. You dont have to retype the two commands over and over.
Suppose you lose track of the time and you want to use "registers" to
see the current cycle. If you type
(cdb) registers
youll see the cycle count, but you lose your "previous command"
buffer and you have to type "skip 9990,4" again. But if you type
(cdb) registers
with a space before the "registers", CDB will execute "registers" but
keep the old "previous command". Now if you press <Enter>, CDB will
execute the "skip" and the "list".
Notice that, when you type "skip 999 0,4", CDB will execute both
commands and display their results. "skip" executes first and
displays the next instruction to execute, then "0,4" displays the
first five core locations. This is messy. If you type instead
(cdb) @skip 999 0,4
hints.txt Mon May 27 17:44:18 2002 34
the "skip" command will execute without display. The "@" operator,
placed before a command, will tell CDB to suppress the display of this
command.
Tests
-----
Use "go" to skip to a new battle, then type
(cdb) @skip 999 @list 0 if B!=3039 0,4
Here is what CDB will do:
1. silently step 1000 times (@skip 999)
2. silently list the first core location (@list 0)
Whats the point in listing the first core location if you dont
display the listing ? Its to set the dot address (and the A and B
values). Youll do it all the time in CDB programming.
3. Test if the B-value of location 0 is different from 3039. If so,
CDB will execute the next command (0,4); if not, CDB will skip
the next command and give the prompt back.
Now, you can press <Enter> until CDB displays the listing of
Fahrenheit. Youll see that Fahrenheit has bombed itself.
So this is how the "if" command works: execute the following command
only if the condition is true. The condition is any expression, it is
true if not equal to zero, false if equal to zero. Easy, isnt it ?
Loops
-----
Try this:
(cdb) @step !1000
and notice that it is exactly equivalent to "@skip 999". What does it
mean ? The "!" command means "repeat the beginning of the command
line up to this (!) command". Here, this will repeat the "@step".
The argument to "!" is the number of times that CDB must repeat the
line. (Warning: for some strange reasons, sometimes MacpMARS will not
accept a space between the and the !)
So we told CDB to repeat 1000 times "@step". If we use
(cdb) @step !999 step
this is equivalent to "skip 999": step 999 times silently and once
with display.
If you omit the argument to "!", CDB will loop forever. Typing
(cdb) @step !
is equivalent to "continue", but slower. Youll have to press
Control-C to get back to the prompt. (In this case, Control-C doesnt
work in the X-window version. I have to type Control-C in the
terminal window where I launched pMARS from. This will be fixed in
the next version of pMARS.)
In addition to the loop count, you can use "if" to break out of a
loop: if you use "if" to skip over the "!" command, the loop will
stop. Use "go" to skip to a new battle and type:
(cdb) @step @list 0 if B==3039 !
CDB will step until Fahrenheit has bombed itself. Use "registers" to
get the exact cycle when this happens, subtract the remaining cycles
from 80000, use "go" to start an new battle and skip to just before
hints.txt Mon May 27 17:44:18 2002 35
the bombing. Check that the next instruction will bomb core
location 0, step over it and check that it does bomb that core
location.
So this is finally the right way of finding when and how Fahrenheit
bombs itself. In just one short command line, we can do the same work
as the tedious process of skipping in decreasing increments that we
used last time. Note that we can use this technique only if we know
which of Fahrenheits instructions is bombed. I think Stefan has some
predefined macros that will help us further. Well keep them for
part 3.
Changing the core
-----------------
Well want to experiment by changing some of Fahrenheits constants to
see which one makes it bomb itself the latest. For example, to set
the B-value of location 1, well set the whole location with the
command "edit". It takes an address as argument. In interactive
mode, "edit" will prompt you for a line of redcode to put at this
address. In a command line, "edit" will take the next "command"
(whatever is between the next and the following one) as the line of
redcode. For example, if you type:
(cdb) edit 1
mov.i <100, <2000
CDB will set the contents of core location 1 to this instruction, in
effect changing the B-value of the instruction to 2000. You could
instead type:
(cdb) edit 1 mov.i <100, <2000
If we want to see the effect of a big decoy on Fahrenheits DJN
stream, we can use:
(cdb) fill 5700,5800
dat 1, 1
This will set the 101 core locations between 5700 and 5800 to
"DAT 1, 1". As with "edit", we can give the instruction on the
command line after a . Determine on which cycle Fahrenheit bombs
itself when this decoy is present.
Computing
---------
CBD can also do arbitrary calculations (and display the results). The
command to use for this is "calc". Try:
(cdb) calc 2+2
(cdb) calc B+1, .+A
(cdb) calc D=D+1
CDB provides 24 variables for your use: C...Z (remember that A and B
contain the A-value and B-value of the dot address; you cannot assign
to them). An expression can contain an assignment, as in the C
language. You will often use "@calc" to do an assignment and avoid
printing the result.
Nested loops
------------
Lets make CDB work hard to determine the constant that will make
Fahrenheit bomb its SPL line as late as possible. Well try the
values of the interval [1004,1007] for the B-field of the first MOV.
hints.txt Mon May 27 17:44:18 2002 36
Well use two nested loops: the outer loop will enumerate the 4
values for the constant, and the inner loop will execute the battle
step by step, checking the SPL after each instruction.
For nested loop, we use the "!!" instruction. It marks the opening of
the loop, which is closed by a matching "!". Our command lines will
be (Ive broken the long line, but you must type it in one line
without the \):
(cdb) ca C=1003,X=3039
(cdb) !!ca C=C+1,[email protected]<100,<C!!@ca D=D+1@s@0if \
B==X!ca d@g@s!4
This is a detailed explanation:
!! start the outer loop
ca C=C+1, D=0 increment the outer loop counter, reset
the inner loop counter (and print the
constant)
@ed 1mov.i <100,<C set the first MOV instruction
!! start the inner loop
@ca D=D+1 increment the inner loop counter
@s step the warrior once
@0 set the dot address to 1
if B==3039! end the inner loop if self-bombed
ca D print the constant and number of cycles
@g@s skip to the first cycle of the next battle
!4 loop 4 times for the outer loop
Four values is not a lot, but I couldnt do better with the strong
suicidal tendency of Fahrenheit (see exercise 6 below). What would
you do to reduce this tendency ?
Theres no reason I should be the one doing all the work, so here are
a few exercises. Note that you wont be able to test your solutions
because my command line is very close to the maximum size allowed by
pMARS. Well have to define macros to overcome this limitation.
1. The above loop will take a lot of time. Accelerate it by stepping
10 by 10 instead of 1 by 1.
2. Were only interested in the value that gives the greatest number
of cycles. Change the command line to display only that value and
the corresponding number of cycles.
3. Use "fill" to abort the current battle instead of finishing it with
"go". How much faster is this ?
4. Even faster: instead of doing the inner loop step by step all the
way, skip to the greatest number of cycles so far, and start
stepping from there if the SPL is still not bombed. (Is that
clear ?)
5. Figure out a way of putting a sequence of instructions under an
"if" instead of a single instruction, so that the sequence is
executed only when the condition is true.
6. [hard] The inner loop fails to stop if the self-bombing doesnt
occur on the SPL. How do you make it work in all cases ?
The end
-------
This is all for this part. In the next one, youll have the answers
to the exercises, and Stefan will tell us about macros. Theres a
whole lot of useful predefined macros that come with pMARS.
Stefan is on vacation, so he didnt proofread this part. Blame him if
it is not as good as part 1 (-:
______________________________________________________________________________
I want to greet you with a few lines written by Myer R Bremer on issue 4...
hints.txt Mon May 27 17:44:18 2002 37
#############################################################################
EDITORS NOTE: Damien is much too modest. Imp spirals are one of the most
difficult subjects to understand. Impfinity missed the 94 draft hill by
only a fraction of a point. Im sure hell breach the hill very soon. Spoke
too soon. Impfinity has just entered the hill as I am posting.
#############################################################################
Well, I think that now Impfinity is going very well!
Myer has a very good sight! ;-)
______________________________________________________________________________
Questions? Concerns? Comments? Complaints? Mail them to:
Beppe Bezzi <[email protected]> or Myer R Bremer <[email protected]> or
for this issue to Maurizio Vittuari <[email protected]>
The hint
A new p-switcher
by Paul Kline
A colorful variety of p-switching mechanisms are sprouting this Spring, and
it would be nice if someone would round them all up for comparison. Also
nice if people would POST a few :-)
A simple, fast switch-on-loss routine for two p-components might
look like this:
pflag equ (somenumber.lt.500)
pGold ldp.ab #0,#0 ; get results of last battle
ldp.a #pflag ,pGold ; retrieve attempted strategy
add.a #1 ,@pGold ; if a loss, increment strategy
mod.a #2 ,pGold ; safeguard against brainwashing
stp.ab pGold ,#pflag ; store current strategy
jmz.a select1 ,pGold ; select strategy 1
jmp select2 ; select strategy 2
(The last jmp is unnecessary if strategy 2 immediately follows)
A powerful adaptation of the routine can be made with no extra
instructions. By increasing the MOD number we have an assymetric
switcher, by which the second strategy is selected more often than
the first. This can be very helpful in pairing up a strong
all-purpose warrior like Torch, with a special-purpose warrior
like Clisson. Like many fast programs with spl-dat clears, Torch
is vulnerable to a stone, which is in turn highly vulnerable to Clisson.
Using an assymetric switcher to select Torch most frequently gives
the best results against a variety of opponents, and the infrequent
Clission strategy breaks up a protracted series of stone attacks.
This is the switcher used by Goldfinch which pairs a one-shot
scanner w/multipass clear, with Clissons dodger.
Paul Kline
[email protected]
______________________________________________________________________________
Extra Extra
Twister
by Beppe Bezzi
Tornado is, beetween my warriors,one my favourites and, being a very
flexible bombing engine, I like a lot to tweak and improve it, testing new
bombs and variations. When Tornado 3.0, that had a success beyond my
expectations, was near the bottom of the hill, a long time indeed :-), I
tried to fix some problems that caused its fall and I coded v 3.3 thats the
one included in Twister. Jack uses a slightly different version but you can
fit this one in the old Jack, using but one paper module, and results wont
differ too much from those on the hill (let me something to publish next
week :-)
The bombs are common dat <1,{1 deadly against clears and slowing djn stream
hints.txt Mon May 27 17:44:18 2002 38
users, intermixed with one spl #xx to allow self bombing to enter the core
clear.
Worth noting are the pattern, not exacly mod 5 but slightly translated, such
way its more difficult for a one shot scanner to slip through my bombs
without noticing them, and the djn protection, jmz.b start,#0 stolen from Torch.
The qscan is rather similar to the one in Stepping Stone, being only a bit
slower overall even if with a better bomb distribution. I coded it from the
warrior I sent to J K Lewis tournament, a thing that proved deadly, I won 13
rounds alone, but too weak. Its a 50%c vamp engine dropping one far jump to
the pit and two near jumps through and to the far jump in a six instructions
loop, something like that:
jn jmp *qqstep, qqstep ;jump near
jf jmp -bombn+pit-(3*qqstep)-qdisp,-qqstep ;jump far
jn ..[qqstep cells].. jn .. [qqstep cells] .. jf
The first jn jumps to jf using a-field of the second jn, the other jumps go
to the pit.
The pit is a standard self destructing, brainwashing pit.
;redcode-94
;name Twister
;author Beppe Bezzi
;strategy qscan -> Tornado bomber
;assert CORESIZE == 8000
;kill Twister
step equ -45
away equ 4000+2 ;mod 5 +2
gate1 equ (gate-4)
org startq
qstep equ 6
qrounds equ 8
qdisp equ -qstep*(qrounds*3/2-1)-60
qqstep equ qstep*qrounds
bigst equ 100 ;or something more :-)
qstart equ startq+145
qst equ qstart -(4*bigst)
pstep equ 40
spacer equ 4
cldst equ (bclr-bgate+spacer+5)
pit spl 4
pit1 mov -3, <1300
spl pit1
spl pit1
stp.b #0, @pit1
jmp pit1
;----Qscan
;dont ever think its the right qscan pattern :-)
startq
s3 for 4
sne.i qst+4*bigst*(s3+0), qst+4*bigst*(s3+0)+bigst*1
seq.i qst+4*bigst*(s3+0)+bigst*2, qst+4*bigst*(s3+0)+bigst*3
mov.ab #qst+4*bigst*(s3+0)-found, found
rof
jmn.b which, found
s2 for 4
sne.i qst+4*bigst*(s2+5), qst+4*bigst*(s2+5)+bigst*1
hints.txt Mon May 27 17:44:18 2002 39
seq.i qst+4*bigst*(s2+5)+bigst*2, qst+4*bigst*(s2+5)+bigst*3
mov.ab #qst+4*bigst*(s2+5)-found, found
rof
jmn.b which, found
s1 for 4
sne.i qst+4*bigst*(s1+10), qst+4*bigst*(s1+10)+bigst*1
seq.i qst+4*bigst*(s1+10)+bigst*2, qst+4*bigst*(s1+10)+bigst*3
mov.ab #qst+4*bigst*(s1+10)-found, found
rof
jmn which, found
which
found jmz.b boot, #0 ;Pyramid decoding
add.b found, pt2
sne.i @found, @pt2
add.ab #(bigst*2),found
sne.i -100, @found
add.ab #bigst, found
qattack ;found.b punta il bersaglio
mov bombm, @found ;dat bomb found position
add.ba found, qstone ;\
add.b found, qstone ; >setup vamp pointers
sub.ba found, bombf ;/
;---vamp attack ---
qb1 mov bombn, *qstone
qb2 mov bombf, @qstone
qstone mov (1*qqstep)+bombn+qdisp,@(3*qqstep)+bombn+qdisp
qstart1 sub qincr, @qb1
add.a qincr, bombf
qjump djn.b qb1, #qrounds
jmp boot
bombn jmp *qqstep, qqstep
qincr dat >-1*qstep,>-1*qstep
bombf jmp -bombn+pit-(3*qqstep)-qdisp,-qqstep
for 5
dat 0,0
rof
;--- Tornado
start
boot
mov gate, }pt2
mov gate, *pt2
mov last, <pt1
spl 1, 1
mov {pt1, <pt1
mov {pt1, <pt1
mov {pt1, <pt1
mov {pt1, <pt1
mov {pt1, <pt1
go djn.b @pt1, #2 ;start Tornado
mov gate, <pt1
pt1 div.f #last,#last+1+away
pt2 div.f #gate+away-5,#bigst+found

dat -25, last-gate1+5
warr
gate
dat -25, last-gate1+15
bombs spl #(step+1), -step ;hit spl
start1 sub incr, @b1
hints.txt Mon May 27 17:44:18 2002 40
stone mov (0*step)+jump,*(1*step)+jump
b2 mov bombs, @stone
b1 mov bombm, *stone
jump jmz.b start1, #0 ;hit by spl
clr mov @djmp, >gate1
mov @djmp, >gate1
djmp djn.b clr, {bombs
incr dat >-3*step,>-3*step
last
bombm dat <1, {1
shift dat #40, #40
______________________________________________________________________________
Questions? Concerns? Comments? Complaints? Mail them to people who care.
authors: Beppe Bezzi <[email protected]> or Myer Bremer <[email protected]>

You might also like