The winner shall be the program that will have killed all its opponents
How do you kill an opponent ?
By putting him in a situation were it will try to execute the code located in a place that doesn't belong to him.
A program can also be killed if it tries to read data in a location that doesn't belong to him or if it tries to execute an area that contains data instead of redcode. How do you take possesion of a location ?
A program takes possession of a location just by the action of accessing it in WRITE
To make it much more interesting, there is an instruction 'SPL' in the redcode that make it possible to split the execution of a program into two independent programs. To keep equality between the oponents, the cpu time is shared on a 1 to 1 basis. That is to say that if at a certain moment, opponent A runs 4 programs and opponent B runs 2 programs, then each of the 2 programs of opponent B will run twice as fast as the ones of opponent A.
With this 'SPL' instruction, a corewar look like a fight for reproduction
There was described the language defined for this War.
I have written in 'C' a program able to run this language on a PComputer screen.
It can be very easily adaptated to any platform since very few procedures are system dependant.
Now, let's go for the Demo
Get the executable for PC
Get also some example Redcode Programs
Open a dos window. Run mars. You will see displayed :
Syntax : mars battle_field_size prog1name [prog2name[..[prog4name]]] RedCode file names default extension is RED. The maximum oponents number is 6.
This means that mars requires parameters on the command line
These are the battle field size, followed by the names of the fighting programs.
Up to 6 can run simultaneously
As the program is written today, the maximum battle field size is 4000.
The screen displays 2000 locations of the battle field
The color of each square indicates the owner of the location
A black square is free (virgin).
The active Keys are
<space bar> for a pause in the process and a status of the fight
<s> to stop the fight immediately
<t> to toggle the area displayed when the battle field size is more than 2000.
Here is the source code
Now let's analyse a little redcode program called CHANG, that reached second place in a CoreWar contest
MOV #0 &-1 JMP &-1 DAT #9 * SPL &-3 SPL &4 ADD #-16 &-3 MOV #0 @-4 JMP &-4 SPL &2 JMP &-1 MOV &0 &1The star is not an executable instruction, is an indication for the interpreter of where the interpreter should start the execution of this program. So the first instruction is 'SPL &-3'
MOV #0 &-1 JMP &-1It is a shield against any agressor trying to attack from lower addresses.
Now let's come back to process 1
SPL &4 ADD #-16 &-3 MOV #0 @-4 JMP &-4 SPL &2 JMP &-1 MOV &0 &1After two splits we reach
SPL &2 JMP &-1 MOV &0 &1You guess what it does ?
MOV &0 &1Is an program autonomously generating its own code !
SPL &2 JMP &-1Generates continuously these gliders
ADD #-16 &-3 MOV #0 @-4 JMP &-4is a bit more complex, because it uses indirect relative addressing '@'
MOV #0 &-1 JMP &-1 DAT #9 * SPL &-3 SPL &4 ADD #-16 &-3 MOV #0 @-4 JMP &-4 SPL &2 JMP &-1 MOV &0 &1So,
ADD #-16 &-3Adds -16 to what is located 3 lines up, i.e. it substracts 16 to DAT #9, so that after, we have DAT #-7
MOV #0 @-4Writes the value 0 at the relative address 4 lines up relative to this line. At this address there is DAT #-7. So we write a 0 just 5 address before the beginning of the program.
Here is what it makes visually after some time :
c DAT #0 * s MOV #7 &c l MOV @c <a DJN &l &c SPL @a ADD #132 &a JMZ &s &c a DAT #100There are four new things in this code : labels (one letter long) that ease reading, indirect relative addressing with pre-decrement by '<' , 'DJN' a loop with test and 'JMZ' a jump with test.
It begins with initialising the loop count to 7. Then it copies itself 100 addresses away.
Gives birth to its child and restarts at the beginning. The next copy will be 232 addresses away. Etc...
l MOV @c <a DJN &l &cIs the copy loop. Can't be shorter.
SPL @aGives birth to the son.
JMZ &s &cIs smart. It says: jump only if there is a zero in address c. This should be normally the case. If we don't read zero, it means that something wrong is going on. In that case, we try to execute the line DAT #100 which is not an instruction. We suicide. This way we release CPU time for all the other healthy processes.
Here is a terrible fight between mouse (winner) and lcd4