DarwinBotsManual
Abrir la app EnglishEN

Variables con def

Cómo ponerle nombre a una dirección de memoria o a un número con def, cómo se resuelven esos nombres y qué trampas tiene.

Escribir 50 inc para contar algo funciona, pero a la tercera dirección suelta ya no sabés qué era cada una. La línea def le pone nombre a un número: después, en cualquier parte del bot, escribís .nombre y el cargador lo cambia por ese número.

' Un contador en una variable propia
def pasos 50

cond
start
.pasos inc
stop

Este bot suma 1 a la celda 50 en cada ciclo: .pasos inc es exactamente lo mismo que 50 inc. Lo comprobamos corriéndolo: después de cinco ciclos la celda 50 vale 5.

Cómo se escribe

La forma es def nombre número, sola en su línea:

Los def se ponen arriba de todo, antes del primer gen, por una razón que sigue.

Cómo se resuelven los nombres

El cargador lee el archivo de arriba hacia abajo y traduce cada palabra en el momento en que la lee. Cuando encuentra .algo:

  1. Busca una sysvar llamada algo, sin distinguir mayúsculas: .UP, .Up y .up son la misma.
  2. Después busca entre tus def ya leídos, esta vez distinguiendo mayúsculas: .Pasos no es .pasos.
  3. Si hay coincidencia en los dos lados, gana tu def. Si hay dos def con el mismo nombre, gana el último.
  4. Si no encuentra nada, .algo vale 0. No hay error ni aviso al cargar.

Dos consecuencias prácticas:

Que un nombre «no exista» y valga 0 parece inofensivo, pero no lo es: en un store, la dirección 0 no hace nada, y en una lectura *0 lee la celda 1000. Un error de tipeo en un nombre deja al gen escribiendo en ningún lado (ver Números y direcciones).

Un def es solo un número

El cargador no sabe si tu def es una dirección o una constante: guarda un número y nada más. Eso te deja usar def para las dos cosas. Este bot usa reloj como dirección y giro como constante:

' Gira un cuarto de vuelta cada 20 ciclos
def reloj 60
def giro 314

cond
start
.reloj inc
stop

cond
*.reloj 20 >=
start
0 .reloj store
.giro .aimdx store
stop

.reloj inc incrementa la celda 60; *.reloj lee su valor; .giro apila directamente el número 314, que es lo que se guarda en .aimdx. Al correrlo, la celda 60 cuenta de 0 a 19, vuelve a 0, y en ese ciclo el .aim del bot baja 314 (un cuarto de vuelta hacia la derecha, porque la vuelta entera es 1256).

LoveBot F2, de Moonfisher, usa el mismo truco para dejarle una «llave» a sus hijos en la memoria genética:

' Fragmento de LoveBot F2 (Moonfisher, 2008)
def original 971
def origkey 1234

cond
*.robage 2 <
start
.origkey .original store
stop

original es una dirección (la 971, que se hereda: ver Memoria libre y epigenética) y origkey es una constante. El gen guarda 1234 en la 971 durante los dos primeros ciclos de vida.

Como es solo un número, el def puede valer cualquier cosa en ±32767. Si lo usás como dirección y cae fuera de 1..1000, se ajusta igual que cualquier dirección (ver Números y direcciones): def x 1050 y def x -50 terminan los dos en la celda 50. El valor tiene que ser un número escrito con cifras: def x .up no copia la dirección de .up, vale 0. El El editor de ADN lo marca.

Un def que pisa una sysvar

Si llamás a tu variable igual que una sysvar, tu def gana en todo el bot. Acá .up deja de ser la orden de avanzar:

def up 50

cond
start
10 .up store
stop

El bot no se mueve: el 10 va a la celda 50, no a la 1 (.up). Y como los def distinguen mayúsculas y las sysvars no, en ese mismo bot .UP sigue siendo la sysvar de verdad. Es una fuente de confusión segura; el lint de la app lo marca como aviso. Elegí nombres que no choquen con la lista de sysvars.

Nombres sin control

El cargador no revisa el nombre. Puntos, cifras o símbolos valen: def a.b 70 o def 5 70 definen variables legales, que se usan como .a.b y .5. Ojo con el último: .5 sin def no es la dirección 5, vale 0 (las direcciones van sin punto).

Más raro todavía: cualquier línea que empiece con las letras def se toma como un def. El cargador descarta los cuatro primeros caracteres y lee lo que queda. Una línea como esta:

defensa 50

define una variable llamada nsa con el valor 50. Si alguna vez un bot hace cosas inexplicables, revisá que ninguna línea empiece con «def» por accidente. El editor también te avisa cuando una línea se lee como def.

use: una palabra muerta

Algunos bots viejos del foro traen líneas como use NewMove. En esta versión use no hace nada especial: cada palabra se lee como ADN común y, al no ser comandos ni números, valen 0. Si la línea está antes del primer gen, esos ceros no se ejecutan nunca; si está dentro de un gen, apilan ceros. Podés borrarlas sin miedo.

Límites y errores que impiden cargar

CasoQué pasa
def x sin número, o def soloEl bot entero no carga.
Número fuera de −32768…32767 (def x 40000)El bot entero no carga.
Más de 1000 defEl bot entero no carga.
Dos def con el mismo nombreCarga; gana el último.
def con un número fuera de 1..1000Carga; usado como dirección, se ajusta a 1..1000.

Rarezas heredadas del 2.48.32

Dos comportamientos curiosos del original, uno conservado y otro corregido:

Por último, los nombres existen solo en tu archivo. Cuando la simulación guarda un bot como .txt (ver El formato .txt), el ADN sale ya traducido: cada .pasos aparece como 50, sin los def.