Un multibot
Paso a paso: un organismo de varias células que nacen atadas, comparten la energía, sostienen la forma y caminan como una sola cosa.
En Un alimentador por lazo usaste un lazo para chuparle la energía a otro bot, y en Un bot que reconoce a su especie aprendiste a distinguir a los tuyos. Ahora vamos más lejos: en vez de usar los lazos, vamos a vivir en ellos.
Qué es un multibot
Un multibot (o multicelular) es un organismo: varios bots unidos por lazos que comparten energía y se sostienen en forma. Un bot pasa a ser multicelular (.multi vale 1) cuando un lazo hecho con .tie cumple sus 19 ciclos y se endurece, y le pasa a los dos extremos a la vez. Todo el mecanismo de los lazos —resorte, endurecimiento, puertos, reparto— está en Lazos y multicelulares; acá lo usamos para armar uno de cero.
La receta de siempre es simple: cada hijo se ata al padre apenas nace, y el organismo crece parto a parto. Para que funcione como organismo y no como un puñado de bots enganchados, falta resolver tres cosas: quién manda, cómo se reparte la despensa y cómo se camina sin desarmarse.
Paso 1 · Nacer atado
Todo parto ata al padre con el hijo con un lazo de nacimiento. Es un lazo provisorio: nunca se endurece y se corta solo a los 100 ciclos. Tiene además una rareza: el padre lo llama 0, y un 0 no sirve para nada, así que por ese lazo el padre no puede escribirle ni pasarle recursos al hijo; el hijo, en cambio, lo llama 1 y sí puede.
Por eso la receta: apenas nace, el hijo se ata de nuevo con .tie, y el lazo nuevo pisa al de nacimiento. A los 19 ciclos ese lazo se endurece y los dos quedan multicelulares.
¿Y cómo sabe un bot que nació de un parto, para atarse? Por el lazo de nacimiento: ya está puesto en su primer ciclo de vida, así que .numties vale
- Un fundador, un bot sembrado suelto, empieza con 0. Esa diferencia basta para
marcar quién es quién, y la guardamos en una celda libre de memoria (Memoria libre y epigenética):
def cuerpo 60
' naci de un parto: soy cuerpo
cond
*.robage 0 =
*.numties 1 =
start
1 .cuerpo store
stop
' apenas nacido, me ato al padre con el puerto 7
cond
*.robage 0 =
*.cuerpo 1 =
start
7 .tie store
stopEl .tie no necesita ver al padre: si no ves a nadie, en tus primeros ciclos el motor prueba con tu padre. El 7 es el puerto: el nombre con el que el hijo va a llamar a ese lazo; el padre lo llamará 1, porque para el otro extremo el lazo se nombra por orden de llegada. Y el fundador no lo pide: no tiene a quién atarse, y un intento fallido cobra el costo del lazo (Atar) igual.
Qué deberías ver: sembrado solo, todavía nada: el fundador no pide el lazo. La parte observable llega con el primer parto (el gen de reproducirse entra en el paso siguiente): el hijo nace con .numties 1, a su primer ciclo ya llama 7 a su lazo, y .multi recién pasa a 1 en los dos a los 19 ciclos del atado.
Paso 2 · Crecer: parir sin soltarse
Un organismo que nunca se reproduce no pasa de la primera generación. Cualquier célula con energía y cuerpo de sobra puede parir: el hijo hereda el ADN, se levanta delante y ya sabemos que se ata solo.
' con energia y cuerpo de sobra, me reproduzco
cond
*.nrg 3000 >
*.body 500 >
start
30 .repro store
stopDos detalles del parto que acá juegan a favor. Primero, la orden .repro no se gasta al fallar: si el lugar de nacimiento está ocupado, se reintenta ciclo tras ciclo. Segundo, ese lugar queda delante del bot, hacia donde apunta, a la suma de los dos radios, y el hijo nace mirando para atrás, espalda con espalda con el padre. Mientras las células queden cerca, el hijo recién nacido ocupa el lugar del siguiente parto y la producción se frena ahí: un organismo quieto no cría más de una célula hija. En el paso 4, cuando los lazos estiren las células, el lugar queda libre y la fábrica arranca de nuevo.
Qué deberías ver: con una sola célula sembrada y energía de sobra, al rato hay dos; el hijo nace con el 30 % de la energía y del cuerpo del padre (menos una milésima del traspaso que paga cada lado). Y como el hijo también tiene el gen del paso 1, se ata y el organismo ya tiene dos células.
Paso 3 · Una sola despensa
En un organismo la energía es de todos. Con .sharenrg escribís qué porcentaje del total querés quedarte con cada compañero de lazo; con 50 quedan parejos. Tres condiciones, siempre las mismas:
- Solo lo puede pedir el que creó el lazo; como acá el hijo es quien se ata, cada célula pide su reparto hacia su propio padre.
- El motor borra la orden en cada ciclo, así que hay que pedirla siempre.
- En un ciclo no se mueve más energía que el propio cuerpo (
.body), y quien pide paga el 1 % de lo movido.
' mientras sea multicelular, reparto energia parejo
cond
*.multi 1 =
start
50 .sharenrg store
stopQué deberías ver: con el padre a 3498 y el hijo a 1498 (sembrado con 5000 de energía), en cuanto .multi vale 1 las dos cifras convergen y quedan clavadas en ~2493 cada una: parejas, menos el 1 % del viaje. En cadenas más largas el reparto va de a pares, pero como todas las células lo piden, la despensa se iguala sola.
Paso 4 · Sostener la forma
Un lazo es un resorte: recuerda un largo de reposo y tira o empuja para volver a él. Endurecido, además, acepta órdenes de geometría: .fixlen fija el largo de reposo y .fixang el ángulo al que tiene que quedar el compañero respecto de hacia dónde apuntás. Con el ángulo fijo el lazo funciona como un brazo: si el compañero se sale de su lugar, el motor empuja a los dos de costado y los endereza.
Pedimos 300 de largo, de borde a borde, y 314 de ángulo: un cuarto de vuelta, así cada hijo queda a un costado del padre y la cadena no se apila.
' con el lazo endurecido, doy forma
cond
*.multi 1 =
start
300 .fixlen store
314 .fixang store
stopQué deberías ver: el parto deja a las células casi pegadas; cuando el lazo endurece, el pedido de 300 las estira: el tirón inicial pasa de 400 y a las decenas de ciclos la distancia se asienta cerca de 330. Y un efecto feliz: al estirarse los bots, el lugar de parto queda libre y las células vuelven a parir: a los ~25 ciclos ya hay tres.
Paso 5 · Marchar: la cabeza decide
Lo último es moverse, y acá conviene saber qué hace el motor y qué no. Cada bot empuja en su dirección con .up; el motor no reparte tu empuje entre los atados. Lo que sí viaja por el lazo es la fuerza del resorte: si te alejás, arrastra al compañero. Y con el ángulo fijado, el torque que corrige la forma empuja a los dos.
Entonces la marcha más simple es la de los gusanos de verdad: solo la cabeza decide. El fundador es la única célula que no marcó cuerpo, así que empuja siempre; el resto se deja llevar por el resorte.
def cuerpo 60
' la cabeza empuja, el cuerpo sigue
cond
*.cuerpo 0 =
start
10 .up store
stopY el bot entero queda así:
def cuerpo 60
' naci de un parto: soy cuerpo
cond
*.robage 0 =
*.numties 1 =
start
1 .cuerpo store
stop
' apenas nacido, me ato al padre con el puerto 7
cond
*.robage 0 =
*.cuerpo 1 =
start
7 .tie store
stop
' con energia y cuerpo de sobra, me reproduzco
cond
*.nrg 3000 >
*.body 500 >
start
30 .repro store
stop
' mientras sea multicelular, reparto energia parejo
cond
*.multi 1 =
start
50 .sharenrg store
stop
' con el lazo endurecido, doy forma
cond
*.multi 1 =
start
300 .fixlen store
314 .fixang store
stop
' la cabeza empuja, el cuerpo sigue
cond
*.cuerpo 0 =
start
10 .up store
stopPara comprobarlo, sembrá varios fundadores y mirá cómo les va. Lo que medimos con tres, a los 100 ciclos:
| Qué miramos | Resultado |
|---|---|
| Células por organismo | De cada fundador con lugar para parir, 3 (a uno que quedó pegado a la esquina del campo no le nació nadie: su lugar de parto caía afuera) |
| Lazos | La cabeza con 2, el resto con 1, y ninguno roto |
| Posiciones relativas | El largo oscila alrededor de los 300 pedidos (en la marcha va de ~200 a ~430) y el ángulo se sostiene cerca del cuarto de vuelta: la cadena camina sin plegarse |
| Avance | El organismo que caminó libre recorrió ~2500 unidades en sus primeros 90 ciclos; en crucero son unas 33 por ciclo (un bot suelto con el mismo empuje navega a ~40): arrastrar células cuesta, pero no mucho |
| Energía | Pareja: ~1650 por célula, de los 5000 iniciales |
En el Bestiario
Hay multibots de verdad en el Bestiario, con años de torneos encima. El Caterpillar de Peter camina como una oruga: clava la cabeza, acorta el lazo a 1 con .fixlen para arrastrar el cuerpo, vuelve a estirarlo a 1000 y repite; reparte por mitades la energía, el caparazón y la baba (y les pasa los desechos enteros), y cuando junta demasiada energía se corta con .deltie para que cada tramo funde un organismo nuevo.
El Tribolis de Bacillus es un gusano con jerarquía: cada célula se declara cabeza, tramo o cola en una celda libre. Todas nacen declarándose cabeza; la que queda sin lazos (el fundador, o una que los perdió) se declara cola y reproduce para fundar el gusano; y la cabeza que junta energía de sobra se degrada a tramo y pare una cabeza nueva, así el cuerpo se alarga. En la marcha, la cabeza manda: empuja y fija su lazo a 628, con el cuerpo colgando atrás; los tramos empujan más despacio para no quedarse, y la cola aturde a las presas con veneno.
Y el W6 de Peterb, un multibot táctico con un genoma enorme: publica por los lazos dónde vio al enemigo y arma cadenas más o menos grandes según cuánta población haya en el campo.
Qué probar después
- Repartir trabajos. En vez de que todas las células hagan todo, marcala como el Tribolis y andá más lejos: unas cazan (Un bot que dispara) y otras fotosintetizan (Cloroplastos y vegetales), con la energía viajando por el reparto. Para elegir quién hace qué, la vía de siempre son los canales del lazo (
.tout1lo publica,.tin1lo escucha) o una celda escrita por el vecino con.tienum,.tielocy.tieval. - Cambiar la marcha. Probá que todas las células empujen: vas a ver que el organismo recorre menos terreno, porque cada una empuja hacia su propio frente y se hace un nudo (en la prueba, menos de un tercio de lo que avanza la marcha de la cabeza). La marcha de oruga del Caterpillar (fijar una célula con
.fixposy acortar el lazo) avanza mejor en espacios chicos. - Ponerlo a prueba. Desafiá el organismo con un depredador y mirá qué pasa si cae la cabeza: el cadáver sigue atado un buen rato (Muerte y cadáveres), nadie empuja y el organismo queda frenado. Después de ese golpe, ¿qué gen tendría que cambiar para que una célula del cuerpo tome el mando?
Para las estrategias de multibots en competencia, seguí Multibots.