Aviso prévio
Esse desafio terminou e não será julgado novamente, mas fique à vontade para postar respostas e testar seu programa contra os outros com o Programa de Controle!
O objetivo deste desafio é fazer uma IA vencer uma luta contra outra IA, estrategicamente, desenhando uma parede em uma grade 25x25 para bloquear o oponente.
Entrada
25 linhas separadas por e terminando com ;
como argumento da linha de comando. Isso incluirá:
- Espaços vazios
.
- Paredes
#
- Jogadores
1
e2
(O oponente é sempre2
)
Exemplo
###############..........;..............#..........;..............#..........;..............#..........;..............#..........;...........1###..........;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;...................###...;...................#.##..;2..................#..#..;#..................##.#..;#...................#.###;....................#####;
que representa o seguinte mapa:
###############..........
..............#..........
..............#..........
..............#..........
..............#..........
...........1###..........
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
...................###...
...................#.##..
2..................#..#..
#..................##.#..
#...................#.###
....................#####
Resultado
Uma sequência gravada no console começando com o caractere que representa a direção que a IA deseja mudar. Este é caso sensível!
- Norte
N
- Leste
E
- Sul
S
- Oeste
W
- Desistir (qualquer outra coisa)
Exemplo
W
Regras do jogo
- À medida que as IAs se movem, elas deixam um sólido rastro de paredes atrás delas.
- Os jogadores começam nos cantos superior esquerdo e inferior direito
- O jogo dura até que qualquer IA atinja uma parede ou as AIs colidam umas com as outras.
- Uma IA vence se o oponente bater primeiro
- Não há vencedor ou perdedor se as IAs perderem ao mesmo tempo.
- Se uma IA sair de uma extremidade da grade, ela continua na mesma direção do outro lado.
Rankings
1º Lugar - FloodBot (Java, 12 vitórias)
2º Lugar - FluidBot (Python, 9 vitórias)
3º Lugar - FillUpBot (C ++, 8 vitórias)
4º Lugar - AwayBot (Ruby, 5 vitórias)
5º Lugar - ArcBot (Python, 4 vitórias)
6º Lugar - BlindSnake (Lote, 2 vitórias)
6º Lugar - RandomBot (C #, 2 vitórias)
Programa de Controle (Testado para Python 3.3.3)
O programa é executado com argumentos dos dois comandos e um único argumento ( ""
se não for necessário) para as AIs, por exemplo. Control.py "ruby" "AwayBot.rb" "FillUpBot.exe" ""
. Pode ser baixado aqui .
import sys, subprocess
Program1, Argument1, Program2, Argument2, Player1, Player2, Grid = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], [0, 0], [24, 24], [['.' for y in range(25)] for x in range(25)]
while True:
Str = ''
for x in range(25):
for y in range(25):
if Grid[x][y] == '1' or Grid[x][y] == '2':
Grid[x][y] = '#'
Grid[Player1[0]][Player1[1]] = '1'
Grid[Player2[0]][Player2[1]] = '2'
for y in range(25):
for x in range(25):
Str += Grid[x][y]
Str += ';'
if Argument1 == '':
move = subprocess.Popen([Program1, Str], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
else:
move = subprocess.Popen([Program1, Argument1, Str], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
Lose1 = False
if move == 'N':
if Player1[1] > 0:
Player1[1] -= 1
else:
Player1[1] = 24
elif move == 'E':
if Player1[0] < 24:
Player1[0] += 1
else:
Player1[0] = 0
elif move == 'S':
if Player1[1] < 24:
Player1[1] += 1
else:
Player1[1] = 0
elif move == 'W':
if Player1[0] > 0:
Player1[0] -= 1
else:
Player1[0] = 24
else:
Lose1 = True
if Grid[Player1[0]][Player1[1]] == '#' or Grid[Player1[0]][Player1[1]] == '2':
Lose1 = True
print('Player 1:', move)
if Argument2 == '':
move = subprocess.Popen([Program2, Str.replace('2','3').replace('1','2').replace('3','1')], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
else:
move = subprocess.Popen([Program2, Argument2, Str.replace('2','3').replace('1','2').replace('3','1')], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
Lose2 = False
if move == 'N':
if Player2[1] > 0:
Player2[1] -= 1
else:
Player2[1] = 24
elif move == 'E':
if Player2[0] < 24:
Player2[0] += 1
else:
Player2[0] = 0
elif move == 'S':
if Player2[1] < 24:
Player2[1] += 1
else:
Player2[1] = 0
elif move == 'W':
if Player2[0] > 0:
Player2[0] -= 1
else:
Player2[0] = 24
elif Lose1:
Lose2 = True
else:
Lose2 = True
print('Player 2:', move)
print(Str.replace(';', '\n'))
if Grid[Player2[0]][Player2[1]] == '#':
Lose2 = True
if Lose1 and Lose2:
print('Draw!')
break
elif Lose1:
print('Player 2 wins!')
break
elif Lose2:
print('Player 1 wins!')
break
fonte
Respostas:
Floodbot
Java
Esse cara é tudo sobre evasão. Ele não se importa em tentar prender o oponente, ele só quer viver. Para fazer isso, ele enche cada direção para ver qual caminho levará à maior área aberta.
Ele também acha que o inimigo é imprevisível, então trata cada quadrado imediatamente ao seu redor como já sendo um muro. Se isso não leva a uma direção possível, ele volta ao mapa "real".
fonte
BlindSnake
Lote
Este bot apenas observa seus arredores próximos. Se não houver uma parede, ela se move para lá.
Eu só queria criar um bot em lote ... E nunca mais o farei
fonte
FluidBot
Python 3
Toma caminho de menor resistência e tenta prever o oponente
Trabalhei nisso por cerca de uma hora. ._.
Testado contra o AwayBot:
FillUpBot:
EDIÇÃO 5 : Mais consciente do futuro; tenta evitar o fechamento de áreas (a menos que, obviamente, o oponente esteja nele).
EDIT 4 : Código limpo.
EDIT 3 : Funciona melhor para áreas de jogo retangulares.
EDIT 2 : Código mais limpo, algoritmo é mais lógico e prevê algumas mudanças no futuro
EDIT : Algoritmo mais defensivo, não conta o fantasma como espaço vazio.
fonte
AwayBot
escrito em Ruby (1.9)
Com o nome adequado, o AwayBot tenta se afastar de qualquer obstáculo. Ele procura um quadrado 15x15 em torno de si, avalia as direções de acordo e escolhe a direção com o menor número de obstáculos. (Isso também significa que evita as bordas, o que é bom para não ficar preso nelas.)
Também considera as paredes mais próximas como um perigo. As paredes próximas a ela pesam muito mais do que as paredes distantes.
Para sua entrada de amostra, ela gera
S
. Os pesos para cada direção da entrada de amostra são[["N", 212], ["E", 140], ["S", 0], ["W", 84]]
.Interjeição: Acabei de perceber que a arena envolve. Bem, então, minha técnica de evitar bordas é um tanto inútil agora, mas meh. Talvez eu conserte depois.
fonte
ARGF.argv[0].chomp
nãogets.chomp
na primeira linha!FillUpBot
escrito em C ++
Não pense que vou ganhar, mas aqui está a minha chance:
Seu compilador C ++ padrão deve ser capaz de lidar com isso.
fonte
#include <cstdlib>
Ajuda? (Basta inseri-lo no topo como uma nova linha)Arcbot
Python 3
Joga com algoritmo baseado em agressões, pois o inimigo e as forças brutas respondem com influência
Esse algoritmo é meio 'baseado em emoção', eu acho. Ao desenvolver isso, percebi que o FluidBot vencia quase todas as vezes. O Arcbot não é o algoritmo mais rápido nem o melhor, mas tem seus pontos fortes.
ele faz colidir com as paredes. Não faço ideia do porquê.
O FLUIDBOT É MELHOR
EDIT : Ajustado os números e a fórmula, ele toca melhor agora, mas ainda perde para o Fluidbot.
EDIT 2 : Opa, esqueci de mudar algum código.
fonte
RandomBot
C #
O RandomBot seleciona aleatoriamente uma direção até que sua rota esteja livre. Se não houver uma direção segura, basta digitar
*
e perder.fonte
Bot de preenchimento (gira 90 graus no sentido anti-horário, quando enfrenta um obstáculo
C ++
No meu código, os dois jogadores (1 e 2) tentam inundar. Ou seja, sempre que enfrentam um obstáculo, eles giram no sentido anti-horário.
Lembre-se, as linhas na entrada são separadas por um
space
ounewline
não por;
fonte