DarwinBotsManual
Abrir la app EnglishEN

La estructura de un bot

Un bot es un archivo de texto con su ADN: genes uno tras otro, comentarios, def y palabras separadas por espacios.

Un bot de DarwinBots es un archivo de texto. Adentro está su ADN: un programa escrito con palabras separadas por espacios que el motor lee una vez, al cargar el bot, y convierte en una lista de tokens. Desde ahí el texto ya no importa: en cada ciclo el bot ejecuta esa lista de principio a fin (el detalle está en Ejecución y costos y en El ciclo y el orden de las acciones).

Esta página te muestra la forma general de un bot. Cómo es el archivo por dentro (fines de línea, cabeceras, lo que se pierde al exportar) está en El formato .txt.

Un bot mínimo

Este es un bot completo. Podés pegarlo en el El editor de ADN y sembrarlo:

' Mi primer bot: avanza siempre
cond
start
10 .up store
stop

Avanza todos los ciclos, cada vez más rápido. Línea por línea:

Un start sin cond delante también funciona y se ejecuta siempre: start 10 .up store stop hace lo mismo que el bot de arriba.

Genes, uno tras otro

Un bot real tiene varios genes, escritos uno después del otro. No se anidan: cond, start, else y stop son marcas planas que van prendiendo y apagando la ejecución mientras el bot recorre su lista. La forma habitual es esta:

cond
  *.nrg 5000 >
start
  50 .repro store
stop

cond
  *.nrg 1000 <
start
  10 .up store
stop

El primer gen se reproduce cuando la energía pasa de 5000; el segundo empuja hacia adelante cuando baja de 1000. Las reglas exactas de cada marca, incluida una rareza heredada de else, están en Genes: cond, start, else y stop.

Dos cosas que conviene saber desde ya:

Comentarios

Hay dos maneras de comentar:

/******************/
/* REPRODUCTION */
/******************/

cond
*.nrg
5000
>
start
50
.repro
store
stop

En el medio de una línea, la barra no comenta nada: stop // fin deja dos palabras más (// y fin) que el cargador convierte en ceros. El fragmento de arriba también muestra que los saltos de línea no tienen significado: escribir una palabra por línea o todo el gen en una sola línea da el mismo bot.

def, al principio

Una línea que empieza con def le pone nombre a una dirección de memoria:

' Contador: empuja durante 5 ciclos y después sigue de largo
def pasos 50

cond
  *.pasos 5 <
start
  10 .up store
  .pasos inc   ' suma 1 a la dirección 50
stop

Desde el def, escribir .pasos es lo mismo que escribir 50, y *.pasos lee lo que hay en esa dirección. El bot empuja cinco ciclos, la dirección 50 llega a 5 y el gen deja de ejecutarse; el bot sigue moviéndose por la inercia.

Los def van arriba, antes del primer lugar donde usás el nombre: el cargador resuelve cada nombre en el momento en que lo lee, y uno definido más abajo vale 0. El valor tiene que ser un número; def mov .up no copia la dirección de .up, deja mov en 0. Todo esto, con más detalle, en Variables con def.

Las palabras del ADN

Fuera de los comentarios y los def, el cargador parte cada línea por los espacios (y por los tabuladores) y convierte cada palabra en un token. Hay pocas clases:

Lo que escribísQué esEjemplo
Un númeroSe apila tal cual10, -5
* y un númeroLee esa dirección de memoria y apila lo que tiene*50
. y un nombreLa dirección de una sysvar (o de un def): es un número.up vale 1
*. y un nombreLee esa sysvar*.nrg
Un operadorHace una cuenta, compara o escribeadd, >, store
Una marca de flujoOrganiza los genescond, start, else, stop, end

Los números van de −32768 a 32767; uno con decimales se redondea al entero más cercano (en el empate, al par: 2.5 vale 2). Más sobre direcciones y rangos en Números y direcciones, y los operadores agrupados por familia en Los operadores por familia.

Fijate que .up sin asterisco no lee nada: es solo el número de la dirección, listo para que un store la use. Para leer el contenido hace falta el *. Un * suelto también lee: .nrg * es lo mismo que *.nrg (ver *).

Mayúsculas y minúsculas

Los operadores, las marcas de flujo y los nombres de sysvars se reconocen sin importar mayúsculas: COND *.NRG 1000 > START 10 .Up STORE STOP es un bot válido. Los nombres que inventás con def, en cambio, distinguen: si definiste pasos, .Pasos no es lo mismo.

Qué rechaza el cargador

Casi nada. El cargador no rechaza palabras: toda palabra que no reconoce se convierte en el número 0, y un .nombre que no existe también vale 0. Un error de tipeo carga sin quejas y hace otra cosa:

' Error a propósito: .upp no existe
cond
start
10 .upp store
stop

Acá .upp vale 0 y el store no escribe en ningún lado: el bot no se mueve. Por eso el El editor de ADN revisa el ADN y te avisa de las palabras que no reconoce, con una sugerencia (en este caso, .up). La lista de tropiezos habituales está en Errores frecuentes.

El bot entero se rechaza, y no entra en la simulación, solo en dos casos:

Genes sin stop, un stop de más o condiciones sueltas cargan igual y se ejecutan con las reglas de siempre.

Una rareza heredada: el primer token y los def

DarwinBots 2.48.32 tiene una rareza que el port conserva: si el bot tiene algún def y su primer token no es una marca de flujo (cond, start, else o stop), ese primer token se pierde al cargar. Por ejemplo:

def pasos 50
5 cond start 10 .up store stop

Ese 5 desaparece. Como lo que va antes del primer cond no se ejecuta nunca, el bot se comporta igual; lo que cambia es la cuenta de su ADN: .dnalen dice 7 en lugar de 8 (cuenta también el end final), y las Mutaciones trabajan sobre la lista ya recortada. El editor te avisa cuando pasa. La solución es simple: empezá el código con cond o con start, como hacen casi todos los bots.