DarwinBotsManual
Abrir la app EnglishEN

Genes: cond, start, else y stop

Cómo se arma un gen con cond, start, else y stop, qué partes del ADN se ejecutan y cómo se numeran los genes.

El ADN de un bot es una lista larga de palabras que se recorre entera, de izquierda a derecha, una vez por ciclo. Lo que la ordena son cuatro marcadores de flujo: cond, start, else y stop. Con ellos se arman los genes: trozos de ADN que se ejecutan solo si se cumplen ciertas condiciones.

No hay anidamiento ni bloques: los cuatro marcadores son planos, y cada uno cambia el estado del intérprete al pasar por él. Esta página cuenta qué hace cada uno, con ejemplos que corrimos en el port.

Anatomía de un gen

La forma típica es esta:

' Avanza los primeros 10 ciclos de vida y despues retrocede
cond
 *.robage 10 <
start
 10 .up store
else
 10 .dn store
stop

Este bot empuja hacia adelante con .up mientras su edad (.robage) es menor que 10, y después empuja hacia atrás con .dn. Corriéndolo, el bot avanza unas 400 unidades, frena por la inercia hacia el ciclo 16 y vuelve sobre sus pasos.

La zona de condiciones

Entre cond y start se ejecuta todo menos los stores: números, lecturas de memoria, operadores y comparaciones. Así que podés calcular antes de comparar:

' En la zona de condiciones se puede calcular, pero no escribir
cond
 2 3 add 5 =
 7 87 store
start
 1 88 store
stop

Acá la condición es 2 3 add 5 = (verdadera) y el cuerpo escribe 1 en la dirección 88. El 7 87 store de la zona de condiciones no escribe nada: un store solo actúa dentro de un cuerpo.

Las comparaciones, como < o =, dejan su resultado en la pila booleana (ver La pila entera y la booleana). Lo que pasa con esa pila en cada marcador es la clave de todo:

No hace falta escribir and entre condiciones: tres comparaciones seguidas ya se combinan con Y. Para un O, usá or explícito.

Un start sin cond

Un start que no viene detrás de un cond abre un gen sin condiciones: se ejecuta todos los ciclos. Es lo mismo que cond start, y muchos bots empiezan así. Bardus, de Moonfisher, es un bot entero de un solo gen cond start … stop que resuelve todo con aritmética, sin una sola comparación.

El else

En esta versión, el else funciona como uno espera:

' Gen con else: escribe 1 o 2 en la direccion 60 segun *50
cond
 *50 0 >
start
 1 60 store
else
 2 60 store
stop

Con la dirección 50 en 0, el bot escribe 2 en la 60; con la 50 en 5, escribe

  1. El else usa el resultado de las condiciones que abrieron el start

anterior.

También vale el else pegado a las condiciones, sin start. Su cuerpo corre solo si las condiciones dan falso, y no hay cuerpo para el caso cierto:

' else sin start: corre cuando la condicion es falsa
cond
 *50 0 >
else
 9 83 store
stop

Con la 50 en 0 escribe 9 en la 83; con la 50 en 3 no hace nada.

Un else que no tiene un cond … start justo antes no se ejecuta nunca: después de un start sin cond, después de un stop o después de otro else. En este bot solo se escribe la dirección 84:

' else despues de un start sin cond, o despues de stop: nunca corre
start
 1 84 store
else
 2 85 store
stop
else
 3 86 store
stop

Código fuera de los genes

Lo que queda antes del primer marcador, o entre un stop y el marcador siguiente, no se ejecuta. Ni siquiera los números se apilan:

' Lo que queda fuera de un gen no se ejecuta
5 70 store
start
 1 71 store
stop
7 72 store
cond
 3 73 store
start
 4 74 store
stop

De las cinco escrituras solo ocurren la de la 71 y la de la 74. La de la 73 no, porque está en la zona de condiciones.

Los marcadores, en cambio, se procesan siempre, aunque el gen se esté saltando, y cobran su costo cada vez (ver Ejecución y costos). Por eso un cond en cualquier lugar abre un gen nuevo: cierra el cuerpo anterior aunque le falte el stop.

' Un cond cierra el gen anterior aunque falte el stop
cond
 1 2 >
start
 1 90 store
cond
start
 2 91 store
stop

El primer gen no corre (1 no es mayor que 2) y el segundo sí: la 91 vale 2.

El ADN termina en el primer end; lo que siga no existe para el bot.

Varios start seguidos

Un segundo start no es un «y además»: abre otro gen, sin condiciones.

' El segundo start abre un gen nuevo sin condiciones
cond
 *50 0 >
start
 1 75 store
start
 2 76 store
stop

Con la 50 en 0, la condición es falsa y la 75 queda en 0, pero la 76 recibe 2 igual. Si querés dos cuerpos con la misma condición, repetí el cond.

La pila booleana pasa de un gen al siguiente

Solo cond limpia la pila booleana: ni stop ni un start sin condiciones lo hacen. Por eso una condición escrita dentro de un cuerpo (ver Condiciones en línea) puede seguir frenando los stores del gen siguiente si ese gen no empieza con cond. El ejemplo está en La pila entera y la booleana.

Si un gen tiene que correr pase lo que pase, empezalo con cond start, o limpiá la pila al final del gen anterior con clearbool o dropbool.

La numeración de los genes

Los genes se numeran desde 1, en orden. Cuenta como gen nuevo:

Ojo con la segunda regla: en cond … start … else … stop, el else cuenta como un gen aparte. Este bot anota en cada cuerpo el número de su gen:

' Cada gen anota su numero con .thisgene
cond
start
 *.thisgene 61 store
stop
start
 *.thisgene 62 store
stop
cond
 1 2 >
start
 *.thisgene 63 store
else
 *.thisgene 64 store
stop

Resultado: la 61 vale 1, la 62 vale 2 y la 64 vale 4 (el start de la 63 es el gen 3, que no corrió). .genes vale 4.

SysvarQué tiene
.genesCuántos genes tiene el ADN. Se actualiza solo.
.thisgeneEl número del gen en curso. Cambia en cada marcador, aunque el gen se salte, así que al final del ciclo queda el del último gen.
.dnalenEl largo del ADN en palabras.

Esa misma numeración usan .delgene, que borra un gen del propio ADN, y .mkvirus, que arma un virus con un gen (ver Virus). Cuando el motor exporta un bot como texto agrega comentarios del estilo Gene: 5 Begins at position 97, con la misma cuenta (ver El formato .txt); muchos bots del Bestiario los traen.

Resumen

SituaciónQué pasa
cond C start A stopA corre si todas las condiciones de C son verdaderas.
cond start A stop o start A stopA corre siempre.
cond C start A else B stopA si C es cierta; B si es falsa. Son dos genes.
cond C else B stopB corre si C es falsa.
else tras stop, tras otro else o tras un start sin condNunca corre.
start A start BB es otro gen, sin condiciones.
Stores entre cond y startNo escriben.
Código fuera de un genNo se ejecuta.