Core Wars is a game in which two opposing warrior programs try to destroy each other inside the memory of a virtual machine. They do this by overwriting each other's instructions, and the first program to execute an illegal instruction loses. Each program is written in an assembly-like language called Redcode, and the virtual machine that runs the two programs is the Memory Array Redcode Simulator (MARS). Your task is to write a MARS that reads two Redcode programs, simulates them, and prints which program wins.
MARS simulates an unusual environment compared with typical processors. The exact rules are:
Every MARS instruction has an opcode written as a three-letter mnemonic plus two operands, the A field and the B field. Each operand is a number in 0-7999 and uses one of three addressing modes:
#, as in #1234. An immediate operand is a literal value. For example, the A field of an ADD (integer addition) may be immediate, in which case its literal value is one of the numbers being added.\$, as in \$1234. A direct operand is an offset relative to the current IP address. For instance, if ADD #5 \$3 is stored at location 4357, it adds the literal 5 to the value in the B field of location 4360 (4357 + 3); if the same instruction were at location 132, it would use the B field of location 135 (132 + 3).@, as in @3, and work like pointers. The indirect operand is an offset relative to the current IP that identifies a first location; the value in the B field of that location is then used as a further offset from that same location to identify a second location. The B field of this second location is the one actually operated on. For example, if location 4357 holds ADD @1 @3, location 4358 holds 11 in its B field, and location 4360 holds 7996 in its B field, then the instruction adds the values in locations 4369 (4358 + 11) and 4356 (4360 + 7996 mod 8000).Each opcode is defined below. Even instructions that do not use both operands must still specify them, because other instructions may use those operands as data storage. Some instructions update only the B field of another instruction; that changes the field's numeric value but not its addressing mode.
| Opcode | Behavior |
|---|---|
| DAT | Serves two purposes: it is a generic placeholder for arbitrary data, and attempting to execute it terminates the simulation with the executing program losing. This is the only way a program can end, so each warrior tries to overwrite the other with DAT instructions. Both operands must be immediate. |
| MOV | If the A operand is immediate, its value is copied into the B field of the instruction selected by MOV's B operand. Otherwise the entire instruction (all field values and addressing modes) at location A is copied to location B. The B operand cannot be immediate. |
| ADD | If the A operand is immediate, its value is added to the B field of the instruction selected by ADD's B operand, and the result is stored back into that B field. Otherwise both operands select instructions: the A and B fields of the instruction at A are added respectively to the A and B fields of the instruction at B, and both results are written to the A and B fields of the instruction selected by ADD's B operand. The B operand cannot be immediate. |
| JMP | Jump to the address given by the A operand: the IP is set to that address instead of being incremented. The A operand cannot be immediate. The B operand must be immediate and is unused. |
| JMZ | If the B field of the instruction selected by JMZ's B operand is zero, jump to the address given by the A operand. Neither operand can be immediate. |
| SLT | If A is immediate, compare its value with the B field of the instruction selected by SLT's B operand; otherwise compare the B fields of the two instructions selected by the operands. If the first value (the one from A) is less than the second, skip the next instruction. The B operand cannot be immediate. |
| CMP | Compare the entire contents of the locations selected by A and B. If they are equal (same opcode and the same values and addressing modes in both operand fields), skip the next instruction. Neither operand can be immediate. |
The first line contains a single integer n, the number of independent simulations to run. Each simulation provides a pair of programs, warrior number one and warrior number two, each given in this format:
The address ranges occupied by the two programs never overlap. Every location not loaded with warrior code is initialized to DAT #0 #0. Execution always starts with warrior number one (the warrior read first).
Each simulation runs until one warrior executes a DAT instruction, or until a total of 32000 instructions (counting both warriors) have been executed. If a warrior executes a DAT, the other warrior wins; print Program #x is the winner., where x is 1 or 2 for the winning warrior. If neither warrior executes a DAT before the instruction limit is reached, the warriors tie; print Programs are tied.