Saturday, 22 October 2011

Koenigstuhl Top 20: Where Are They Now

This afternoon I stumbled across a status report from Koenigstuhl, 03 July 2001. Curious to see how the hill has changed over 10 years I compared the report to the current hill:

2001 RankWarriorAuthor2011 Rank
1Pattel's VirusBen Ford8
2Recycled BitsDavid Moore12
3CombatraDavid Moore4
4Self-Modifying Code v0.11Ben Ford22
5Self-Modifying Code v0.10Ben Ford25
6QuicksilverMichal Janeczek76
7UninvitedJohn Metcalf88
8Recycled Bits--David Moore93
9Tuesday AfternoonJohn K W139
10Fire and IceDavid Moore94
11RecoveryIan Oversby97
12ReindeerIan Oversby141
13Three MusketeersRobert Macrae157
14The StormbringerChristian Schmidt133
15Am I alive?Christian Schmidt166
162 CrazyChristian Schmidt189
17Digitalis 4Christian Schmidt198
18Bigger BrotherPhilip Kendall58
19Liquid PaperSean McDonald109
20Origami Harquebusmjp49

Only three warriors remain in the top 20 while the majority have fallen 50+ places. :-)

Tuesday, 27 September 2011

Whirl: '88 qscan -> oneshot

Whirl is a qscan -> oneshot which recently entered the '88 hill.
;redcode
;name Whirl
;author John Metcalf
;strategy qscan -> oneshot
;assert CORESIZE==8000

        qfirst equ (qp2+2*qstep)
        qdist  equ qfirst+111
        qstep  equ 

        qi  equ 7                       
        qr  equ 7

qbomb   dat <qi/2-qi*qr,   <qi*qr-qi/2

        qa  equ qstep*16
        qb  equ qstep*5+2
        qc  equ qstep*10
        qd  equ qstep*2
        qe  equ qstep*1

qgo     cmp qdist+qc,      qfirst+qc
        jmp qfast,         <qa
        cmp qdist+qe+qd,   qfirst+qe+qd
qp1     jmp <qfast,        <qc
qp2     cmp qdist,         qfirst
qp3     jmp qskip,         <qe

        cmp qdist+qb,      qfirst+qb
q1      djn qfast,         #qp1

        cmp qdist+qd+qc,   qfirst+qd+qc
        jmp qslow,         <qfirst+qd+qc+4
        cmp qdist+qd+qb,   qfirst+qd+qb
x1      jmp qslow,         <q1
        cmp qdist+qc+qc,   qfirst+qc+qc
q2      djn qslow,         #qp2
        cmp qdist+qd,      qfirst+qd
        jmp qslow,         <qfast
        cmp qdist+qa,      qfirst+qa
        jmp q1,            <q1

        cmp qdist+qa+qd,   qfirst+qa+qd
        jmp x1,            <q1
        cmp qdist+qc+qb,   qfirst+qc+qb
        jmp q2,            <q1
        cmp qdist+qe+qd+qc,qfirst+qe+qd+qc
        jmp qslower,       <qfirst+qe+qd+qc+4
        cmp qdist+qe+qd+qb,qfirst+qe+qd+qb
        jmp qslower,       <q1
        cmp qdist+qe+qc+qc,qfirst+qe+qc+qc
        jmp qslower,       <q2
        cmp qdist+qd+qd+qc,qfirst+qd+qd+qc
q3      djn qslower,       #qp3
        cmp qdist+qe+qc,   qfirst+qe+qc
        jmp <qfast,        <q2
        cmp qdist+qd+qd,   qfirst+qd+qd
        jmp <qfast,        <q3
        cmp qdist+qd+qd+qb,qfirst+qd+qd+qb
        slt <q3,           <q1

        jmz pgo,           qdist+qe+qd+qc+10

qslower add @q3,           @qslow
qslow   add @q2,           qkil
qfast   add @q1,           @qslow

qskip   cmp <qdist+qstep+50, @qkil
        jmp qloop,         <1234

        add #qdist-qfirst, qkil
qloop   mov qbomb,         @qkil
qkil    mov <qfirst+qstep+50, <qfirst
        sub #qi,           @qloop
        djn qloop,         #qr+2

pgo     mov last,          boot+10
c       for 10
        mov last-c,        <pgo
        rof
        jmp boot+7


step    equ -12
first   equ (201*12-8)
boot    equ (pgo-first-100)

dbmb    dat <2667,         <-10

clear   spl 0,             <dbmb-sptr-8
cloop   mov @sloop,        <sptr
        mov @sloop,        <sptr
bomb    djn cloop,         <dbmb-4

steps   dat <step*3,       <step*3+1

sloop   add steps,         @cloop
        mov dbmb,          <sptr
sptr    cmp first+step*2,  @first+1
        jmp <sloop
last    jmp sloop

        end qgo

Thursday, 11 August 2011

The Second ICPC

Christian Schmidt recently announced the Second International Corewar Programming Contest with a concept similar to the new DynaHill.

The hill will be initialised with a pool of 3800 published warriors. Entries will compete against programs in their neighbourhood and move up or down depending on their score.

An interesting twist is the chance to enter warriors in 8 different categories including '94, '88, LP and nano. For full details of the rules see the official tournament page.

The deadline is 15th September. Good luck :-)

Friday, 1 July 2011

A Brief Introduction to Core War

What is Corewar?


Corewar is a programming game in which the aim is to eliminate all opponents from the memory of a virtual computer. Players write short battle programs to compete against each other.

Battle programs are written in Redcode, the assembly language of the MARS virtual processor. Redcode has 18 opcodes. Each Redcode instruction is made up of an opcode, a source pointer, a destination pointer, a source addressing mode and a destination addressing mode. For example, the mov instruction copies information from the source to the destination:

mov 10, 20

In the example, the source is 10 and the destination is 20. When the instruction is executed, it take the information in the cell 10 locations after the mov and copies it to the cell 20 locations after.

Here's another example, known as an imp:

mov 0, 1

When this executes, it copies the information from 0 locations ahead (i.e. itself) to 1 location ahead:

mov 0, 1
mov 0, 1 <--- the copy

Execution continues with the next instruction, so the program executes the copy it just made. Addresses in Corewar are relative to the cell they're stored in, so when the copy executes it makes a new copy one location ahead:

mov 0, 1
mov 0, 1 <--- the copy
mov 0, 1 <--- the second copy

The addressing mode affects how the address is interpreted. If no addressing mode is specified, direct addressing is used as in the examples above. The alternatives are immediate and indirect addressing.

Immediate addressing is indicated by an octothorpe (#). Instead of using data a number of cells away, it uses the data stored in the current instruction. For example:

add #10, 20

The # shows the data to be used is 10, not the value from the cell 10 locations away. add #10, 20 adds 10 to the value in the cell 20 locations ahead.

Indirect addressing is indicated by one of the following symbols, < @ > { * }. Instead of using data from a number of cells away, that data is used as a pointer to the actual data to be used. For example:
add #10, @1
dat 0,   19

When the add instruction executes, it adds 10 to the cell 20 locations ahead. @1 tells the Redcode processor to use the destination of the cell 1 location away as a pointer. This contains 19, so the destination is 19 locations after the dat, or 20 after the add.

Here's a quick run down of addressing modes. A-field is another name for the source pointer and b-field is for the destination pointer:

  • < use the b-field as a pointer after subtracting 1 from it
  • @ use the b-field as a pointer
  • > use the b-field as a pointer and afterwards add 1 to it
  • { use the a-field as a pointer after subtracting 1 from it
  • * use the a-field as a pointer
  • } use the a-field as a pointer and afterwards add 1 to it
  • # use the data in the currently executing instruction

Here are the 18 opcodes supported by the Redcode processor:

  • mov - copy data from source to destination
  • add - add value from source to destination
  • sub - subtract value at source from destination
  • div - divide destination by source
  • mod - destination = destination MODULO source
  • mul - multiply destination by source
  • seq - skip next instruction if source equal to destination
  • sne - skip next instruction if source not equal to destination
  • slt - skip next instruction if source less than destination
  • jmp - jump to a-field
  • jmn - jump to a-field if b-field non-zero
  • jmz - jump to a-field if b-field zero
  • djn - subtract 1 from b-field. if result non-zero, jump to a-field
  • spl - start a new thread at a-field
  • dat - destroy thread when executed
  • stp - store source to private memory
  • ldp - load private memory to destination
  • nop - no operation

Top Corewar Links


  • Beginners' Guide to Redcode
    Ilmari's guide to Redcode provides a gentle introduction to the art of Corewar.
  • Corewar Bibliography
    The Corewar Bibliography is a comprehensive index of Corewar articles and the ideal starting point to research any Corewar topic.
  • Corewars - King of the Hill
    KOTH.org is the provider of several online hills. Submit your program by email to compete against others.
  • KOTH@SAL Corewar Hills
    The hills at SAL present some alternative settings, including the beginner hill and the popular nano hill.
  • CoreWar "Koenigstuhl" Page
    Koenigstuhl is the Valhalla of Corewar! When an author publishes their battle programs, they're archived on the Koenigstuhl infinite hills.
  • Programming in Corewar
    In Corewar a battle is played out between computer programs, which attempt to eliminate all opponents within the memory of the MARS virtual computer.
  • Fizmo's Corewar Info
    The ultimate source for any information regarding Corewar, a programming game where small programs fight each other.

Thursday, 10 February 2011

An Early Description of Core War

Until I saw this description of Core War I assumed Dewdney and Jones were the first to use the term in the Core War Guidelines.

“Core war is a game surreptitiously played by systems programmers on large installations, where a player's goal in each fixed time slice of real time is to propagate his program elsewhere in memory, while doing as much “damage” (read: clearing to zero) as possible at random places in the hopes of causing the opponent's program to blow up. The game of core war is rarely mentioned with more than a whisper, and thus tends to be lost amid the din of easier and less abstract games such as Star Trek, Adventure or Dungeons and Dragons”
-- BYTE Magazine, July 1978, page 106-107


This brief description was published 6 years before A. K. Dewdney's first Core War article in Scientific American (May 1984, page 14-22).

Have you seen any other early mentions of Core War?

Monday, 17 January 2011

Revisiting the Dragon Curve

A few days ago I published code to draw the Heighway Dragon Curve. Here's a variation that's 3 lines shorter and plots the curve in 655360 cycles. The pMARS command line is pmarsv -s 90000 -c 1000000.

;redcode-fractal
;name Dragon Curve 2
;author John Metcalf

        width  equ 315
        stack  equ dragon+100
        plot   equ direct+width+1
        first  equ 80*width+50

        mov    #first,   plot
dragon  mov.ab count,    <plot
test    mov.b  @plot,    #0
        add.ba @plot,    direct
        div    #2,       @plot
        mod    #2,       test
        jmz    test,     test
        mod.a  #4,       direct
direct  add.b  3,        width+1
count   sub.ba #65536,   #1+1
        jmp    dragon,   -width+1

Sunday, 9 January 2011

Dragon Curve in Redcode

dragon curve in redcode

The Heighway Dragon Curve is fractal line than goes through a series of 90° turns, creating a pattern which fills a 2 dimensional space. The program plots 32768 points in 458741 cycles. The pMARS command line is pmarsv -s 90000 -c 500000.

;redcode-fractal
;name Dragon Curve
;author John Metcalf

        width  equ 315
        stack  equ dragon+100

dragon  mov.x  paira,    <stack
recur   djn    dragon,   #15
        mod.a  #4,       direct
        add.b  *direct,  plot
plot    mov    >recur,   80*width+110
        mov.ba >stack,   ret
ret     jmp    0,        }stack
turn    add.a  @stack,   direct
        mov.x  pairb,    <stack
        jmp    recur

direct  dat    3,        width
paira   dat    turn-ret, -1
        dat    0,        -width
pairb   dat    plot-ret, 1

Thursday, 9 December 2010

Corewar Programming Contest

The First International Corewar Programming Contest has just been announced, with a first prize of $50 sponsored by www.corewar.info.

The competition takes place in the unexplored area between '94nop and LP settings which has recently been investigated by Fizmo in Redcode Talk.

The exact settings are as follows:

Standard:CWS'94
Coresize:8000
Processes:200
Entry length:20
Points win:3
Points tie:1
Cycles:80000
Rounds:1000

The pMARS command line is pmars -p 200 -l 20 -r 1000. STP and LDP are forbidden, up to two entries are allowed and battles will take part in a round-robin tournament.

For more information, take a look at the announcement in rec.games.corewar.

Friday, 5 November 2010

Four Lines of Redcode

Sierpinski triangle

The Sierpinski triangle or gasket is a fractal named after the Polish mathematician Waclaw Sierpinski. Surprisingly the fractal can be generated with just 4 lines of Redcode:

        width  equ 126
        trail  equ (sum-CORESIZE%width)
        start  equ (trail-width+1)

sum     mov    #3,    @3
ptr     mov.b  trail, sum
        add.b  {ptr,  sum
        djn    sum,   #start

The magic incantation for pMARS is pmars -v 132. Alternatively set the width to 128 to view using CoreWin :-)

Sunday, 5 September 2010

Redcode Talk Issue 1

Redcode Talk
Christian Schmidt recently published the first issue of Redcode Talk. The issue contains a couple of articles by Fizmo:

  • The undiscovered area between LP & 94draft
  • Random Warrior Talk: One Man Army v1.0

Friday, 23 July 2010

Happy Numbers

Today's Programming Praxis challenges us to write a program to list the happy numbers up to a given limit. A number is happy if the sum of the square of it's digital eventually reaches 1. E.g. 7 is happy because 72=49, 42+92=97, 92+72=130, 12+32+02=10, 12+02=1.

Here's my solution in Redcode:

org    newcand

        base   equ 10
        limit  equ 100
        tries  equ 50

stack   dat    0
happy   dat    1
cand    dat    0
total   dat    0
repeat  dat    0
 
newcand mov.ba happy,     cand
        mov    #tries,    repeat
again   mov    #-1,       total
digits  mov.ab cand,      cand
        mod    #base,     cand
        div.a  #base,     cand
        mul.b  cand,      cand
        add.b  cand,      total
        jmn.a  digits,    cand
        jmz    found,     total
        mov.ba total,     cand
        add.a  #1,        cand
        djn    again,     repeat
nexthap seq    #limit,    happy
        jmp    newcand,   >happy
        dat    0

found   mov.b  happy,     <stack
writen  mov.b  @stack,    <stack
        div    #10,       >stack
        mod    #10,       @stack
        add    #48,       @stack
        jmn    writen,    <stack
        add    #1,        stack
wloop   sts    >stack,    0
        jmn    wloop,     stack
        sts.a  #10,       0
        jmp    nexthap

Sunday, 24 January 2010

Cross Simulator Core Graphics

One difficulty when trying to write code to plot graphics in Redcode is the width of the core display. The four most popular simulators uses a variety of different widths:

Simulator
Display Width
pMARS SDL mode 0
157
pMARS SDL mode 2
126
CoreWin
128
ARES
80
nMars
various

The simplest solution is to define a variable for the width which can be modified by the person running the program. Alternatively it's possible to use the the predefined VERSION constant to determine the simulator:

Simulator
Version
pMARS SDL mode 0
92
pMARS SDL mode 2
92
CoreWin
230
ARES
0
nMars
93

Putting the two together we can write the following code which sets the correct width for pMARS SDL, CoreWin and ARES:

width equ ( (VERSION==92)*157 + (VERSION==230)*128 + (VERSION==0)*80 )

Thursday, 7 January 2010

Fractals in Corewar

Koch Curve in RedcodeIn 1997 Anton Marsden organised a Corewar tournament with a difference.  The three rounds challenged players to use Redcode to solve a variety of problems.

In the third round of Anton's Corewar Tournament the challenge was to write a Redcode program to draw a pretty picture.  First place was taken by Ilmari Karonen with a fractal fern.

Here's my own attempt at creating a pretty picture in the core view of pMARS. It's a fractal known as the Koch Curve.

Here's the program, just 18 instructions:

width equ 157

        org    koch

        stack equ count+30

koch:   mov    #2-ptr, >stack
        jmp    count,  }move

        sub.a  #2,     move
        mov    #2-ptr, >stack
        jmp    count

        jmp    return, }move

count:  djn    koch,   #11
        mod.a  #8,     move
        div.a  #2,     move
        add.b  *move,  pos
        mul.a  #2,     move
pos:    add    #1,     koch+71*width/2+16
return: mov.ba <stack, ptr
ptr:    jmp    0,      >count

move:   dat    -1
        dat    -width
        dat    1
        dat    width

Have you tried to write a graphical display in Corewar?

Tuesday, 27 October 2009

Tinywarrior Issue 4

Tinywarrior issue 4, corewarThe fourth issue of Tinywarrior has just been published, the newsletter which reports the latest events and techniques for the tiny hill. Here's what you can expect to find in this issue:

Flux and the SPL/DIV Clear by John Metcalf examines a SPL/DIV clear inspired by G2.

Larger Than Infinity by Zul Nadzri reveals the results of Zul's experiments with White Noise.

Any feedback would be greatly appreciated.

Tuesday, 25 August 2009

Maezumo, Evolving for the Corewar Tiny Hill with a Twist

Maezumo, the Evolver with a TwistAt the beginning of August, Christian Schmidt released version 1.04 of Maezumo, his corewar evolver. If you're familiar with the old version the biggest difference you'll notice are the additions to the progress report.

Maezumo evolves warriors using traditional mutation, keeping a hill of the top warriors. Hill warriors are then injected back into the soup. Where Maezumo offers something innovative is in the hint modes.

If the hint modes are enabled, Maezumo generates warriors from inbuilt templates. These challenge the hill and if successful enter the soup for further enhancement by the mutation algorithm.

Maezumo is supplied with a Windows binary, Basic source code and all the necessary support files. To evolve for the tiny hill, I simply extracted the archived, changed the settings in maezumo.ini and double clicked maezumo.exe. I selected the scanner/paper hint mode to cover the two most successful tiny strategies.

After a 13 hour run, the top warrior on Maezumo's hill is an evolved style paper which scores 75 against SAL's tiny hill. I think it would be realistic to expect a strong tiny warrior after a 3 or 4 day run.

Have you tried Maezumo yet? If so, let me know your thoughts :-)

Thursday, 9 July 2009

TEV Hints and Another Evolved Bomber

Recently I've been experimenting with different hints in TEV0 and TEV12 hoping to guide the evolution of Redcode programs. TEV is a small program written in Basic and uses the principles of random mutation and survival of the fittest to create a Redcode program over a number of generations.

Redcode is the language of Corewar, a game in which two or more programs battle to control the memory of a virtual computer. Here's a quick introduction to Corewar. Traditionally programs are coded by hand, but a number of players have risen to the challenge of writing a program to evolve good contenders.

The purpose of a hint is to control the direction of evolution by issuing a score penalty for certain types of code. Here are the hints I've been experimenting with:

  • a penalty for three consecutive opcodes the same
  • a penalty for the first opcode being a SPL
  • a penalty for the a-mode of a SPL being #

This produced some really weird programs to begin with, but after relaxing the penalties stronger programs emerged. Unfortunately TEV still hasn't produced a decent replicator so instead here's the code for the most successful bomber of the latest run, medusa's mirror:

;redcode-nano
;name medusa's mirror
;author John Metcalf
;strategy evolved using TEV12 with hints
;assert CORESIZE==80

mov.i <46, $11
spl.i #-4, {56
mov.i <36, {79
mov.i {79, {54
djn.f $78, {59
end

Next I'm hoping to divide the pool into different regions and implement a different hint in each region. If you have any suggestions for hints, please let me know.

Thursday, 25 June 2009

1.2K Tiny Corewar Evolver

Here's the latest version of the Tiny Corewar Evolver, a small (<1.2K) GWBasic program to evolve Redcode warriors against a benchmark. This version producted Wrath of the Machines after a 28 hour run.

The two biggest differences from TEV0 are as follows:
  • no longer aborts a bad benchmark early
  • replaces the lowest scoring warrior with the current warrior

TEV12.BAT
@dir /b /o-d *.red >w.evo
@echo END >>w.evo
@gwbasic tev12
@erase ?.evo


TEV12.BAS
10 P$="pmars -s 80 -p 80 -c 800 -l 5 -b -k -P":R=142:L=5:P=25:K=80
20 O$="mov.imov.ispl.bdjn.f;xxxx":M$="<@>{*}$#"
30 DIM W$(99),A$(L,P),B$(L,P),C(L,P),D$(L,P),E(L,P),S(P):RANDOMIZE TIMER
40 W=0:OPEN "w.evo" FOR INPUT AS #1:M=LEN(M$):q=0:h=1
50 INPUT #1,W$(W+1):IF W$(W+1)<>"END" THEN W=W+1:GOTO 50 ELSE CLOSE #1
60 q=(q mod p)+1:J=1:FOR I=2 TO P:IF S(I)<s(j) THEN j=i
70 NEXT i:FOR I=1 TO L:A$(I,J)=A$(I,q):B$(I,J)=B$(I,q):C(I,J)=C(I,q)
80 D$(I,J)=D$(I,q):E(I,J)=E(I,q):NEXT I:S(J)=s(q)
90 Z=S(Q)/H:FOR I=1 TO L:IF RND*Z<.3 THEN C(I,q)=INT(RND*K)
100 IF RND*Z<.3 THEN E(I,q)=INT(RND*K)
110 Z$=MID$(M$,INT(RND*M)+1,1):IF RND*Z<.3 THEN B$(I,q)=Z$
120 IF RND*Z<.3 THEN D$(I,q)=","+Z$
130 IF RND*Z<.1 THEN A$(I,q)=MID$(O$,INT(RND*LEN(O$)/5)*5+1,5)+" "
140 NEXT I:OPEN "w.evo" FOR OUTPUT AS #1:FOR I=1 TO L
150 PRINT #1,A$(I,q);B$(I,q);C(I,q);D$(I,q);E(I,q):NEXT I:CLOSE #1
160 s(q)=0:FOR I=1 TO W:SHELL P$+" w.evo "+W$(I)+" >s.evo"
170 OPEN "s.evo" FOR INPUT AS #1:INPUT #1,Z$:CLOSE #1:Z=1
180 IF MID$(Z$,Z,1)<>" " THEN Z=Z+1:GOTO 180
190 s(q)=s(q)+3*VAL(LEFT$(Z$,Z))+VAL(RIGHT$(Z$,LEN(Z$)-Z)):NEXT I
200 IF s(q)>H THEN H=s(q):SHELL "copy w.evo best.war"
210 goto 60

Saturday, 20 June 2009

Results from an Even Simpler Corewar Evolver

Over the last week I've been removing as much as possible from TEV, the Tiny Corewar Evolver. The latest version is down to 1.2K and produced a mad mad bomber which entered SAL's nano hill in 7th place:

;redcode-nano
;name wrath of the machines
;author John Metcalf
;strategy evolved mad mad bomber
;strategy 28 hours with TEV 1.2K
;assert CORESIZE==80

spl.b #76, {32
mov.i >11, {49
mov.i }79, {76
mov.i <64, {29
djn.f $-3, {58
end

Wednesday, 10 June 2009

Corewar Tiny Evolver TEV v0

The Corewar Tiny Evolver is a small (< 1.5K) program written in GWBasic. After a couple of hours evolving, TEV is capable of producing programs able to compete with hand-written progams and enter the Corewar nano hill.

Instructions

Place TEV0.BAS, TEV0.BAT and a selection of benchmark warriors in the same directory. The parameters in line 10-20 are set up for the nano hill but can be adjusted if required.

Run TEV0.BAT. Evolution will continue until you decide to terminate the program. Throughout the process, the best warrior can always be found in the file BEST.WAR.

Program Layout

  • batch file: generate a list of benchmark warriors, run the evolver
  • 10-20: set evolution parameters (see Parameters)
  • 30-50: initialise the evolver
  • 60-110: mutate current warrior based on how well it performs
  • 120-130: write current warrior to file
  • 140-180: benchmark current warrior, abort if poor performance
  • 190: if benchmark warrior is best to date, save a copy
  • 200-220: replace a lower scoring warrior with current warrior
  • 230-250: if score below threshold, discard warrior and select another
  • repeat from 60

Parameters

The evolution parameters are set in lines 10-20
  • K: coresize
  • L: maximum warrior length
  • P: number of warriors in the evolution pool
  • R: number of rounds per benchmark battle
  • M$: addressing modes to be used
  • O$: opcode/modifier combinations to be used
  • P$: pMARS command line

TEV0.BAT
@dir /b /o-d *.red >w.evo
@echo END >>w.evo
@gwbasic tev0
@erase ?.evo


TEV0.BAS
10 P$="pmars -s 80 -p 80 -c 800 -l 5 -b -k -P":R=142:L=5:P=20:K=80
20 O$="mov.ispl.bdjn.f;xxxx":M$="<@>{*}$#"
30 DIM W$(500),A$(L,P),B$(L,P),C(L,P),D$(L,P),E(L,P),S(P):RANDOMIZE TIMER
40 W=0:OPEN "w.evo" FOR INPUT AS #1:M=LEN(M$):H=80
50 INPUT #1,W$(W+1):IF W$(W+1)<>"END" THEN W=W+1:GOTO 50 ELSE CLOSE #1
60 FOR I=1 TO L:IF RND*S(1)/H<.6/L THEN C(I,1)=(C(I,1)+INT((RND-RND)*K))MOD K
70 IF RND*S(1)/H<.7/L THEN E(I,1)=(E(I,1)+INT((RND-RND)*K))MOD K
80 IF RND*S(1)/H<.3/L THEN B$(I,1)=MID$(M$,INT(RND*M)+1,1)
90 IF RND*S(1)/H<.4/L THEN D$(I,1)=MID$(M$,INT(RND*M)+1,1)
100 IF RND*S(1)/H<.3/L THEN A$(I,1)=MID$(O$,INT(RND*LEN(O$)/5)*5+1,5)
110 NEXT I
120 OPEN "w.evo" FOR OUTPUT AS #1:FOR I=1 TO L
130 PRINT #1,A$(I,1)+" "+B$(I,1);C(I,1);","+D$(I,1);E(I,1):NEXT I:CLOSE #1
140 S(1)=0:FOR I=1 TO W:SHELL P$+" w.evo "+W$(I)+" >s.evo"
150 OPEN "s.evo" FOR INPUT AS #1:INPUT #1,Z$:CLOSE #1:Z=1
160 IF MID$(Z$,Z,1)<>" " THEN Z=Z+1:GOTO 160
170 S(1)=S(1)+3*VAL(LEFT$(Z$,Z))+VAL(RIGHT$(Z$,LEN(Z$)-Z))
180 IF I>W/5 AND S(1)*150/H<I*R THEN 240 ELSE NEXT I
190 S(1)=100*S(1)/(W*R):IF S(1)>H THEN H=S(1):SHELL "copy w.evo best.war"
200 FOR J=2 TO P:IF S(J)>S(1) THEN NEXT J:GOTO 230
210 FOR I=1 TO L:A$(I,J)=A$(I,1):B$(I,J)=B$(I,1):C(I,J)=C(I,1)
220 D$(I,J)=D$(I,1):E(I,J)=E(I,1):NEXT I:S(J)=S(1)
230 IF S(1)>H*.9 THEN 60
240 Z=INT(RND*(P-1))+2:FOR I=1 TO L:A$(I,1)=A$(I,Z):B$(I,1)=B$(I,Z)
250 C(I,1)=C(I,Z):D$(I,1)=D$(I,Z):E(I,1)=E(I,Z):NEXT I:S(1)=S(Z):GOTO 60

Wednesday, 27 May 2009

The Incredible! Corewar Secret

Towards the end of 2002 a five line warrior entered the KOTH.org '94 Draft hill in fifth place, later becoming King of the Hill. Although I've often been asked about Incredible, so far I've kept its secret quiet:
Program "Incredible!" (length 5) by "John Metcalf"
;strategy tweaked away one instruction

Last battle concluded at : Sun Dec 1 17:26:58 EST 2002

# %W/ %L/ %T Name Author Score Age
1 40/ 42/ 18 Herbal Avenger Michal Janeczek 139 18
2 39/ 42/ 19 Combatra David Moore 136 7
3 24/ 11/ 65 Blowrag Metcalf/Schmidt 136 62
4 35/ 35/ 30 Mantrap Arcade Dave Hillis 136 2
5 24/ 13/ 64 Incredible! John Metcalf 135 1
6 28/ 22/ 51 Reepicheep Grabun/Metcalf 133 135
7 27/ 22/ 52 Son of Vain Oversby/Pihlaja 132 106
8 33/ 34/ 33 Cyanide Excuse Dave Hillis 131 8
9 25/ 22/ 53 Paperazor Christian Schmidt 129 79
10 28/ 27/ 45 Uninvited John Metcalf 129 125

Incredible is a standard paper/imp using an exploit to hide its true length from the KOTH script. The script has two sections. The front-end checks a warrior compiles correctly and extracts the name, author, strategy and length for the reports. The back-end runs the actual battle.

Incredible takes advantage of the fact the front-end calls pMARS with a different number of rounds to the back-end. This is used to present different code to the front-end:
;redcode-94
;name length exploit
;author John Metcalf
;strategy demonstrate how to hide a program's true length
;assert CORESIZE == 8000

for ROUNDS < 5
;the front-end sees this code
for 5
dat 0, 0
rof
rof

for ROUNDS > 4
;the back-end sees this code
;insert warrior code here
rof
end

I couldn't reveal the secret earlier because the KOTH script crashes if the code for the back-end contains errors. The script also crashes if the exploit is used to send '94 code to the '88 hill or p-space code to the no p-space hill. Unfortunately KOTH.org will be closing in a few days so it should be safe to share this now.