TUTORIAL
Bienvenido a Core War
Esto es un juego de programación. Escribes un bot en Redcode, un ensamblador diminuto, y lo sueltas en el núcleo: un anillo de 8000 celdas de memoria compartido con los bots enemigos. Cada bot ejecuta una instrucción por turno. No hay muros ni reglas de combate: quien sobrescribe el código del otro, o aguanta vivo más tiempo, gana la ronda. La Arena muestra todo el núcleo como píxeles, así que ves a tu programa arrastrarse, bombardear y escanear en tiempo real.
Las lecciones empiezan con un bot de una sola línea y terminan con un guerrero que cambia de estrategia entre rondas. Puedes saltar adelante o volver atrás cuando quieras desde la lista de pasos. Cada lección trae un bot completo: ábrelo en el editor, lánzalo, cambia un número y vuelve a lanzarlo.
Lección 0: Cómo se juega
- Bots: tus guerreros y la biblioteca de solo lectura. CLONA un bot de la biblioteca para editar una copia.
- Editor: escribe Redcode; los errores aparecen abajo. LANZAR abre la arena con este bot ya seleccionado.
- Arena: rellena los slots de bots (un bot solo es una prueba,
+ BOTañade más), elige rondas, velocidad y semilla. Observa el núcleo: cada píxel es una celda, coloreada según el último guerrero que la escribió; las celdas brillantes se están ejecutando. - Partidas: una partida en curso se guarda automáticamente; reanúdala más tarde o comparte el archivo
.cdsave.
Lección 1: El Imp
El núcleo es un anillo de 8000 celdas. Un proceso ejecuta una celda por turno y pasa a la siguiente. MOV copia una celda. Con el modificador .I copia la instrucción entera, y #0 significa "esta misma instrucción".
;redcode-94
;name Imp
;author Tutorial
;strategy Copies itself one cell forward, forever.
MOV.I #0, 1
END
En cada turno, el Imp se copia en la celda siguiente y luego ejecuta esa copia. Recorre todo el núcleo sobrescribiendo lo que encuentra a su paso. Un solo DAT no puede matarlo (simplemente lo sobrescribe), pero tampoco mata nada por sí mismo: suele acabar en empate.
Enfréntalo a Dwarf de la biblioteca y observa el rastro verde.
Lección 2: Dwarf, el bombardero
Un DAT mata al proceso que lo ejecuta. Dwarf lanza DATs cada cuatro celdas, así que cualquier guerrero de más de 3 celdas acaba recibiendo un impacto.
;redcode-94
;name Dwarf
;author Tutorial
;strategy Drops a DAT every 4 cells.
ORG start
target DAT.F #0, #0
start ADD.AB #4, target
MOV.AB #0, @target
JMP start
END
ADD.AB #4, target: suma 4 al campo B de target. Ese campo es nuestro puntero.MOV.AB #0, @target:@significa "ve a donde apunta el campo B de target"; escribe 0 en el campo B de esa celda. Es el Dwarf exacto del borrador de ICWS'94, y no es una bombaDATde verdad: solo pone a cero un campo. Aun así rompe la mayoría del código (un Imp se convierte enMOV.I 0, 0y se queda parado). La lección 3 lanza bombasDATcompletas.JMP start: bucle.
¿Por qué 4? 8000 es divisible por 4, así que el puntero recorre 2000 celdas y vuelve exactamente a target, que ya es un DAT. Dwarf nunca bombardea sus propias tres líneas de código.
Lección 3: Modificadores
El modificador elige qué campos se mueven. Compara:
MOV.A a, bcopia solo el campo A.MOV.B a, bcopia solo el campo B.MOV.AB a, bcopia el campo A de a en el campo B de b.MOV.F a, bambos campos.MOV.I a, bla instrucción entera, opcode incluido.
El Dwarf de arriba usa ADD.AB para que el 4 inmediato (un campo A) vaya al campo B de target. Aquí tienes un Dwarf que lanza instrucciones DAT completas con MOV.I. Su bomba tiene operandos con predecremento: cuando un proceso enemigo la ejecuta, ambos operandos se evalúan antes de que el proceso muera, así que otras dos celdas lejanas también sufren daños.
;redcode-94
;name Dwarf Plus
;author Tutorial
;strategy Full-instruction DAT bombs with decrementing fields.
ORG start
ptr DAT #0, #0
bomb DAT <2667, <5334
start ADD.AB #4, ptr
MOV.I bomb, @ptr
JMP start
END
Enfrenta Dwarf a Dwarf Plus varias veces con la misma semilla.
Lección 4: Modos de direccionamiento y la puerta anti-imp
Los dos operandos se evalúan en cada instrucción, incluso los que JMP ignora. < decrementa el campo B de la celda direccionada antes de usarlo. Un JMP que decrementa una celda una y otra vez es una puerta anti-imp: cuando una copia del Imp (MOV.I 0, 1) cae ahí, su campo B pasa a ser 0, así que se copia sobre sí misma y el proceso avanza hacia núcleo vacío y muere.
;redcode-94
;name Gated Dwarf
;author Tutorial
;strategy Dwarf whose loop instruction also gates the cell before it.
ORG start
gate DAT #0, #0
target DAT #0, #0
start ADD.AB #4, target
MOV.AB #0, @target
JMP start, <gate
END
Enfrenta Gated Dwarf al Imp: ahora el Imp suele morir en lugar de empatar (la puerta se activa una vez por vuelta del bucle, así que necesita unas cuantas vueltas). Como target y start están 1 y 2 celdas después de gate, y las bombas caen en múltiplos de 4 desde target, la puerta nunca recibe una bomba.
Lección 5: SPL y el anillo de imps
SPL inicia un segundo proceso. Los procesos de un mismo guerrero se turnan. Tres imps separados 2667 celdas (3 x 2667 = 8001, una más que el núcleo) se persiguen y avanzan una celda cada tres copias: un anillo de imps. Es mucho más difícil de detener con una puerta que un solo imp.
;redcode-94
;name Imp Ring
;author Tutorial
;strategy 3-point imp ring launched with SPL.
step EQU 2667
ORG start
start MOV.I imp, imp+step
MOV.I imp, imp+2*step
SPL imp+step
SPL imp+2*step
JMP imp
imp MOV.I #0, step
END
EQU define una constante. imp+2*step es una expresión que evalúa el ensamblador. Prueba step = 4001 con dos imps.
Lección 6: Escáneres
Un escáner busca al enemigo antes de bombardear. El núcleo vacío es DAT 0, 0, así que un campo B distinto de cero significa "aquí hay algo". JMZ salta si el campo comprobado es cero.
;redcode-94
;name Scanner
;author Tutorial
;strategy Scan every 3039th cell for a non-zero B-field, bomb it.
step EQU 3039
ORG scan
ptr DAT #0, #0
bomb DAT #0, #0
scan ADD.AB #step, ptr
JMZ.B scan, @ptr
MOV.I bomb, @ptr
JMP scan
END
ADD.AB #step, ptravanza el puntero.JMZ.B scan, @ptr: si el campo B de la celda escaneada es cero, vuelve a escanear.- Si no, suelta la bomba y continúa.
Contra Dwarf, el escáner encuentra rápido el código del bombardero. Contra un Imp, desperdicia bombas en su rastro. Un escáner de verdad usa un paso impar que nunca repite celda y se salta su propio código.
Lección 7: Arranque (boot)
El código que cargas es un blanco fijo. Copia el guerrero real lejos, salta allí y deja que el enemigo malgaste bombas en el lanzador. Un bucle de MOV con punteros con predecremento copia hacia atrás; DJN con un inmediato cuenta las iteraciones en su propio campo B.
;redcode-94
;name Boot Dwarf
;author Tutorial
;strategy Copies Dwarf 3000 cells away and runs the copy.
dist EQU 3000
len EQU 4
ORG boot
boot MOV.I <src, <dst
DJN boot, #len
JMP dwarf+1+dist
src DAT #0, dwarf+len
dst DAT #0, dwarf+len+dist
dwarf DAT.F #0, #0
ADD.AB #4, dwarf
MOV.AB #0, @dwarf
JMP dwarf+1
END
<src: decrementa el campo B de src y luego lee la celda a la que apunta: primero la última línea de Dwarf.<dst: lo mismo en el lado del destino.DJN boot, #len: decrementa el propio campo B delDJNy repite el bucle mientras no sea cero.JMP dwarf+1+dist: dwarf en sí es elDAT; la ejecución empieza en elADDque lo sigue.- Las referencias de Dwarf son relativas (
dwarf+1,@dwarf), así que la copia funciona sin cambios.
Lección 8: P-space, aprender entre rondas
Cada guerrero conserva 500 celdas privadas entre las rondas de una partida. La celda 0 indica cómo fue la última ronda: 0 = morimos, 1 = ganamos, 2 = empate. LDP carga una celda y STP guarda una. Este guerrero recuerda en la celda 1 qué estrategia usó y cambia cada vez que pierde.
;redcode-94
;name Switcher
;author Tutorial
;strategy Runs Dwarf or an imp ring; switches after a lost round.
step EQU 2667
ORG start
res DAT #0, #0
cur DAT #0, #0
start LDP.AB #0, res ; res.B = last result
LDP.AB #1, cur ; cur.B = strategy 0 or 1
JMN.B keep, res ; did not lose: keep it
MUL.AB #-1, cur ; toggle 0 <-> 1
ADD.AB #1, cur
keep STP.B cur, #1 ; remember it
JMZ.B dwarf, cur
MOV.I imp, imp+step
MOV.I imp, imp+2*step
SPL imp+step
SPL imp+2*step
JMP imp
imp MOV.I #0, step
target DAT.F #0, #0
dwarf ADD.AB #4, target
MOV.AB #0, @target
JMP dwarf
END
Juega una partida de 10 rondas contra Scanner y observa cómo cambia de estrategia tras cada derrota. Los guerreros de p-space reales ("pswitchers") eligen entre varios componentes y son una parte importante del juego competitivo moderno.
Y ahora qué
- Clona los clásicos de la biblioteca y léelos línea a línea.
- Cambia un solo número cada vez y vuelve a lanzar con la misma semilla.
- Lee las secciones del Manual sobre modificadores por defecto y orden de evaluación; ahí se esconden la mayoría de las sorpresas.