Weźmy wojnę czołgów!
Częściowo zainspirowany Destroy Them With Lazers
Cel
Twoim zadaniem jest kontrolowanie czołgu. Poruszaj się i strzelaj do innych czołgów i przeszkód na polu bitwy 2D. Ostatni stojący czołg zostanie zwycięzcą!
Format mapy
Zbiornik będzie na polu 2D oparte na n
przez n
siatkę kwadratów jednostkowych. Zdecyduję, co n
będzie oparte na liczbie zgłoszeń. Każdy kwadrat może zawierać tylko jeden z:
- Czołg
- Drzewo
- Skała
- Ściana
- Nic
Wszystkie przeszkody i czołgi całkowicie wypełniają swoje pola i blokują wszystkie strzały, które do nich trafiły, od zadawania obrażeń dalej.
Oto przykład pola z #
= tank; T
= drzewo; R
= kamień; W
= ściana; .
= nic z n
= 10
.....#....
..T....R..
WWW...WWWW
W......T..
T...R...Ww
W...W.....
W....W...T
WWWWWW...R
W.........
WWWWWWRT..
Współrzędne mają format, w x, y
którym x
zwiększa się od lewej do prawej i y
zwiększa się od dołu do góry. Lewa dolna spacja ma współrzędną 0, 0
. Każdy czołg może przenieść się na dowolne puste miejsce i strzelać w dowolnym kierunku.
Dynamika mapy
Twój czołg nie musi tylko strzelać do innych czołgów! Jeśli strzela coś na mapie, może się zdarzyć.
- Jeśli zostanie wystrzelona ściana, zostanie zniszczona po pewnej liczbie strzałów, od 1 do 4
- Jeśli drzewo zostanie wystrzelone, zostanie natychmiast zniszczone
- Jeśli zostanie wystrzelona skała, strzał przejdzie nad nią i uszkodzi następną rzecz, w którą trafi
Gdy coś zostanie zniszczone, nie będzie go już na mapie (zostanie zastąpione niczym). Jeśli strzał zniszczy przeszkodę, zostanie ona zablokowana i nie uszkodzi niczego dalej na swojej drodze.
Dynamika czołgu
Każdy czołg zaczyna się od life
= 100. Każdy strzał w czołg zmniejsza się o 20-30 w life
zależności od odległości. Można to obliczyć za pomocą delta_life=-30+(shot_distance*10/diagonal_map_length)
(gdzie diagonal_map_length
jest (n-1)*sqrt(2)
). Dodatkowo każdy zbiornik regeneruje 1 life
na turę.
Okazuje
Zostanie przeprowadzona pewna liczba rund (zdecyduję, kiedy otrzymam zgłoszenia). Na początku każdej rundy losowo generowana jest mapa, na której umieszczane będą czołgi w losowo pustych miejscach. Podczas każdej rundy każdy czołg otrzyma turę w dowolnej kolejności. Po tym, jak każdy czołg otrzyma turę, otrzymają kolejność w tej samej kolejności. Runda trwa, dopóki nie zostanie tylko jeden czołg. Ten czołg będzie zwycięzcą i otrzyma 1 punkt. Gra przejdzie do następnej rundy.
Po rozegraniu wszystkich rund opublikuję wyniki dotyczące tego pytania.
Podczas tury czołgu może wykonać jedną z następujących czynności
- Poruszaj się maksymalnie o 3 spacje w jednym kierunku, poziomo lub pionowo. Jeśli zbiornik zostanie zablokowany przez przeszkodę lub inny czołg, zostanie przesunięty tak daleko, jak to możliwe, bez przechodzenia przez przeszkodę lub zbiornik.
- Strzelaj w określonym kierunku, reprezentowanym przez kąt zmiennoprzecinkowy w stopniach. Oś X lokalnej przestrzeni twojego czołgu (poziomo od lewej do prawej, czyli wschód lub
TurnAction.Direction.EAST
) wynosi 0 stopni, a kąty rosną przeciwnie do ruchu wskazówek zegara. Strzały są niedokładne, a rzeczywisty kąt strzału może być o 5 stopni większy lub mniejszy niż wybrany kąt. - Nic nie robić.
Tury nie są ograniczone w czasie, ale nie oznacza to, że możesz celowo tracić czas na rozłączanie wszystkiego.
Zgłoszenia / protokół
Każdy zgłoszony program będzie kontrolować jeden czołg na polu. Program sterujący jest w Javie, więc twoje programy na razie muszą być w Javie (prawdopodobnie w pewnym momencie napiszę opakowanie dla innych języków lub możesz napisać własny).
Twoje programy zaimplementują Tank
interfejs, który ma następujące metody:
public interface Tank {
// Called when the tank is placed on the battlefield.
public void onSpawn(Battlefield field, MapPoint position);
// Called to get an action for the tank on each turn.
public TurnAction onTurn(Battlefield field, MapPoint position, float health);
// Called with feedback after a turn is executed.
// newPosition and hit will be populated if applicable.
public void turnFeedback(MapPoint newPosition, FieldObjectType hit);
// Called when the tank is destroyed, either by another tank,
// or because the tank won. The won parameter indicates this.
public void onDestroyed(Battlefield field, boolean won);
// Return a unique name for your tank here.
public String getName();
}
Battlefield
Klasa zawiera 2D tablicę obiektów ( Battlefield.FIELD_SIZE
przez Battlefield.FIELD_SIZE
), która reprezentuje to, co na polu bitwy. Battlefield.getObjectTypeAt(...)
da FieldObjectType
dla obiektu w określonych współrzędnych (jeden FieldObjectType.ROCK
, FieldObjectType.TREE
, FieldObjectType.TANK
, FieldObjectType.WALL
, i FieldObjectType.NOTHING
). Jeśli spróbujesz wyciągnąć obiekt poza zasięg mapy (współrzędne <0 lub> = Battlefield.FIELD_SIZE
), wówczas IllegalArgumentException
zostanie wyrzucony znak „ an” .
MapPoint
to klasa do określania punktów na mapie. Użyj MapPoint.getX()
i, MapPoint.getY()
aby uzyskać dostęp do współrzędnych.
EDIT: Niektóre metody użytkowe zostały dodane: MapPoint.distanceTo(MapPoint)
, MapPoint.angleBetween(MapPoint)
, Battlefield.find(FieldObjectType)
, i TurnAction.createShootActionRadians(double)
jak sugeruje Wasmoo .
Więcej informacji można znaleźć w javadocs, patrz sekcja poniżej.
Wszystkie klasy (publiczne API) znajdują się w pakiecie zove.ppcg.tankwar
.
Program kontroli
Pełne źródło i javadocs programu sterującego i interfejsu API czołgu można znaleźć na moim repozytorium GitHub: https://github.com/Hungary-Dude/TankWarControl
Możesz wysyłać żądania ściągnięcia i / lub komentować, jeśli zobaczysz błąd lub chcesz poprawić.
Napisałem dwa programy przykładowych zbiorników RandomMoveTank
i RandomShootTank
(nazwa mówi wszystko).
Aby uruchomić swój czołg, dodaj swoją w pełni kwalifikowaną (nazwa pakietu + nazwa klasy) klasę czołgu tanks.list
(jedną klasę na linię), edytuj ustawienia w razie potrzeby w zove.ppcg.tankwar.Control
(opóźnienie skrętu, czy wyświetlać graficzną reprezentację pola itp.), i biegnij zove.ppcg.tankwar.Control
. Upewnij się, że na liście znajdują się co najmniej 2 czołgi, w przeciwnym razie wyniki są niezdefiniowane. (W razie potrzeby użyj zbiorników na próbki).
Twoje programy będą uruchamiane na moim komputerze w ramach tego programu sterującego. Po napisaniu dołączę link do źródła. Możesz sugerować zmiany w źródle.
Zasady
- Twoje zgłoszenia muszą być zgodne z powyższymi wytycznymi
- Twoje programy mogą nie uzyskiwać dostępu do systemu plików, sieci ani próbować atakować mojego komputera w jakikolwiek sposób
- Twoje programy nie mogą próbować wykorzystywać mojego programu kontrolnego do oszukiwania
- Bez trollingu (np. Celowe marnowanie programu na rozłączanie wszystkiego)
- Możesz mieć więcej niż jedno zgłoszenie
- Staraj się być kreatywny przy przesyłaniu zgłoszeń!
- Zastrzegam sobie prawo do dowolnego zezwalania lub niedozwolania programów
Powodzenia!
AKTUALIZACJA: Po naprawieniu błędu teleportacji na ścianie i wdrożeniu regeneracji, uruchomiłem bieżące zgłoszenia przez 100 rund zBattlefield.FIELD_SIZE = 30
AKTUALIZACJA 2: Dodałem nowe zgłoszenie, RunTank, po wygłupieniu z Groovy na trochę ...
Zaktualizowane wyniki:
+-----------------+----+
| RandomMoveTank | 0 |
| RandomShootTank | 0 |
| Bouncing Tank | 4 |
| Richard-A Tank | 9 |
| Shoot Closest | 19 |
| HunterKiller 2 | 22 |
| RunTank | 23 |
| Dodge Tank | 24 |
+-----------------+----+
Obecnie czołgi regenerują 1 życie na turę. Czy należy to zwiększyć?
MapPoint
„sx
ay
floats
? Nie powinnyints
?