NOTA : ¡El ganador de esta competencia es Jack ! No se aceptarán más presentaciones.
Aquí está la sala de chat para este desafío del rey de la colina . Este es el primero, ¡así que estoy abierto a sugerencias!
Reaper es un concepto de juego desarrollado por el Arte de la resolución de problemas que implica paciencia y codicia. Después de modificar el juego para que se ajuste a un concurso de estilo KOTH (Gracias a @NathanMerrill y @dzaima por sus sugerencias y mejoras), este es el desafío.
El juego funciona de la siguiente manera: tenemos un valor conocido como Reap que se multiplica por una constante dada en cada tic. Después de cada tick, cada bot tiene la opción de "cosechar", lo que significa agregar el valor actual de Reap a la puntuación de uno y reducir Reap a 1.
Sin embargo, hay un número fijo de ticks que un bot debe esperar entre "cosechas" y un número fijo de puntos necesarios para ganar el juego.
¿Suficientemente simple? Aquí están sus entradas:
I / O
Debe escribir una función en Python 3 que tome 3 entradas. El primero es self
, usado para hacer referencia a objetos de clase (mostrados más adelante). El segundo es el Reap
valor actual de la cosecha que ganaría si fuera a "cosechar". El tercero es prevReap
una lista de los bots que cosecharon durante el tic anterior.
Otros objetos a los que puede acceder en su función:
self.obj: An object for your use to store information between ticks.
self.mult: The multiplier that Reap is multiplied by each tick
self.win: The score you need to win
self.points: Your current set of points
self.waittime: The amount of ticks that you must wait between reaps during the game
self.time: The number of ticks since your last reap
self.lenBots: The number of bots (including you) in the game.
self.getRandom(): Use to produce a random number between 0 and 1.
Usted DEBE no editar cualquiera de los contenidos de estos objetos, a excepción de self.obj
.
Debe generar resultados 1
para cosechar, y cualquier otra cosa (o nada) para no cosechar. Tenga en cuenta que si cosecha cuando no ha esperado suficientes tics, ignoraré el hecho de que ha elegido cosechar.
Reglas
Los parámetros que utilizaré son winning_score=10000
, multiplier=1.6-(1.2/(1+sqrt(x)))
, waittime = floor(1.5*x)
donde x
es el número de los robots en el KOTH.
- El juego termina cuando un jugador (o múltiples) alcanza el puntaje ganador.
- Cuando varios bots piden cosechar a la vez, se les da prioridad a los bots que han esperado más tiempo (en caso de empate, los bots que han esperado el tiempo máximo tienen permitido cosechar y ganar puntos en el Reap)
- Su bot no debe tomar más de 100 ms en promedio en 5 ticks.
- Si quieres importar bibliotecas, ¡pregunta! Intentaré agregar cualquier biblioteca que pueda ejecutar en mi versión de escritorio de Python (las matemáticas ya están importadas: siéntase libre de usarlo)
- Todas las lagunas estándar para KoTH, como los bot duplicados, los bots de 1 en 1, etc., están igualmente prohibidos.
- Cualquier bot que use algún tipo de aleatoriedad debe usar la
getRandom
función que he proporcionado.
Puede encontrar el controlador en el enlace TIO a continuación. Para usarlo, agregue el nombre de su función BotList
como una cadena y luego agregue la función al código. Modifique multiplier
para cambiar lo que el Reap se multiplica por cada tic, modifique winning_score
para cambiar qué puntaje es necesario para finalizar el juego, y modifique waittime
para cambiar el número de ticks a esperar entre las cosechas.
Para su comodidad, aquí hay algunos bots de muestra (y bastante tontos). No se permitirán enviar bots similares a estos. Sin embargo, demuestran cómo funciona el controlador.
def Greedybot(self,Reap, prevReap):
return 1
def Randombot(self,Reap, prevReap):
if self.obj == None:
self.obj=[]
self.obj.append(prevReap)
if self.getRandom()>0.5:
return 1
Para aquellos interesados, aquí está el controlador con las 15 presentaciones incorporadas: Pruébelo en línea
RESULTADOS FINALES
¡WOO ESTÁN FINALMENTE AQUÍ! Verifique el enlace TIO arriba para ver qué código usé para generar la clasificación final. Los resultados no son terriblemente interesantes. Durante las 1000 carreras que hice con diferentes semillas aleatorias, los resultados fueron
1000 wins - Jack
0 wins - everyone else
¡Felicitaciones al ganador de Bounty Jack! (también conocido como @Renzeee)
fuente
len(BotList)
?25
bots en juego. Sin embargo, primero esperaré un poco para ver los bots de otras personas. Rushabh Mehta , ¿habrá una fecha límite / fecha final cuando se ejecutarán todos los bots y se determinará un ganador?Respuestas:
Twitchy Mess indeciso
Este bot realiza primero las comprobaciones habituales (¿Puedo cosechar, puedo ganar?) Y luego busca un valor objetivo antes de cosechar. Sin embargo, es indeciso, por lo que una vez que alcanza el objetivo, se pregunta cuánto tiempo más puede esperar y no cosecha de inmediato. Además, es nervioso, por lo que accidentalmente puede "presionar el botón" y cosechar antes del objetivo.
Dato curioso: así es básicamente como juego a Reaper como humano.
fuente
Francotirador
Un bot alimentado por el rencor. Realiza un seguimiento de los tiempos de reutilización y puntajes del oponente. Intenta evitar que otros ganen. Prácticamente nunca gana, pero hace que el juego sea frustrante para otros.
EDITAR:
Si nadie es> = 70% del puntaje ganador:
Si al menos la mitad de los otros usuarios están en enfriamiento, intente cosechar.Esto hace que sea difícil apuntar a oponentes específicos, por lo que se eliminó.Si alguien ES> = 70% de la puntuación ganadora:
aburrido
Solo por diversión, este bot fue traído por un amigo y en realidad no quiere estar aquí. Lanzan un d16 hasta que obtienen un número en 1-9, luego intentan cosechar cada vez que un número contiene el dígito elegido. (¡Ir a buscar un d10 interrumpiría el juego, lo cual es grosero, y 0 es demasiado fácil!)
fuente
self.obj.opponents[opponent]["time"] += 1
en el primer for-loop yself.obj.lastReap
al final del segundo for-loop. Además de eso, buenas ideas. Tengo curiosidad por saber cómo funcionaría contra muchos otros bots. Cuando estoy usando muchos bots codiciosos y aleatorios, solo cosecharé lo antes posible porque la mayoría de las veces la mitad de los bots no pueden cosechar. Pero, por supuesto, esos no son competidores realistas.Jack
Este es un bot simple con 4 reglas:
He optimizado los 3 ticks en comparación con los bots existentes actuales (Sniper, grim_reaper, Every50, mess, BetterRandom, Averager, algunos más).
Intenté quedarme con mi solución anterior (5 ticks) pero también cosecho si no ha cosechado más de X ticks, y luego cosecho después de que se hayan pasado menos ticks durante la no cosecha (es decir, 5, si esperó más que yo) .waittime + 5, también cosechará si no ha cosechado 4 ticks). Pero esto no mejoró solo siempre cosechando después de 4 ticks en lugar de 5.
fuente
Cada 50
Estos bots cosecharán cada vez que la
Reap
cantidad sea superior a 50.¿Por qué 50?
Si supongo que habrá 25 bots en juego, significa que
multiplier = 1.6-(1.2/(1+sqrt(25))) = 1.4
y elwaittime = floor(1.5*25) = 37
. Desde elReap
comienzo en1
, subirá así:Como puede ver, alcanza más de 50 después de 13 ticks. Dado que
Reap
se restablecerá a 1 cada vez que un bot cosecha, ywaittime
para un bot que cosecha es 37, la probabilidad de que un bot coseche más temprano que tarde es bastante alta, especialmente con bots similares al ejemploGreedyBot
, que cosecharán tan pronto comowaittime
sea posible. Disponible de nuevo. Al principio quería hacer 200, que es el 17 ° tic, algo en el medio de los 37 tics de tiempo de espera, pero con la suposición de que hay 25 bots en juego, existe una gran posibilidad de que alguien más me arrebataReap
antes que yo. Así que lo bajé a 50. Todavía es un buen número redondeado, pero especialmente porque es el tick 13 (con 25 bots), y 13 y 'cosechar' también encajan un poco en el mismo género 'malvado'.Código:
El código es trivial risible.
Notas:
Este bot es bastante malo con poca cantidad de bots en juego. Por ahora lo dejaré, y podría hacer un mejor bot calculando el mejor momento para hacerlo
Reap
. Con una cantidad extremadamente baja de bots en juego,waittime
es mucho más bajo, por supuesto, por lo que inclusoGreedyBot
podría ganar fácilmente con este bot siwaittime
es lo suficientemente bajo.Esperemos que más personas agreguen muchos más bots. ;pag
fuente
def Every49(self, Reap, prevReap): return Reap > 49
Su movimiento.int
evitar la desigualdad, ya que 1 es el verdadero comandoTrue
explícito1
. Pensé que laTrue == 1
verificación aún regresaríaTrue
para mi bot agregándolo a las listas deReapers
en sunext
función, pero agregué el reparto a int de todos modos como usted sugirió.Promediador
Este bot intenta cosechar cada vez que el valor actual de Reap está por encima del valor promedio cosechado.
fuente
Parca
Este bot mantiene un promedio de los valores de todas las cosechas anteriores, así como el tiempo que cada bot ha estado esperando. Cosecha cuando ha estado esperando más de 3/4 de los otros bots y la cosecha es al menos 3/4 del tamaño de la cosecha promedio vista hasta ahora. El objetivo es obtener muchas cosechas de bajo riesgo de tamaño razonable.
Editar: se corrigieron algunos errores de sintaxis embarazosos.
Pruébalo en línea
fuente
self.obj.reaps
lugar deself.reaps
y enself.obj
lugar deself.object
y enprevReap
lugar deprevLeap
y agregar () después deself.obj.players.values
dos veces. Y creoself.obj.reaps = []
que no funcionará a menos queself.obj
sea un objeto. No estoy completamente seguro de si todo sigue funcionando según lo previsto y si todo lo que dije es cierto, pero después de estos cambios y el uso de un Objeto ficticio paraself.obj
cuando aún no existe, su código se compila para mí.class Object(object):
[nueva línea]pass
en la parte superior y lo uséself.obj = Object()
enif not hasattr(..)
(si no recuerdo mal).BetterRandom
El bot se basa en la suposición de que la posibilidad de cosechar debe ser proporcional al tamaño de cosecha porque un punto es un punto, sin importar cuándo se haya obtenido. Siempre hay una pequeña posibilidad de cosechar, esto mantiene el comportamiento explotable. Primero pensé que sería directamente proporcional y asumí que la constante de proporcionalidad debería estar alrededor
1/mult^waittime
(la cosecha máxima suponiendo que al menos un bot juega codicioso) después de ejecutar algunas simulaciones, descubrí que esta era realmente la constante óptima. Pero Random todavía superó al bot, así que concluí que la relación no era directamente proporcional y agregué una constante para calcular cuál era la relación. Después de algunas simulaciones, descubrí que contra mi conjunto de pruebas de bots-1.5
era óptimo. Esto en realidad corresponde a una relación inversamente proporcional entre la probabilidad de cosecha yreap*sqrt(reap)
lo cual es sorprendente Así que sospecho que esto depende en gran medida de los bots específicos, por lo que sería mejor una versión de este bot que calcule k mientras se juega. (Pero no sé si puede usar datos de rondas anteriores).EDITAR: Hice un programa para encontrar el tipo de proporcionalidad automáticamente. En el conjunto de prueba
["myBot("+str(k)+")","Randombot","Greedybot","Every50","Jack","grim_reaper","Averager","mess"]
encontré el nuevo valor.fuente
(reap/self.mult**self.waittime)**-0.810192835
siempre está por encima de 1, es decir, self.getRandom () nunca es más alto.self.obj
es eso . Para ver algunos ejemplos sobre cómo usarlo, mira algunos otros bots que lo están usando.Objetivo
Mis posibilidades de ganar con lío son casi nulas ahora, ¡así que es hora de estropear a todos los demás bots de la mayor manera posible! :)
Este bot funciona de manera similar al francotirador. Cada vez que alguien cosecha, elige un objetivo aleatorio de quien haya cosechado. Luego, simplemente espera hasta que ese objetivo casi pueda cosechar nuevamente y lo golpea. Sin embargo, no cambia el enfoque: una vez que ha sido elegido y bloqueado, no puede escapar :)
fuente
EveryN
Supongo que es hora de mi segundo bot justo antes de la fecha límite.
Este bot:
n
rondas, donden
se calcula conn = 3 + ceil(self.waittime / self.lenBots)
Código:
No programo en Python muy a menudo, así que si ves algún error avísame.
fuente
subsequentRoundsWithoutReaps
aroundsWithoutReaps
; usado minúsculas con guiones bajos para el nombre del método; y eliminó el paréntesis en las declaraciones if. Gracias.prevReap
andlenBots
y such y las variables asumidas son camelCase como en Java. ;) Ah bueno, cualquiera que sea el caso que usemos, debería funcionar de todos modos. Sin embargo, los 2 espacios en lugar de los 4 con sangría probablemente habrían causado algunos problemas, así que gracias de cualquier manera.En curso: mi proyecto para extender T4T a cada KOTH abierto.
Tal para cual
Teta para n tatuajes
Kevin
Solo para mantenerte alerta.
fuente
self.last
no es una cosa, ¡pero puedes hacerself.obj.last
una cosa! De todos modos, agregaré los tres bots para los memes +1Joe promedio
Me inspiré en Averager y creé un bot que calcula en promedio cuántos turnos toma antes de que alguien coseche e intente cosechar un turno antes de eso.
fuente
HardCoded
Sí lo es.
En lugar de promediar en las cosechas pasadas, use un promedio precalculado en una carrera típica. No va a mejorar con el tiempo de todos modos.
fuente