aBOTcalypse Now

8

aBOTcalypse

¡Diseña un bot para competir en un desafío del Rey de la Colina! Aquí hay una repetición de un juego de bot predeterminado.

El tablero es 2D, como un videojuego de desplazamiento lateral (pero sin desplazamiento).

Un bot válido debe aceptar una representación de cadena multilínea de la región del tablero que puede ver, y generar un movimiento para el bot.

Mecánica

Este es un juego de supervivencia. El apocalipsis ha llegado, y solo quedan bots (y un suministro interminable de rocas almacenadas en el espacio martillo ). Cada bot tiene una ubicación de inicio aleatoria, en la elevación 0. En un movimiento dado, un bot puede descansar, moverse, lanzar una piedra o dejar caer una piedra. Los bots pueden compartir espacio con rocas estacionarias, pero un bot que colisiona con otro bot o un meteorito muere, al igual que un bot golpeado por una roca arrojada.

  • Gravedad: los robots y las rocas deben descansar sobre el piso del tablero o sobre otra roca; descansar sobre otra cosa (aire, un meteorito, un bot, etc.) deja a uno "sin soporte". Los bots o rocas no compatibles caerán hasta que sean compatibles; una caída de más de un espacio matará a un bot, y un bot debajo de una roca o bot que cae también es asesinado. Esto significa que intentar moverse o desplegarse solo funcionará si el bot comparte actualmente un espacio con una roca (de lo contrario, el bot / roca caerá 1 espacio). Un espacio puede quedar "sin soporte" si la roca debajo de él cae o es destruida por un meteorito o un proyectil .
  • Meteoritos: cada turno un meteorito entra al tablero desde la parte superior. Un meteorito tiene una velocidad de magnitud 2, con un ángulo aleatorio elegido uniformemente en el rango [-180,0], y una posición x inicial aleatoria. Los meteoritos caen en línea recta a lo largo de la trayectoria dada hasta que golpean algo, en cuyo punto desaparecen. Tenga en cuenta que el redondeo en el movimiento de un meteorito es hacia 0 (según Python int()).
  • Proyectiles: un bot puede elegir lanzar una roca a cualquier distancia hasta su altura. Una roca arrojada se mueve en línea recta hasta que golpea algo (todo en un turno, a diferencia de un meteorito; las rocas arrojadas no aparecen en el tablero), en una pendiente de - elevation / max distance. Tenga en cuenta que las rocas arrojadas comienzan su trayectoria en x + - 1 cuadrado. Por ejemplo, si un bot está a una elevación de 5 y lanza una distancia de 1, la roca comenzará en (x-1,5)y terminará en (x-2,0). La colisión solo se verifica en pasos de dx=1, y dyse redondea hacia 0 (según Python int()).

Entrada

Cada bot puede ver un cuadrado de 20 píxeles en cada dirección (distancia de Chebyshev = 20), hasta los límites del tablero. Hay 8 caracteres diferentes en cada cadena de entrada:

  • '#' (límite del tablero)
  • '.' (aire)
  • '@'(meteorito)
  • '&' (rock)
  • 'e'/ 's'(un bot enemigo, o en sí mismo)
  • 'E'/ 'S'(un bot enemigo, o él mismo, compartiendo un espacio con una roca)

Aquí hay un ejemplo de entrada (los saltos de línea serán \n):

..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............................#
..............@...............#
.....................E........#
.....................&........#
.....................&........#
.....................&........#
.....................&........#
...........@.........&........#
....................s&........#
###############################

Salida

Hay cuatro acciones que un bot puede tomar cada turno.

  • rest (literalmente siéntate y no hagas nada)
  • move <direction>mueve el espacio uno bot en cualquiera de las cuatro direcciones, up, down, left, o right. El movimiento hace que el bot caiga si el nuevo espacio no es soportado por el piso o una roca ( fall > 1 = bot.kill()).
  • drop <direction>coloca ("cae") una roca en la dirección indicada. Dejar caer una piedra hacia arriba (es decir, colocar una piedra en el cuadrado [bot_x, bot_y+1]) o hacia un lado hace que se caiga hasta que se sostenga (posiblemente caiga sobre el bot durante drop up). drop downcoloca una roca en la misma posición que el bot, si aún no hay una roca allí.
  • throw <direction> <distance>lanza una piedra según la mecánica de "proyectiles" anterior, con la distancia máxima indicada. La distancia máxima es irrelevante para lanzar hacia arriba o hacia abajo: el proyectil choca con el cuadrado de abajo (for down) o intenta chocar con el cuadrado de arriba (for up) y luego con el cuadrado del bot si no golpea nada (matando al bot) .

Un bot en el concurso debe generar una cadena escalar con su acción al recibir la cadena de entrada.

Interfaz

Un bot debe consistir en un solo programa al que se pueda llamar mediante un pitón 2 subprocess. Cualquier comando debe indicarse y se guardará en un archivo llamado command.txt; antes de que comience un juego, el controlador ejecutará cada comando en command.txtorden, y luego el comando final se usará para pasar la entrada al bot a partir de ese momento.

Un bot puede tener un solo archivo de almacenamiento llamado storage.txten su carpeta; el bot "Default Thrower" muestra un ejemplo de implementación, usando json para guardar su estado durante varios turnos. Además, siéntase libre de incluir la salida de depuración en un solo escritura errlog.txt, que pasaré en caso de que su bot falle durante una ejecución. Me aseguraré de ejecutar varias pruebas con cada bot, para tratar de encontrar cualquier error de antemano.

Puntuación

La puntuación total de un bot es igual al número de turnos que sobrevive, acumulados en X juegos de longitud máxima Y. Por el momento X,Y = 10, 500,; si los bots duran mucho tiempo, aumentaré Y, y si duran poco tiempo, aumentaré X.

El código del controlador se encuentra en controller.py ; muchas gracias a @Nathan Merrill por su DDOS koth del que adapté el código del comunicador.

Sirpercival
fuente
¿Qué impide que los robots hagan estructuras como &&&\n&S&\n###? Serían invulnerables a la caída de meteoritos.
LegionMammal978
nada en absoluto. sin embargo, tendrían que reconstruir parte de la estructura si fue golpeada por algo (lo que implica estar expuesto en una de las capas externas durante el proceso de mantenimiento), y aún tendrían que lidiar con otros bots.
sirpercival
Por lo que puedo ver, no hay forma de cavar rocas.
LegionMammal978
¿Qué quieres decir con "cavar"? cada bot tiene tantas rocas como quiera, almacenadas en hammerspace ( editaré ese enlace en la pregunta). o quieres destruir rocas? Si ese es el caso, entonces una roca se destruye cuando es alcanzada por cualquier proyectil, no solo un meteorito. También date cuenta de que otros bots pueden entrar directamente a tu fortaleza.
sirpercival
1
Debe agregar el hecho de que los meteoritos / proyectiles destruyen rocas.
LegionMammal978

Respuestas:

1

Python 2, Edgebot

Edgebot quiere esconderse en una esquina y construir una torre. Correrán hacia un extremo, se acumularán un poco y luego comenzarán a soltar rocas para construir un muro. A Edgebot no le gustan los visitantes y arrojará piedras a cualquiera que se acerque demasiado a su torre. Si todo sale terriblemente mal y se cae el edgebot, caerá una roca sobre su cabeza

import sys
from random import randint
class edgebot():    

    def playtime(self,board):
        try:   
            self.max_height = 5    
            board = board.splitlines()

            #find edgebot
            for y in xrange(0,len(board)):
                row = board[y]
                symbol = 's' if row.count('s') else 'S'
                x = row.find(symbol)
                if x >= 0:
                    self.height = 20 - y
                    break

            ground = board[len(board)-2]
            floor = board[len(board)-1]
            nasty_person = 'e' if ground.count('e') else 'E'
            bad_x = ground.find(nasty_person)
            side = ground.find('#')
            if abs(side - x) ==1:
                self.end_found = 1
            else:
                self.end_found = 0

            if side - x == -1:
                self.direction = 'right'
            else:
                self.direction = 'left'       


            #Bad edgebot! No climbing out of the game!           
            if floor[x] != '#':
                if board[self.height-1][x] == '&':
                    dist = randint(3,self.height)
                    return 'throw ' + self.direction + ' ' + `dist`
                elif symbol =='S':
                    return 'drop up'
                else:
                    return 'move down'

            #Edgebot will go through you to find a corner. You have been warned.    
            elif abs(x - bad_x) <=2:
                if x - bad_x >0:
                    return 'throw left 1'
                else:
                    return 'throw right 1'

            #edgebot wants to hide in a corner
            elif self.end_found ==0:
                if side == -1:
                    return 'move right'#edgebot is right-handed
                elif side - x < -1:
                    return 'move left'
                elif side - x > 1:
                    return 'move right'

            #Too close! Throw rocks at it!
            elif self.height+1>= abs(x-bad_x) and abs(x-bad_x) >=3:
                distance = abs(x - bad_x) - 2
                if distance < 1:
                    return 'throw ' + self.direction + ' 1'
                else:
                    return 'throw ' + self.direction + ' ' +`distance - 1`
                self.max_height += 2 #people came close, edgebot needs to be higher up!

            #edgebot wants a home in the corner        
            elif self.height <self.max_height :
                if symbol =='S':
                    return 'move up'
                else:
                    return 'drop down'

            #edgebot wants a wall. edgebot has, at best, a limited understanding of architecture        
            elif bad_x < 3 or self.height+1<abs(x-bad_x):
                if self.direction == 'right' and row[x+1] == '&':
                    self.max_height += 2
                    return 'drop down'
                elif self.direction == 'left' and row[x-1] == '&':
                    self.max_height += 2
                    return 'move down'
                else:
                    return 'drop ' + self.direction         

            else:
                return 'drop down' #Not sure? Hide under a rock!
        except:
            return 'drop up' #All gone horribly wrong? Squish.


print edgebot().playtime(sys.argv[1])  

Perdón por todas las ediciones, no ejecuté suficientes casos de prueba antes de enviar. Hay un pequeño problema en que el pequeño tratará de salir de la parte superior del tablero con el tiempo suficiente, pero con suerte eso no será un problema en la mayoría de los partidos. Edgebot ahora debería arrojar rocas distancias aleatorias una vez que haya subido lo suficientemente alto

Última edición por ahora. Edgebot ahora arrojará piedras a cualquiera que esté lo suficientemente cerca entre él y la pared. No tiene sentido que salga corriendo a través de alguien

LogicianWithAHat
fuente