aBOTcalypse Now

8

aBOTcalypse

Projete um bot para competir em um desafio do tipo Rei da Colina! Aqui está uma repetição de um jogo de bot padrão.

O tabuleiro é 2D, como um videogame com rolagem lateral (mas sem rolagem).

Um bot válido deve aceitar uma representação de cadeia de linhas múltiplas da região do quadro que pode ver e gerar uma movimentação para o bot.

Mecânica

Este é um jogo de sobrevivência. O apocalipse chegou, e apenas robôs (e um suprimento infinito de rochas armazenadas no espaço do martelo ) permanecem. Cada bot recebe um local inicial aleatório, na elevação 0. Em um determinado movimento, um bot pode descansar, se mover, atirar uma pedra ou soltar uma pedra. Os bots podem dividir espaço com rochas estacionárias, mas um bot que colide com outro bot ou um meteoro é morto, assim como um bot atingido por uma pedra lançada.

  • Gravidade: bots e pedras devem repousar sobre o chão do tabuleiro ou sobre outra pedra; descansar em outra coisa (ar, meteoro, bot, etc.) deixa um "sem suporte". Bots ou rochas não suportados cairão até serem suportados; uma queda maior que um espaço matará um bot, e um bot debaixo de uma pedra ou bot caindo também é morto. Isso significa que tentar mover ou soltar só funcionará se o bot estiver atualmente compartilhando um espaço com uma rocha (caso contrário, o bot / rock voltará a cair 1 espaço). Um espaço pode se tornar "não suportado" se a rocha abaixo dele cair ou for destruída por um meteoro ou projétil .
  • Meteoros: A cada turno, um meteoro entra no tabuleiro de cima. Um meteoro tem uma velocidade de magnitude 2, com um ângulo aleatório escolhido uniformemente no intervalo [-180,0] e uma posição x inicial aleatória. Os meteoros caem em uma linha reta ao longo da trajetória determinada até atingirem algo, momento em que desaparecem. Observe que o arredondamento no movimento de um meteoro é na direção de 0 (conforme o de python int()).
  • Projéteis: Um bot pode escolher atirar uma pedra a qualquer distância até sua elevação. Uma pedra jogada se move em linha reta até atingir algo (tudo em um turno, diferente de um meteoro; pedras lançadas não aparecem no tabuleiro), em uma inclinação de - elevation / max distance. Observe que as rochas lançadas começam sua trajetória em x + - 1 quadrado. Por exemplo, se um bot está a uma altitude de 5 e joga à esquerda a uma distância de 1, a rocha começará em (x-1,5)e terminará em (x-2,0). A colisão é verificada apenas nas etapas de dx=1e dyé arredondada para 0 (conforme o python int()).

Entrada

Cada bot pode ver um quadrado de 20 pixels em cada direção (distância de Chebyshev = 20), até os limites do quadro. Existem 8 caracteres diferentes em cada sequência de entrada:

  • '#' (limite do quadro)
  • '.' (ar)
  • '@'(meteoro)
  • '&' (Rocha)
  • 'e'/ 's'(um bot inimigo, ou ele próprio)
  • 'E'/ 'S'(um bot inimigo, ou ele próprio, compartilhando um espaço com uma rocha)

Aqui está um exemplo de entrada (quebras de linha serão \n):

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

Resultado

Existem quatro ações que um bot pode executar a cada turno.

  • rest (literalmente sente-se e não faça nada)
  • move <direction>move o espaço um bot em qualquer uma das quatro direcções, up, down, left, ou right. O movimento faz com que o bot caia se o novo espaço não for suportado pelo chão ou por uma rocha ( fall > 1 = bot.kill()).
  • drop <direction>coloca ("cai") uma pedra na direção indicada. Soltar uma pedra (colocando uma pedra no quadrado [bot_x, bot_y+1]) ou para o lado faz com que ela caia até ficar apoiada (possivelmente caindo durante o bot drop up). drop downcoloca uma pedra na mesma posição que o bot, se já não houver uma pedra.
  • throw <direction> <distance>lança uma pedra de acordo com a mecânica dos "projéteis" acima, com a distância máxima indicada. A distância máxima é irrelevante para arremessar para cima ou para baixo - o projétil colide com o quadrado abaixo (para down) ou tenta colidir com o quadrado acima (para up) e depois com o quadrado do bot se não atingir nada (matá-lo) .

Um bot no concurso deve gerar uma sequência escalar com sua ação ao receber a sequência de entrada.

Interface

Um bot deve consistir em um único programa que pode ser chamado via python 2 subprocess. Quaisquer comandos devem ser indicados e serão salvos em um arquivo chamado command.txt; antes de um jogo começar, o controlador executará cada comando em command.txtordem e, em seguida, o comando final será usado para passar a entrada para o bot a partir de então.

Um bot pode ter um único arquivo de armazenamento chamado storage.txtem sua pasta; o bot "Default Thrower" mostra um exemplo de implementação, usando json para salvar seu estado durante várias voltas. Além disso, sinta-se à vontade para incluir a saída de depuração em somente gravação errlog.txt, que transmitirei caso seu bot falhe durante uma execução. Certificarei-me de executar vários testes com cada bot, para tentar encontrar erros antes.

Pontuação

A pontuação total de um bot é igual ao número de turnos em que sobrevive, acumulados em X jogos de duração máxima Y. No momento X,Y = 10, 500,; se os bots durarem muito, aumentarei Y e, se durarem pouco, aumentarei X.

O código do controlador é encontrado em controller.py ; muito obrigado a Nathan Merrill por seu DDOS koth, do qual adaptei o código do Communicator.

sirpercival
fonte
O que impede os robôs de criar estruturas como &&&\n&S&\n###? Eles seriam invulneráveis ​​a meteoros caindo.
LegionMammal978
nada mesmo. no entanto, eles teriam que reconstruir parte da estrutura se isso fosse atingido por alguma coisa (que envolve ser exposto a uma das camadas externas durante o processo de manutenção) e ainda teriam que lidar com outros bots.
Sirpercival
Tanto quanto posso ver, não há como cavar pedras.
LegionMammal978
o que você quer dizer com "cavar"? cada bot tem quantas pedras quiser, armazenadas no espaço do martelo (vou editar esse link na pergunta). ou você pretende destruir rochas? se for esse o caso, uma pedra é destruída quando é atingida por qualquer projétil, não apenas por um meteoro. também percebe que outros bots podem entrar na sua fortaleza.
Sirpercival
1
Você deve adicionar o fato de que meteoros / projéteis destroem rochas.
LegionMammal978

Respostas:

1

Python 2, Edgebot

Edgebot quer se esconder em um canto e construir uma torre. Eles correm para um lado, constroem um pouco e depois começam a soltar pedras para construir um muro. O Edgebot não gosta de visitantes e atira pedras em quem se aproxima demais da torre. Se tudo der errado e o Edgebot travar, ele derrubará uma pedra em sua própria cabeça

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])  

Desculpe por todas as edições, não executamos casos de teste suficientes antes do envio. Há um pequeno problema em que o rapaz tentará sair do topo da tabela com tempo suficiente, mas espero que isso não seja um problema na maioria das partidas. O Edgebot agora deve apenas atirar pedras a distâncias aleatórias quando subir alto o suficiente

Última edição por enquanto. O Edgebot agora atirará pedras em alguém próximo o suficiente entre ele e a parede. Não faz sentido sair correndo através de alguém

LogicianWithAHat
fonte