Un bot que dispara
Paso a paso hasta un cazador completo: girar hasta ver, apuntar con las ref*, disparar de cerca y reinvertir la energía en hijos.
En Un bot que se mueve escribiste un bot que avanza y vira, y en Un bot que busca comida le diste ojos para encontrar comida. Este tutorial le suma lo que le falta a un cazador: apuntar y disparar. Al final tenés un bot que ve, persigue, le roba energía a distancia y, con lo que gana, se reproduce.
Paso 1: el blanco y el cazador
Un cazador sin presa no se nota, así que empezamos por las dos especies. Andá a Bots y creá dos bots con + Nuevo bot: «Cazador» y «Blanco». Al Blanco dejale un gen vacío, para que se quede quieto:
' Blanco de practica: no hace nada
cond
start
stopAl Cazador le vamos escribiendo el ADN en los pasos que siguen. Después sembrá el Cazador en un escenario nuevo (en su ficha, Sembrar → Nuevo escenario con estos) y el Blanco en esa misma corrida (Sembrar en la corrida actual), con Cantidad de bots en 1 cada uno y colores bien distintos.
Para mirar de cerca, hacé clic en un bot: el inspector te deja seguir su energía ciclo a ciclo (El inspector).
Paso 2: girar hasta verlo
.eye5 es el ojo frontal: vale 0 si no hay nada adelante y crece cuanto más cerca está lo que ve. El gen más simple para buscar es girar mientras ese ojo no ve nada:
' Sin nada a la vista: giro buscando
cond
*.eye5 0 =
start
35 .aimdx store
stop.aimdx gira hacia la derecha la cantidad que le escribís. Con 35 por ciclo gira justo un ojo por vez: lo que hoy entra por .eye4 pasa al frontal al ciclo siguiente. Así barre el frente de costado a costado.
Qué deberías ver: el Cazador gira sobre su eje y en algún momento se frena, quieto, mirando al Blanco. En nuestra corrida giró ocho ciclos hasta que el otro le entró por el ojo frontal, a unas 650 unidades de borde a borde, y ahí se quedó apuntándolo. Si no ve nada en 360 grados, sigue dando vueltas para siempre.
Paso 3: apuntarle de frente
Girar de a pasos encuentra, pero no persigue: si el blanco se mueve, se te escapa del ojo frontal, que es angosto. Para apuntar de verdad hace falta saber dónde está, y eso lo dan las celdas ref*: lo que el ojo con foco ve queda descrito en ellas (Visión). La posición del otro está en .refxpos y .refypos; el operador angle convierte esas dos coordenadas en el rumbo hacia ese punto, y .setaim gira hasta ese rumbo. Todo junto en un gen, que además empuja hacia adelante para acercarse:
' Si veo algo: le apunto y me acerco
cond
*.eye5 0 >
start
*.refxpos *.refypos angle .setaim store
10 .up store
stopFijate que la condición es *.eye5 0 > y no «veo algo por cualquier ojo»: las ref* describen lo que ve el ojo con foco, y si ese ojo no ve nada valen 0 — apuntarías hacia la esquina (0, 0) del campo.
Qué deberías ver: el Cazador clava el rumbo en el blanco y avanza hacia él, corrigiendo cada ciclo. En nuestra corrida, contra un blanco que se desplazaba de costado, lo mantuvo en el ojo frontal durante todo el recorrido, sin perderlo nunca.
Paso 4: disparar de cerca
Llegó la parte del título. Escribir un número en .shoot dispara, y el número elige el tipo: el −1 es el que come: le saca energía al blanco, y de vuelta vuela hacia vos un regalo con lo robado, que te alimenta cuando llega (Disparos). El motor lanza el tiro en la fase de acciones del mismo ciclo, hacia donde apunta tu rumbo.
Ahora, ¿cuándo disparar? No en cuanto lo veas. Los disparos pierden fuerza con la distancia y mueren al final de su alcance, que con 1000 de cuerpo llega a unos 440 (Disparos). En nuestra corrida, con el blanco a unas 650 unidades de borde a borde (un eye5 de 5), el Cazador llovía disparos que se esfumaban en el camino sin tocar a nadie. Dispará solo de cerca:
' Lo tengo cerca y enfrente: disparo
cond
*.eye5 50 >
start
-1 .shoot store
stopUn eye5 de 50 es unos 200 de distancia de borde a borde: a esa distancia el tiro llega con casi toda su fuerza. Es el mismo umbral que usa Hunter 2.16, del Bestiario.
Qué deberías ver: en el inspector, la energía del Blanco baja ciclo a ciclo mientras el Cazador dispara, y la del Cazador sube. En nuestra corrida, apenas superó el umbral de cerca, el blanco empezó a perder más de 200 por ciclo y a los quince estaba muerto; el cazador había pasado de 3000 a más de 6000 de energía.
Dos ajustes más, para cuando los necesites:
- El costo. Cada disparo tiene precio (Disparar: 2 en la liga F1), pero en los escenarios de fábrica, salvo el Partido F1, los costos están en 0: acá disparar es gratis. En la F1, cada tiro sale de tu energía (Experimentar).
- La potencia.
.shootvalmultiplica la fuerza del −1: con 8 la duplica, y se cobra como un disparo más caro. Para empezar no hace falta.
Paso 5: gastar la ganancia en hijos
Un cazador que junta energía y no hace nada con ella no va a ninguna parte. La orden de dividirse es .repro: el número es el porcentaje de energía, cuerpo y cloroplastos que se lleva el hijo. Con la energía que deja una buena caza, un umbral de 5000 va bien:
' Con energia de sobra: un hijo
cond
*.nrg 5000 >
start
30 .repro store
stopEl 30 % deja al hijo con casi un tercio y al padre con la mayoría, para seguir cazando. Dos cosas que conviene saber (.repro, Reproducción):
- La orden persiste hasta que nace el hijo: si el parto falla —por ejemplo, porque no hay lugar donde tiene que aparecer el crío— se reintenta sola cada ciclo.
- El hijo hereda el ADN: a los pocos ciclos de nacido ya busca y dispara como el padre.
Por qué 5000 y no más: una sola presa de 3000 deja al cazador rondando los
- Con el umbral en 6000, en nuestra corrida no alcanzó el corte por 45 de
energía y no se reprodució nunca; con 5000, apenas mató a su primera presa nació el hijo: el padre quedó con unos 3950 de energía y 700 de cuerpo, el hijo arrancó con unos 2230 y 300.
El cazador completo
Acá está todo junto, los cuatro genes. Copialo en el editor y sembralo contra cualquier cosa que se mueva.
' Cazador: busca, apunta, dispara y se reproduce
' Gen 1: sin nada a la vista, giro buscando
cond
*.eye5 0 =
start
35 .aimdx store
stop
' Gen 2: si veo algo, le apunto y me acerco
cond
*.eye5 0 >
start
*.refxpos *.refypos angle .setaim store
10 .up store
stop
' Gen 3: lo tengo cerca y enfrente: disparo
cond
*.eye5 50 >
start
-1 .shoot store
stop
' Gen 4: con energia de sobra, un hijo
cond
*.nrg 5000 >
start
30 .repro store
stop
endQué deberías ver: el cazador barre con la vista, encañona a la primera presa, la persigue disparando y, cuando la energía le sobra, se divide. En nuestra corrida contra un solo blanco móvil lo cazó en unos cincuenta ciclos, tuvo dos hijos, y después la familia quedó girando en el lugar, robándose entre sí lo que quedaba — sin comida nueva, un cazador termina volviéndose contra los suyos. Sembrá más presas, o vegetales con la repoblación (Repoblar por debajo de (cloroplastos)), y mirá la manada crecer.
Qué probar después
- Comer cadáveres. El −1 no les saca nada a los muertos, pero el −6 les roba cuerpo y es el disparo más rendidor contra cualquier blanco (Disparos).
- Veneno y defensas. Con −3 paralizás al blanco y le escribís en la memoria; del otro lado, caparazón, baba, toxina y veneno son las formas de que no te hagan esto a vos (Defensas).
- No disparar a los tuyos. Comparar la firma del otro con la tuya (
.refeyecontra.myeye) es la mejora natural de este bot: Un bot que reconoce a su especie. - Cazar con costos. En el Partido F1 cada disparo cuesta y las presas también se defienden: la misma táctica necesita umbrales y presupuesto (Experimentar).