CoreWar


Nuestro programa lucha contra sus enemigos en una máquina
virtual. Solo una programación inteligente puede darle la
victoria. Y su victoria será tambien la nuestra, en el
torneo de CoreWar que está organizando Virus Report.

 

En el año 1984, A. K. Dewdney presentó un juego en su
columna de Scientific American (Investigación y Ciencia).
En este juego, llamado CoreWar, dos programas escritos en
un assembler imaginario y limitado luchaban entre si. El
juego tuvo tanto éxito que se creó la ICWS (International
Core Wars Society), organización que realiza torneos
internacionales todos los años. No solo eso, sino que la
sociedad se expandió por el mundo e incluso se efectuaron
torneos en Buenos Aires, el primero de ellos en 1988 en
la Universidad de Buenos Aires.

El lenguaje

El assembler que se utiliza se llama Redcode, y consta de
sólo diez instrucciones. En el recuadro 1 vemos la lista
de las instrucciones. En este assembler no existen los
registros ni el direccionamiento absoluto. Para ejecutar
los programas necesitamos un simulador de la máquina
virtual que los contiene: el MARS. Estas son las siglas
de Memory Array Redcode Simulator, además de significar
Marte en inglés, el dios de la guerra. La memoria de esta
máquina es circular, o sea, si tiene 2000 posiciones de
memoria, numeradas de 0 a 1999 la posición 2000 equivale
nuevamente a la primera posicion o número 0. De todas
formas, los números veraderos no importan, ya que no
existe el direccionamiento absoluto, sólo trabajamos con
posiciones relativas a la actual. Cada posición de
memoria, a diferencia de las máquinas que conocemos,
contiene una instrucción completa con hasta dos
operandos. De esta forma, de una sola vez podemos copiar
una instrucción completa o un dato. Otra cosa extraña que
tiene este procesador, es la instrucción SPL. Con ella
podemos dividir el procesamiento de nuestro programa en
varias copias, haciendo un multitasking. Esto tiene sus
ventajas obvias, como tener más frentes de ataque, pero
tambien tiene desventajas. Para hacer multitasking de
esta forma el programa primero debe copiarse a otra
posición de memoria y luego pasarle el control del
procesador mediante la instrucción SPL. Cada contrincante
tiene uso del procesador por turnos, y si existe más de
una copia de uno de ellos le tocará una vez a cada copia.
Esto es así: supongamos que existen los programas A y B.
Si el A se divide en A1 y A2, la secuencia de ejecución
será: A1, B, A2, B, A1, B, A2... etc. Vemos que para que
el multitasking sea eficaz debemos tener en cuenta este
esquema de funcionamiento para que no sea una molestia
inútil dividirse en varios programas.

Direccionamiento

Como podemos ver en el recuadro 2, hay cuatro modos de
direccionamiento. El primero es inmediato, y se refiere a
un número y no a una dirección de memoria. El segundo es
directo, y es el modo usado por default. Este se refiere
a una posición de memoria. El tercero, el indirecto, toma
la posición de memoria como un puntero hacia otra
dirección. Y el cuarto, más complejo, es el de
autodecremento indirecto. Es similar al indirecto pero
antes de usar el puntero lo decrementa en uno. Vayamos a
algunos ejemplos:

Mov #0 $1

Pone un 0 en la posición de memoria que se encuentra a
una posición de distancia.

Mov #0 @1
Dat 5

Pone un 0 en la posición apuntada por el Dat, o sea,
cinco posiciones adelante del Mov.

Mov #0 <1
Dat 5

Esto decrementa el Dat en uno, con lo cual pasa a valer
cuatro, y pone un cero en la cuarta celda a partir del
Mov.

Para simplificar la programación podemos usar labels como
en assembler, por ejemplo

Bomba 0
Start Mov bomba 5

Esto mueve el contenido de la casilla llamada bomba cinco
posiciones adelante. Tambien tenemos un label especial
llamado START que indica dónde empieza la ejecución de
nuestro programa. Tambien, si utilizamos números
negativos el direccionamiento, como es lógico, apuntará a
ese número de casillas atrás de nuestra instrucción.

La lucha

Los programas tienen todo permitido para destruir a su
adversario. Pueden tener tácticas de defensa, de
ocultación, o de ataque frontal. La lucha termina cuando
de uno de los dos programas no queda ninguna copia en
funcionamiento. Para que un programa deje de funcionar
debe intentar ejecutar una instrucción ilegal, o sea, una
que no esté definida, un código de operación que no esté
de 1 a 10. Es obvio que una táctica posible es llenar la
memoria de ceros para que el otro programa se tropiece
con uno de ellos y muera. Pero hay que tener en cuenta
que si nuestro propio programa encuentra uno de esos
ceros tambien va a morir. Otra forma de terminar la
batalla es con empate, es posible que ninguno de los dos
programas destruya al otro en un tiempo razonable, por lo
tanto el MARS detiene su ejecución.

El torneo

Llamamos a todos los programadores que deseen luchar que
empiezen a preparar sus programas. Dentro de unos meses
lanzaremos la convocatoria para nuestro torneo, que
tendrá como premio un modem de 2400. Para que empiecen a
practicar, pondremos a disposición de todos en nuestro
BBS, en el 954-1792, las 24 horas, el programa que se usó
para el último torneo de CoreWar en Buenos Aires, escrito
por Fabio Friedlaender.
En la próxima nota, para los que prefieren otros
lenguajes, hablaremos del torneo de C-Robots y P-Robots,
en C y en Pascal respectivamente. Y tambien presentaremos
ejemplos de programas escritos en Redcode.