KOTH asimétrico: atrapa al gato
ACTUALIZACIÓN : Los archivos gist se actualizan (incluidas las nuevas sumisiones) ya que Controller.java no detectó Excepciones (solo errores). Ahora detecta errores y excepciones y también los imprime.
Este desafío consta de dos hilos, este es el hilo del receptor, el hilo del gato se puede encontrar aquí .
El controlador se puede descargar aquí .
Este es un KOTH asimétrico: cada presentación es un gato o un receptor . Hay juegos entre cada par de cada un gato y un receptor. Los gatos y los receptores tienen clasificaciones separadas.
Receptor
Hay un gato en una cuadrícula hexagonal. Su tarea es atraparlo lo más rápido posible. Cada turno, puede colocar un cubo de agua en una celda de la rejilla para evitar que el gato pueda ir allí. Pero el gato no es (tal vez) tan tonto, y cada vez que coloca un cubo, el gato se moverá a otra celda de la cuadrícula. Como la cuadrícula es hexagonal, el gato puede ir en 6 direcciones diferentes. Su objetivo es rodear al gato con cubos de agua, cuanto más rápido mejor.
Gato
Sabes que el receptor quiere atraparte colocando cubos de agua a tu alrededor. Por supuesto que tratas de evadir, pero como eres un gato perezoso (como lo son los gatos) exactamente das un paso a la vez. Esto significa que no puede permanecer en el mismo lugar que usted, pero debe moverse a uno de los seis lugares circundantes. Cada vez que veas que el receptor colocó un nuevo cubo de agua, vas a otra celda. Por supuesto, intenta evadir el mayor tiempo posible.
Cuadrícula
La cuadrícula es hexagonal, pero como no tenemos estructuras de datos hexagonales, tomamos una 11 x 11
matriz cuadrada en 2d e imitamos el 'comportamiento' hexagonal que el gato solo puede mover en 6 direcciones:
La topología es toroidal, eso significa que si pisa una celda 'fuera' de la matriz, simplemente será transferido a la celda correspondiente en el otro lado de la matriz.
Juego
El gato comienza en la posición dada en la cuadrícula. El receptor puede hacer el primer movimiento, luego el gato y su receptor se mueven alternativamente hasta que el gato sea atrapado. El número de pasos es la puntuación para ese juego. El gato intenta obtener una puntuación lo más alta posible, el receptor intenta obtener una puntuación lo más baja posible. La suma promedio de todos los juegos en los que participó será el puntaje de su presentación. Hay dos clasificaciones separadas, una para el gato y otra para los receptores.
Controlador
El controlador dado está escrito en Java. Como un receptor o un gato, cada uno debe completar cada uno implementar una clase Java (ya hay algunos ejemplos primitivos) y colocarla en elplayers
paquete (y actualizar la lista de gatos / receptores en la clase Controlador), pero también puede escribir funciones adicionales dentro de esa clase. El controlador viene con cada dos ejemplos de trabajo de clases simples de gatos / receptores.
El campo es una matriz 11 x 11
2D int
que almacena los valores de los estados actuales de las celdas. Si una celda está vacía, tiene valor 0
, si hay un gato tiene valor -1
y si hay un depósito hay un 1
.
Hay algunas funciones que puede usar: isValidMove()
/ isValidPosition()
son para verificar si su movimiento (cat) / posición (catcher) es válido.
Cada vez que es tu turno, takeTurn()
se llama a tu función . El argumento contiene una copia de la cuadrícula actual y tiene métodos como read(i,j)
para leer la celda (i,j)
, así comoisValidMove()/ isValidPosition()
que verifica la validez de su respuesta. Esto también gestiona el ajuste de la topología toroidal, lo que significa que incluso si la cuadrícula es solo 11 x 11, aún puede acceder a la celda (-5,13).
El método debe devolver una int
matriz de dos elementos, que representan posibles movimientos. Para los gatos, estos son los {-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}
que representan la posición relativa de dónde quiere ir el gato, y los receptores devuelven las coordenadas absolutas de dónde quieren colocar un balde {i,j}
.
Si su método produce un movimiento no válido, su envío será descalificado. El movimiento se considera no válido, si en su destino ya hay un cubo o el movimiento no está permitido / el destino ya está ocupado (como un gato), o si ya hay un cubo / gato (como un receptor). Puede verificar eso de antemano con las funciones dadas.
Su envío debe funcionar razonablemente rápido. Si su método tarda más de 200 ms en cada paso, también será descalificado. (Preferiblemente mucho menos ...)
Los programas pueden almacenar información entre los pasos.
Envíos
- Puede realizar tantos envíos como desee.
- No modifique significativamente las presentaciones que ya ha enviado.
- Por favor, cada presentación en una nueva respuesta.
- Cada presentación debe tener preferiblemente su nombre único.
- La presentación debe consistir en el código de su clase, así como una descripción que nos diga cómo funciona su presentación.
- Puede escribir la línea
<!-- language: lang-java -->
antes de su código fuente para obtener un resaltado automático de sintaxis.
Puntuación
Todos los gatos competirán contra todos los receptores el mismo número de veces. Intentaré actualizar los puntajes actuales con frecuencia, los ganadores se determinarán cuando la actividad haya disminuido.
Este desafío está inspirado en este viejo juego flash
Gracias @PhiNotPi por probar y dar algunos comentarios constructivos.
Puntajes actuales (100 juegos por emparejamiento)
Name Score Rank Author
RandCatcher 191674 8 flawr
StupidFill 214246 9 flawr
Achilles 76820 6 The E
Agamemnon 74844 5 The E
CloseCatcher 54920 4 randomra
ForwordCatcher 94246 7 MegaTom
Dijkstra 46500 2 TheNumberOne
HexCatcher 48832 3 randomra
ChoiceCatcher 43828 1 randomra
RandCat 77928 7 flawr
StupidRightCat 81794 6 flawr
SpiralCat 93868 5 CoolGuy
StraightCat 82452 9 CoolGuy
FreeCat 106304 3 randomra
RabidCat 77770 8 cain
Dijkstra's Cat 114670 1 TheNumberOne
MaxCat 97768 4 Manu
ChoiceCat 113356 2 randomra
PRINT_STEPS = true
más detalladas en el archivoMyFrame.java
). Luego grabé esto con LICEcap y lo edité con GIMP . Si tiene más preguntas, ¡solo pregunte!Respuestas:
Aquiles
Aquiles no es demasiado brillante, pero es implacablemente eficiente. Primero evita que el gato use la envoltura del tablero, luego divide el tablero en dos. Luego sigue dividiendo la parte del tablero en la que está el gato por la mitad hasta que queda atrapado.
Demostración RandCat vs Aquiles
fuente
Agamenón
Agamenón divide el área del gato por la mitad con una línea vertical hasta que el gato solo tiene una franja de ancho 2 para moverse, en cuyo punto atrapa al gato.
Agamenón vs RandCat:
Este receptor es mucho mejor que Aquiles y creo que es lo suficientemente diferente como para justificar una nueva respuesta.
fuente
HexCatcher
Si el receptor puede meter al gato dentro de un gran hexágono con 3 unidades de lados donde las esquinas del hexágono ya están ocupadas por cubos, el receptor puede mantener al gato en esta área y atraparlo. El hexágono se ve así:
Esto es lo que HexCatcher intenta lograr. Mentaliza el campo con estos grandes hexágonos de manera que cada celda de la esquina sea parte de 3 grandes hexágonos.
Si existe la posibilidad de mantener al gato en el área actual conectando dos esquinas al lado del gato, el bot lo hará. (Por ejemplo, en la imagen si el gato está en 7,5, elegimos 7,6 incluso si solo las celdas 6,6 y 8,5 están ocupadas todavía).
Si lo anterior no es una opción, elegimos jugar en una esquina que es parte del área donde está el gato. Si todas esas esquinas ya están elegidas (como en la imagen), elegimos una celda al lado del gato.
Son posibles múltiples pequeñas mejoras, como manejar mejor la envoltura (el mosaico se rompe allí) o hacer los últimos dos movimientos de manera óptima. Podría hacer algunos de estos. Si no está permitido, lo agregaré (fuera de competencia) a los interesados.
DijkstrasCat vs HexCatcher:
fuente
CloseCatcher
Elige una de las posiciones donde el gato podría pisar en el siguiente paso. Elige el que daría la mayor cantidad de caminos posibles después de 3 pasos para el gato si se moviera allí y el campo no cambiara.
El código es casi idéntico a mi entrada Cat, FreeCat , que elige la dirección de una manera muy similar.
SpiralCat vs CloseCatcher:
fuente
Dijkstra
No le gustan mucho los gatos (:
v{ >
FreeCat vs Dijkstra
(necesidades actualizadas):Cómo intenta atrapar al gato:
Analiza todos los cuadrados del tablero y trata de encontrar el cuadrado que minimiza la apertura del tablero y maximiza cuánto está tendido el tablero; en relación con el gato. La apertura y la fibrosidad de un tablero se calculan utilizando una modificación de su famoso algoritmo .
Franqueza:
La apertura de un tablero en relación con una posición es el número de posiciones alcanzables desde esa posición.
Stringiness:
La fibrosidad de un tablero en relación con una posición es la suma de las distancias entre las posiciones alcanzables y la posición.
Con la última actualización:
Ahora, es mucho mejor atrapando a
FreeCat y a su propio gatotodos los gatos.Desafortunadamente, también es mucho peor al atrapar a los locos gatos que no cooperan. Podría mejorarse al detectar si el gato es uno de los locos y luego actuar como CloseCatcher.Error corregido.
fuente
error: cannot infer type arguments for PriorityQueue<>
en esta líneaPriorityQueue<int[]> open = new PriorityQueue<>(new Comparator<int[]>() {
.int[]
entre los dos diamantes vacíos despuésPriorityQueue
.ForwordCatcher
Coloca un cubo delante del gato, o si se toma, se coloca detrás.
RabidCat vs ForwordCatcher:
fuente
ChoiceCatcher
Utiliza el mismo mecanismo de puntuación que mi entrada ChoiceCat . Hay una pequeña modificación que ayuda a elegir las celdas relevantes en los primeros pasos, ya que a ChoiceCat no le importan los primeros grupos, ya que no los ve como una amenaza.
ChoiceCatcher parece tener un puntaje considerablemente mejor que los receptores actuales.
ChoiceCat vs ChoiceCatcher:
fuente
RandCatcher
Esto se hizo solo para probar el controlador y coloca aleatoriamente los cubos (de manera muy ineficiente).
fuente
StupidFillCatcher
Esto se hizo solo para probar el controlador. Simplemente se llena columna por columna hasta que se atrapa al gato.
fuente