Lessons
Read them in order. Each "Try it" button opens the arena with that warrior loaded. Then press Fight.
Memory is a ring of cells
The battlefield is called the core: 8000 cells in the standard game. Every cell holds one instruction, and the end wraps around to the start, so cell 8000 is cell 0 again.
Addresses are relative: 0 means this cell, 1 the next one, -1 the previous one. Neither warrior knows where it was loaded.
Empty cells hold DAT 0, 0. A program that executes a DAT dies. Make every enemy process hit a DAT and you win. If nobody dies within 80,000 cycles, it's a tie.
Your first warrior: the Imp
This program copies itself into the next cell. The next cell is exactly where it runs next, so it crawls through memory forever.
The Imp almost never wins, but it is very hard to kill. It mostly ends in ties.
โ๏ธ Try it in the arenaBombing: the Dwarf
bomb is a DAT whose B-field works as a target pointer. Each loop adds 4 to the target, then copies the bomb to wherever the pointer says (that's what @ means).
It covers every 4th cell. The Dwarf itself is 4 cells long, so its own bombs miss it.
โ๏ธ Try it in the arenaAddressing modes
The symbol in front of a number says how to use it:
| #5 | the number 5 itself (immediate) |
| $5 | the cell 5 ahead (direct, the default) |
| @5 | go to cell 5, then follow its B-field |
| *5 | go to cell 5, then follow its A-field |
| <5 {5 | like @ and *, but subtract 1 first |
| >5 }5 | like @ and *, but add 1 afterwards |
More processes: SPL
SPL starts a new process. A warrior gets one instruction per turn however many processes it has, so more processes doesn't mean more speed. It means the warrior is harder to kill.
A replicator like this one copies itself across the core faster than most bombers can hit it.
โ๏ธ Try it in the arenaLook before you shoot: scanners
SNE compares two cells. If they differ, one of them isn't empty memory, so something is there. The scanner bombs both cells and keeps looking.
When the scan finishes, it wipes every cell of the core except its own.
โ๏ธ Try it in the arenaRock, paper, scissors
Most warriors are one of three kinds:
Stones (bombers like the Dwarf) are small and fast. Papers (replicators) make copies faster than stones can bomb them. Scissors (scanners) find papers and cut them down, but stones are too small for them to find in time.
Paper beats stone, scissors beat paper, stone beats scissors, roughly. Good warriors mix two kinds.
Safety in numbers: imp rings
Three imps, spaced (CORESIZE+1)/3 cells apart, take turns: each one copies itself onto the spot the next one is about to run. Together they advance one cell per round, like a single fat imp.
SPL 1 followed by MOV -1, 0 is a classic trick for getting exactly three processes. Bombers struggle to kill all three in time.
Clearing the core
SPL #0 creates an endless stream of processes, and each one wipes one cell and moves the pointer on. Eventually every cell gets a DAT, including the ones the enemy is hiding in.
The trick: when the pointer wraps all the way around and hits itself, the bomb that lands there resets it to 4, so the Broom never sweeps away its own code. It's one of the few things that reliably kills an Imp.
โ๏ธ Broom vs ImpTraps: make them work for you
A DAT bomb kills one process. Against a replicator running thousands of them, that's hopeless. So instead of killing, trap: plant a JMP on the enemy that leads into an SPL 0 loop.
Trapped processes multiply uselessly instead of copying or bombing, and a final DAT clear wipes them all out. That's how Mousetrap beats Mice nine times out of ten.
Small cores: Tiny and Nano
Same game, less room. Tiny has 800 cells and allows 20 instructions. Nano has 80 cells and only 5 instructions. Warriors start just a few cells apart and battles are over in a blink.
Long, clever warriors don't fit, so there are fewer tricks to learn. A beginner, an evolutionary algorithm or an AI has a real chance against experienced players here. Write numbers in terms of CORESIZE and the same warrior works on all three.
Your turn
Open the template in the arena, change something, and press Test Warrior 1 against every built-in. Or go straight for the challenges. Your score is points per 100 rounds: 3 for a win, 1 for a tie, so the maximum is 300.
Getting above 150 takes some real thought. Getting above 200 means you've found something clever.
โ๏ธ Open the templateRedcode reference
Everything the simulator on this site understands. It follows the ICWS '94 draft, the standard used by Core War competitions since 1994.
Rule sets
| Standard | Tiny | Nano | |
|---|---|---|---|
| core size | 8000 | 800 | 80 |
| cycles before a tie | 80,000 | 8,000 | 800 |
| max processes | 8000 | 800 | 80 |
| max length | 100 | 20 | 5 |
| min distance | 100 | 20 | 5 |
Scoring: 3 points per win, 1 per tie, 0 per loss.
Instructions
| DAT | data; any process that runs it dies |
| MOV | copy A to B |
| ADD SUB MUL | B = B + A, B โ A, B ร A |
| DIV MOD | B = B รท A, B mod A; dividing by 0 kills the process |
| JMP | jump to A |
| JMZ / JMN | jump to A if B is zero / not zero |
| DJN | decrement B, jump to A if it's not zero |
| SEQ (CMP) | skip the next instruction if A equals B |
| SNE | skip the next instruction if A differs from B |
| SLT | skip the next instruction if A is less than B |
| SPL | queue the next instruction, then a new process at A |
| NOP | do nothing |
Addressing modes
| # | immediate: the number itself, pointing at this instruction |
| $ | direct: the cell that many steps away (default) |
| @ | B-indirect: go there, then follow its B-field |
| * | A-indirect: go there, then follow its A-field |
| < | like @, but decrement that B-field first |
| { | like *, but decrement that A-field first |
| > | like @, but increment that B-field afterwards |
| } | like *, but increment that A-field afterwards |
All addresses are relative to the instruction being executed, and wrap around the core.
Modifiers
A modifier like MOV.AB says which fields the instruction reads and writes.
| .A | A-field to A-field |
| .B | B-field to B-field |
| .AB | A-field to B-field |
| .BA | B-field to A-field |
| .F | both: A to A and B to B |
| .X | both, crossed: A to B and B to A |
| .I | the whole instruction (MOV, SEQ, SNE; arithmetic and SLT treat it as .F) |
Default modifiers
Leave the modifier out and it's chosen from the instruction and the modes:
| DAT NOP | .F |
| MOV SEQ SNE | .AB if A is #, else .B if B is #, else .I |
| ADD SUB MUL DIV MOD | .AB if A is #, else .B if B is #, else .F |
| SLT | .AB if A is #, else .B |
| JMP JMZ JMN DJN SPL | .B |
Syntax
| label | loop MOV 0, 1 names an address; a trailing colon is allowed |
| EQU | step EQU 4 defines a constant |
| ORG | ORG start sets where execution begins |
| END | ends the warrior; END start also sets the start |
| FOR / ROF | i FOR 3 โฆ ROF repeats lines; &i becomes 01, 02, 03 |
| expressions | + - * / %, parentheses, comparisons, && || |
| one operand | DAT x means DAT 0, x; JMP x means JMP x, 0 |
| ;name ;author | comments that name your warrior |
Predefined constants
| CORESIZE | cells in the core |
| MAXCYCLES | cycles before a tie |
| MAXPROCESSES | process limit per warrior |
| MAXLENGTH | maximum instructions |
| MINDISTANCE | minimum gap between warriors |
| WARRIORS | number of warriors (2) |
Use them to write warriors that work under every rule set, e.g. step EQU (CORESIZE+1)/3.
How a cycle runs
- Each warrior has a queue of processes. It starts with one, at its start address.
- Warriors take turns. On its turn, a warrior takes the first process off its queue and runs one instruction.
- That process goes back on the end of the queue at its next address, unless it ran a DAT or divided by zero.
SPLqueues the next instruction first, then the new process (if the queue isn't full).- A warrior with an empty queue is dead. The last one alive wins. If time runs out, it's a tie.
Warriors are loaded at random positions at least MINDISTANCE apart, so every round is different. That's why scores are averaged over many rounds.
Not supported (yet)
P-space (LDP, STP, PIN), battles between more than two warriors, and read/write distance limits. Standard '94 warriors that don't use these run unchanged.