En este desafío, debes diseñar una especie de organismos unicelulares para luchar hasta la muerte en el campo de las placas de Petri. La arena se representa como una cuadrícula rectangular, donde cada celda ocupa un espacio:
.....x....
...x...o..
...x.c..o.
.......o..
Atributos
Cada celda tiene tres atributos. Al especificar su especie celular al comienzo del juego, asigna 12 puntos entre estos atributos.
- Puntos de vida (HP): si el HP de una celda cae a cero, muere. Las nuevas celdas tienen HP total.
- Cuando una célula muere, deja un cadáver que otras células pueden comer para obtener energía.
- Una celda no puede recuperar HP perdido, pero puede crear una nueva celda con HP completo al dividirse.
- Energía : la mayoría de las acciones que puede realizar una célula requieren energía. Al descansar activamente, una célula puede recuperar la energía perdida hasta el máximo de su especie.
- Es probable que falle una especie celular con menos de 5 energías, porque no puede dividirse para crear nuevas células.
- Una célula no puede recuperar energía más allá del valor máximo de su especie.
- Una celda recién creada tiene un valor de energía inicial copiado de su padre (y un valor máximo dictado por su especificación de especie).
- Acidez : si una célula elige explotar, el nivel de acidez de la célula se usa para calcular el daño a las células adyacentes.
Comportamiento
Cada turno, cada celda puede tomar una acción:
Mover: la celda se mueve un espacio en cualquier dirección (N / S / E / W / NE / NW / SE / SW) a un costo de 1 energía.
- Una célula no puede moverse a un espacio ocupado por otra célula viva.
- Una celda no puede moverse fuera de la cuadrícula.
- Pasar a un cadáver celular destruye el cadáver.
Ataque: una célula ataca a una célula adyacente e inflige 1 a 3 daños, gastando 1 a 3 puntos de energía.
- Una célula puede atacar en cualquier dirección (N / S / E / W / NE / NW / SE / SW).
- Es legal atacar células amigas.
Divide: la celda se divide y crea una nueva celda en un espacio adyacente, a un costo de 5 de energía.
- Una celda puede dividirse en cualquier dirección (N / S / E / W / NE / NW / SE / SW).
- La nueva celda tiene HP completa de acuerdo con las especificaciones de su celda original.
- La nueva celda tiene tanta energía como su celda principal después de restar el costo de división. (Por ejemplo, una celda principal con 8 puntos de energía iniciales se reducirá a 3 de energía y producirá una celda secundaria con 3 de energía).
- Una nueva celda no puede actuar hasta tu próximo turno.
- Una célula no puede dividirse en un espacio ocupado por una célula viva, pero puede dividirse en un espacio ocupado por un cadáver de células muertas (esto destruye el cadáver).
Comer: una célula come un cuerpo celular adyacente, ganando 4 de energía.
- Una célula puede comer en cualquier dirección (N / S / E / W / NE / NW / SE / SW).
Descanso: una célula no hace nada durante un turno, recuperando 2 de energía.
Explotar: cuando una celda tiene 3 HP o menos y más energía que HP, puede optar por explotar, causando daño a las ocho celdas adyacentes.
- El daño a cada celda adyacente es
(exploding cell HP) + (explodng cell acidity)
- Una célula explotada muere y deja un cadáver, al igual que las células muertas en la explosión.
- El daño a cada celda adyacente es
Protocolo
Preparar
Su programa se ejecutará con la cadena BEGIN
provista en stdin. Su programa debe escribir en la salida estándar una lista separada por espacios de 3 enteros no negativos, lo que representa HP, la energía, y la acidez de su especie de la célula: por ejemplo, 5 6 1
. Los números deben sumar 12. La acidez puede ser 0
, si lo desea. (Otros atributos también pueden ser cero, ¡pero hacerlo funcionalmente pierde el juego!)
Comienza con una celda, en la esquina noroeste o sureste, a un espacio de cada borde. La celda inicial tiene HP y energía completos.
Cada célula actúa
Cada turno, su programa se invocará una vez por cada célula viva de su equipo (excepto las células que acaban de crear este turno) para que la célula pueda actuar. Su programa cuenta con datos sobre stdin que incluyen el estado de la placa de Petri e información sobre esta celda en particular:
10 4
..........
..xx.c....
...c...o..
......o...
6 3 5 7
Los dos primeros números indican el ancho y la altura de la arena: aquí, hay una arena de 10 por 4.
- Las
o
celdas son tuyas; Lasx
células son tus enemigos. (Esto siempre es cierto; cada jugador siempre ve sus propias células comoo
). - Los
.
espacios están vacíos. - Los
c
espacios representan cadáveres celulares comestibles.
Los números después de la línea vacía representan información sobre esta celda:
- Los primeros dos números son
x,y
coordenadas, indexadas0,0
en la parte superior izquierda (por lo que6 3
aquí se refiere al extremo suro
celda ). - El tercer número es el HP de la celda; El cuarto número es la energía de la célula.
Su programa debería generar (para stdout) una acción. En los ejemplos a continuación, usaremos N
como una dirección de ejemplo, pero puede ser cualquier dirección legal para esa acción ( N
/ S
/ E
/ W
/ NE
/ NW
/ SE
/ SW
). Toda la salida del programa no distingue entre mayúsculas y minúsculas, pero los ejemplos usarán mayúsculas. Cualquier acción de salida que no sea válida (ya sea porque tiene una sintaxis no válida o intenta una acción ilegal) se ignora y da como resultado la celda REST
(y, por lo tanto, gana 2 energías).
MOVE N
DIVIDE N
EAT N
ATTACK N 2
- el número representa la fuerza del ataque (1 - 3)REST
EXPLODE
El turno de su equipo consiste en que todas sus células tengan la oportunidad de actuar, una por una. Todas sus células actúan antes que cualquiera de las células del oponente. Una vez que todas sus células actúan, su turno termina y comienza el turno de su oponente. Una vez que actúan todas las células de tu oponente, tu turno comienza de nuevo. Dentro de su turno, cada célula tiene prioridad para actuar en función de su edad: las células más antiguas de su equipo actúan primero antes que las células más jóvenes.
Ejemplo
Así es como podría comportarse un programa. La entrada de stdin se denota aquí con >
flechas iniciales (separadas de la entrada real por un espacio de aclaración) y la salida en stdout tiene <
flechas.
> BEGIN
< 5 6 1
Luego, el programa se invoca nuevamente:
> 10 4
> ..........
> .o........
> ........x.
> ..........
>
> 1 1 5 6
< DIVIDE SE
Después del turno de su oponente (que decidió hacerlo DIVIDE W
con la celda inicial simple), su programa se invoca dos veces, una para cada celda:
> 10 4
> ..........
> .o........
> ..o....xx.
> ..........
>
> 1 1 5 1
< MOVE E
Para la segunda invocación en su turno:
> 10 4
> ..........
> ..o.......
> ..o....xx.
> ..........
>
> 2 2 5 1
< MOVE SE
Tenga en cuenta que esta segunda celda ve el estado actualizado del tablero en función del movimiento de la otra celda anteriormente en su turno. También tenga en cuenta que esta celda se ha creado con 1 energía, porque la celda principal tenía 6 energías cuando realizó la división el último turno (por lo que el 6 original, menos el costo de división de 5 energías, creó una celda secundaria con 1 energía).
Ahora su turno ha terminado y comienza el turno de su oponente. Las dos celdas opuestas tendrán la oportunidad de actuar, y luego comenzará su próximo turno.
Victoria
Puedes ganar por:
- Destruyendo todas las celdas opuestas, o
- Tener más células que tu oponente después de que cada jugador haya completado 150 turnos
La puntuación se basará en el número de victorias en 100 juegos entre sí. En la mitad de las simulaciones, su programa podrá ir primero.
Los juegos de empate (es decir, exactamente el mismo número de celdas después de 150 turnos, o las únicas celdas restantes se matan juntas en una explosión) no se cuentan en el total de victorias de ninguno de los jugadores.
Otra información
- Su programa no debe intentar mantener el estado (más allá del uso del estado de la placa de Petri): los organismos monocelulares no tienen muy buena memoria y reaccionan ante el mundo momento a momento. En particular, la escritura en un archivo (u otro almacén de datos), la comunicación con un servidor remoto o la configuración de variables de entorno están explícitamente prohibidas.
- Los envíos se ejecutarán / compilarán en Ubuntu 12.04.4.
- Los detalles de los 100 juegos de puntuación aún no están confirmados, pero probablemente involucrarán múltiples tamaños de arena (por ejemplo, 50 carreras en una arena pequeña y 50 carreras en una arena más grande). Para una arena más grande, puedo aumentar el conteo máximo de turnos para asegurarme de que pueda tener lugar una batalla adecuada.
Recursos
Aquí está el código del conductor que ejecuta la simulación, escrita para Node.js, llamada por node petri.js 'first program' 'second program'
. Por ejemplo, podría parecer una celda escrita en Python contra una celda escrita en Java node petri.js 'python some_cell.py' 'java SomeCellClass'
.
Además, entiendo que leer y analizar varias líneas en stdin puede ser un gran dolor, por lo que he redactado algunas celdas de muestra completas en diferentes idiomas que puede construir, revisar o ignorar por completo.
- Celda Java
- Célula Python
- Celda de JavaScript (para usar con Node.js)
Por supuesto, eres libre de escribir una celda en un idioma diferente; Estos son simplemente tres idiomas para los que decidí escribir código repetitivo para ayudar a ahorrar tiempo.
Si tiene algún problema al ejecutar el controlador, no dude en enviarme un ping en la sala de chat que he creado para este desafío . Si no tiene suficiente reputación para chatear, simplemente deje un comentario.
fuente
'node c:/cell/cell_template.js'
para cada argumento, tal como necesitaría especificar'java CellTemplate'
el código Java. Lo aclararé en el texto del desafío. Si todavía tiene problemas, nosotros (y cualquier otra persona con problemas técnicos) podemos continuar esta discusión en una sala de chat que acabo de hacer .Respuestas:
Aquí está mi bot relativamente simple, que programé en Ruby. Básicamente, prioriza dividir primero e intenta dividir hacia los enemigos para ganar control sobre el campo. Su segunda prioridad es comer, y la tercera es atacar. Venció fácilmente la celda de Python de muestra.
fuente
$
.$
se usa para indicar una variable global. Sí, son malvados, pero en este pequeño programa, no importa demasiado.Ameba
Primero se divide en cuatro y luego trata de llegar al término medio para limitar el espacio de replicación de los oponentes. Luego comienza a replicarse. Al moverse o replicarse, encuentra el camino óptimo hacia el enemigo más cercano, y se mueve o se divide hacia él, para tratar de cortar el espacio disponible del enemigo.
Si un enemigo está adyacente o a un espacio de distancia, siempre atacará o se moverá hacia él, permitiendo que la fila detrás de no hacer nada llene los espacios vacíos.
No he probado esto contra ninguna otra presentación, así que no tengo idea de qué tan bien funcionará.
fuente
Celda simple hecha en
node.js
. Probado contra la célula de nodo de ejemplos y contra Kostronor los supera.Actualizar
Todavía bastante simple, trata de moverte hacia el enemigo o dividirte.
fuente
Evolución
¡Esta presentación ha evolucionado y ya no es un simple organismo de células chamuscadas! Intenta atacar / explotar siempre que sea posible, de lo contrario se divide o se mueve hacia el enemigo. Moverse debería resolver el problema de una célula rodeada de células amigas con energía máxima, incapaz de hacer algo útil.
Después de moverse, siempre quedan 3 energías para golpear al enemigo lo más fuerte posible.
fuente
frenético
Debido a que usé Clojure, que tiene algunas limitaciones, principalmente el gran tiempo de inicio, tomé un poco de vida. Cuando el programa se entrega
BEGIN
, genera4 6 2 LOOP
, lo que indica que no se detiene. Luego toma las entradas como una secuencia continua y termina conEND
. No guarda ningún estado, lo que queda claro al no usar ninguna variable global o reutilizar los valores de retorno. Debido a que la implementación de esta acción en bucle aún no se ha realizado, no pude probar completamente el código (espero que el código sea lo suficientemente claro).La célula ganó su nombre por su naturaleza de explotar siempre que sea posible (y por lo tanto tener acidez) y priorizando el ataque justo después de dividirse.
Subí el archivo jar generado a mi Dropbox . Corre con
java -jar petridish-clojure.jar
Solo para aclarar:
Actualizar registro
fuente
Hambriento, bot hambriento
Aquí hay una entrada en R. Espero haber entendido correctamente cuáles fueron las especificaciones técnicas sobre cómo comunicarse con su programa. Debería activarse con
Rscript Hungryhungrybot.R
.Si tiene al menos 6 de energía, se divide, preferentemente en la dirección del enemigo. De lo contrario, come lo que esté al lado o lo que sea accesible. Si no se puede alcanzar comida, explotará cuando haya más enemigos que células hermanas o peleará con enemigos cercanos. Descansa solo si la energía es 0 y no hay nada para comer disponible.
fuente
Error: unexpected 'else' in "else"
su código. Me temo que no conozco R en absoluto, por lo que no puedo comenzar a resolver este error. Como referencia, recibo este error tanto cuando lo ejecuto en el controlador como cuando simplemente ejecuto el programa y escribo manualmenteBEGIN
.Error in if (dir[1] < 0) where <- paste(where, "N", sep = "") : missing value where TRUE/FALSE needed
Error: object 'food' not found
(cuando frente a frente contra presentación Rubí de Alex, posiblemente otros)Bacterias coordinadas
Espero no llegar demasiado tarde.
Gana contra otros oponentes (y siempre matándolos a todos), en mis pruebas, y la batalla nunca terminará si se enfrenta a sí misma, una evidencia de que la estrategia es fuerte.
Cuando eres unicelular, puedes memorizar el estado anterior, ¡pero puedes explotar tu propia posición para comportarte de manera diferente! =)
Esto dividirá las bacterias en divisor y motor, y al hacerlo mantendrá más bacterias útiles en lugar de solo la línea del frente, mientras mantiene la línea de defensa.
También coordina sus ataques para enfocarse en un enemigo específico, de modo que los enemigos mueran más rápido (esto es para enfrentar a mi otra célula individual que se enfoca en HP).
A mitad del juego, que es detectado por la cantidad de células en el tablero, intentarán empujar al territorio enemigo flanqueándolas. Esta es la estrategia ganadora clave.
Esta tiene la tasa de crecimiento más alta en comparación con todos los demás oponentes actualmente, pero tiene un comienzo lento, por lo que funciona mejor en grandes arenas.
Ejecútalo con
java CoordinatedBacteria
fuente
Creo que publicaré mi presentación, ya que eres tan generoso para agregar la lógica repetitiva ...
Hubo un problema en su lógica, donde la acción de comer emitiría un ATAQUE en lugar de un COMER y desperdiciaría el cadáver.
He modificado tu esencia para tener una solución que funcione, que debería funcionar relativamente bien. Comienza con 4 hp y 8 de energía, por lo que después de una división y un descanso, ambas células pueden dividirse nuevamente. Intentará multiplicarse, atacar a los enemigos, comer cadáveres y descansar, en este orden. Por lo tanto, las células internas almacenarán sus 8 puntos de energía, para reemplazar rápidamente las células externas muertas y dejarles 3 puntos de energía para realizar un ataque de 3 puntos o multiplicarse después de un turno de descanso. Los 4 CV son para sobrevivir al menos a un ataque de fuerza total.
el ácido parece ser una pérdida de puntos para mí, así que lo mantuve fuera ...
No probé la presentación, ya que era una cosa de 2 minutos;)
Aquí está mi código:
fuente
Bombardero delgado
Dado que tan amablemente proporcionó el código repetitivo, decidí hacer mi propia celda simple; Esta célula tiene 4 acidez, solo 1 hp y 7 de energía. Intenta salir del rango de amistosos y luego espera allí (o come si es posible) hasta que tenga la oportunidad de explotar o replicarse. Ataca solo si es la única opción.
Es una estrategia bastante divertida y probablemente funcionará mal, pero tengo curiosidad por ver cómo funciona. Lo probaré y lo mejoraré más tarde hoy, tal vez.
fuente
node c:/cells/petri.js 'node c:/cells/bomber.js' 'node c:/cells/sample.js
. Cuando escribo esto en la consola de la aplicación de nodo, solo obtengo tres puntos, cuando intento ejecutarlo en el cmd de Windows, obtengo: 'node' no se reconoce como un comando interno o externo, un programa operable o un archivo por lotes. Guardé todos los archivos como archivos .js en la carpeta correcta. ¿Alguna ayuda para un novato? Iría al chat o comentaría en otro lugar, pero mi representante es demasiado bajo.if((nearbyEnemies.length - nearbyFriendlies.length > 1 ¦¦
; esos¦¦
no parecen ser un operador válido y tiene paréntesis que no coinciden. ¿Creo que el formato del código se estropeó cuando lo publicaste?=
) cuando lo que quieres es la comparación de igualdad (==
).