Ogłoszenie
To wyzwanie się zakończyło i nie zostanie ponownie ocenione, ale możesz opublikować odpowiedzi i przetestować swój program na tle innych za pomocą Programu Kontroli!
Celem tego wyzwania jest stworzenie sztucznej inteligencji do wygrania walki z inną sztuczną inteligencją poprzez strategiczne narysowanie ściany na siatce 25 x 25 w celu zablokowania przeciwnika.
Wejście
25 linii oddzielonych i zakończonych ;
jako argument wiersza poleceń. Będzie to obejmować:
- Puste miejsca
.
- Ściany
#
- Gracze
1
i2
(Przeciwnik jest zawsze2
)
Przykład
###############..........;..............#..........;..............#..........;..............#..........;..............#..........;...........1###..........;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;...................###...;...................#.##..;2..................#..#..;#..................##.#..;#...................#.###;....................#####;
który reprezentuje następującą mapę:
###############..........
..............#..........
..............#..........
..............#..........
..............#..........
...........1###..........
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
...................###...
...................#.##..
2..................#..#..
#..................##.#..
#...................#.###
....................#####
Wynik
Ciąg napisany na konsoli zaczynający się od znaku reprezentującego kierunek, w którym AI chce się obrócić. W tym rozróżniana jest wielkość liter!
- Północ
N
- Wschód
E
- południe
S
- Zachód
W
- Zrezygnuj (cokolwiek innego)
Przykład
W
Zasady gry
- Gdy SI poruszają się, pozostawiają za sobą solidny ślad ścian.
- Gracze zaczynają w lewym górnym i prawym dolnym rogu
- Gra trwa, dopóki dowolna sztuczna inteligencja nie uderzy o ścianę lub nie zderzy się ze sobą.
- AI wygrywa, jeśli jej przeciwnik rozbije się jako pierwszy
- Nie ma zwycięzcy ani przegranego, jeśli obie SI przegrają jednocześnie.
- Jeśli AI zejdzie z jednej krawędzi siatki, kontynuuje w tym samym kierunku z drugiej strony.
Rankingi
1. miejsce - FloodBot (Java, 12 wygranych)
2 miejsce - FluidBot (Python, 9 wygranych)
3 miejsce - FillUpBot (C ++, 8 zwycięstw)
4 miejsce - AwayBot (Ruby, 5 wygranych)
5. miejsce - ArcBot (Python, 4 wygrane)
6. miejsce - BlindSnake (partia, 2 wygrane)
6. miejsce - RandomBot (C #, 2 wygrane)
Program sterujący (przetestowany dla Python 3.3.3)
Program jest uruchamiany z argumentami dwóch poleceń i pojedynczym argumentem ( ""
jeśli nie jest wymagany) dla AI, np. Control.py "ruby" "AwayBot.rb" "FillUpBot.exe" ""
. Można go pobrać tutaj .
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
źródło
Odpowiedzi:
Floodbot
Jawa
Ten facet polega na unikaniu. Nie chce próbować uwięzić przeciwnika, po prostu chce żyć. Aby to zrobić, wypełnia każdy kierunek, aby zobaczyć, która droga doprowadzi do największej otwartej przestrzeni.
Uważa również, że wróg jest nieprzewidywalny, dlatego każdy otaczający go kwadrat traktuje jak mur. Jeśli to nie prowadzi do możliwego kierunku, wraca do „rzeczywistej” mapy.
źródło
BlindSnake
Partia
Ten robot obserwuje tylko swoje najbliższe otoczenie. Jeśli nie ma ściany, porusza się tam.
Chciałem tylko stworzyć bota wsadowo ... I nigdy więcej tego nie zrobię
źródło
FluidBot
Python 3
Obiera ścieżkę najmniejszego oporu i próbuje przewidzieć przeciwnika
Pracowałem nad tym przez około godzinę. ._.
Testowane przeciwko AwayBot:
FillUpBot:
EDYCJA 5 : Bardziej świadomy przyszłości; stara się unikać zamykania obszarów (chyba, że oczywiście jest w nich przeciwnik).
EDYCJA 4 : Wyczyszczony kod.
EDYCJA 3 : Działa lepiej na prostokątnych obszarach gry.
EDYCJA 2 : Czystszy kod, algorytm jest bardziej logiczny i przewiduje pewne ruchy w przyszłości
EDYCJA : Bardziej defensywny algorytm, nie liczy jaźni duchów jako pustej przestrzeni.
źródło
AwayBot
napisane w Ruby (1.9)
AwayBot, o dobrej nazwie, próbuje uciec od przeszkód. Szuka wokół siebie kwadratu 15 x 15, odpowiednio waży kierunki i wybiera kierunek z najmniejszą liczbą przeszkód. (Oznacza to również, że omija krawędzie, co jest dobre, aby się w nich nie uwięzić).
Uważa także, że ściany bliżej są bardziej niebezpieczne. Ściany tuż obok niego ważą znacznie więcej niż ściany daleko.
Na przykładowe dane wyjściowe
S
. Wagi dla każdego kierunku wprowadzania próbki wynoszą[["N", 212], ["E", 140], ["S", 0], ["W", 84]]
.Wtrącenie: Właśnie zauważyłem, że arena się zawija. No cóż, moja technika omijania krawędzi jest teraz trochę bezcelowa, ale ja. Może naprawię to później.
źródło
ARGF.argv[0].chomp
a więc zamiastgets.chomp
w pierwszym wierszu!FillUpBot
napisane w C ++
Nie sądzę, że wygram, ale i tak mam na to:
Standardowy kompilator C ++ powinien być w stanie to obsłużyć.
źródło
#include <cstdlib>
pomaga? (Po prostu wstaw go u góry jako nowy wiersz)Arcbot
Python 3
Gra algorytmem opartym na agresji, gdy wrogowie i brutale odpowiadają z wpływem
Algorytm ten jest chyba „oparty na emocjach”. Rozwijając to, zdałem sobie sprawę, że FluidBot pobił go prawie za każdym razem. Arcbot nie jest najszybszym ani najlepszym algorytmem, ale ma swoje zalety.
To nie upaść na ścianach. Nie mam pojęcia dlaczego.
FLUIDBOT JEST LEPSZY
EDYCJA : Dostosowałem liczby i formułę, teraz gra lepiej, ale wciąż przegrywa z Fluidbotem.
EDYCJA 2 : Ups, zapomniałem zmienić kod.
źródło
RandomBot
DO#
RandomBot losowo wybiera kierunek, dopóki jego trasa nie będzie wolna. Jeśli nie ma bezpiecznego kierunku, po prostu pisze
*
i traci.źródło
Fill Up Bot (obraca się o 90 stopni w kierunku przeciwnym do ruchu wskazówek zegara, gdy napotyka przeszkodę)
C ++
W moim kodzie dwaj gracze (1 i 2) próbują zalać. Oznacza to, że za każdym razem, gdy napotykają przeszkodę, skręcają w lewo.
Pamiętaj, że linie wejściowe są oddzielone znakiem a
space
lubnewline
nie;
źródło