Jeśli kiedykolwiek grałeś w Spacewar! , wiesz, że to była fajna gra. Jeśli nie, wiedz o tym: była to (i jest) jedna z pierwszych i najważniejszych gier komputerowych. I nadal jest fajnie! Klon, na którym dorastałem, to ten , którym najwyraźniej i niestety jest tylko Windows. Więc odtworzyłem to!
KotH jest tutaj: PPCG - Spacewar! King of the Hill . Zachęcam cię do gry jako człowiek przeciwko przynajmniej jednemu botowi, aby przekonać się, jak działa ta gra.
Gra
- Jedna klatka ma 30 milisekund (a więc około 33 klatek na sekundę).
- Pole ma szerokość 800 pikseli i wysokość 600 pikseli.
- Pole jest toroidalne, co oznacza, że statki kosmiczne i pociski, które poruszają się poza polem, pojawiają się ponownie po przeciwnej stronie.
- Istnieją dwa statki kosmiczne, czerwony i niebieski.
- Kolor czerwony jest ustawiony na x = 50, a losowy y między 50, (wysokość pola - 50) pikseli.
- Niebieski jest ustawiony na x = (szerokość pola - 50) i losowo y między 50, (wysokość pola - 50) pikseli.
- Obie ściany x = (szerokość pola) / 2.
- Dostępne elementy sterujące to:
- Skręć w lewo - 5 stopni na klatkę przeciwnie do ruchu wskazówek zegara.
- Skręć w prawo - 5 stopni na klatkę zgodnie z ruchem wskazówek zegara.
- Pocisk ognia - porusza się z dodatkowymi 10 pikselami na ramkę oprócz prędkości statku, w kierunku, w którym statek był skierowany.
- Wóz strażacki - przyspiesza statek kosmiczny z prędkością 0,30 pikseli na klatkę w kierunku, w którym wskazuje statek kosmiczny.
- Skok nadprzestrzenny - teleportuje się do losowych współrzędnych w polu, z 25% szansą na wybuch. Te losowe współrzędne mogą znajdować się nad Słońcem.
- Maksymalna prędkość dla statków wynosi 15 pikseli na klatkę przy mocy silnika i 40 pikseli na klatkę przy wzmocnieniu grawitacyjnym.
- Podczas jazdy z prędkością większą niż 15 pikseli na klatkę ciąg silnika może jedynie zmienić kierunek lub zwolnić.
- Jeśli chodzi o pociski:
- Pociski poruszają się w linii prostej.
- Pociski mogą być wystrzeliwane z maksymalną prędkością 1 na 0,1 sekundy.
- Pociski mają żywotność 2,25 sekundy.
- Statki mają maksymalnie 20 pocisków każdy.
- Pociski są wewnętrznie cząstkami punktowymi.
- W samym centrum jest słońce, które jest wyjątkowo niebezpieczne dla twojego statku. Najmniejszego kontaktu jest śmiertelne. To słońce niszczy również pociski.
- Słońce ma grawitację. Wynikowe przyspieszenie wynosi 5000 / (odległość ^ 2) pikseli / ramkę ^ 2, gdzie odległość jest w pikselach. Ma to wpływ na statki kosmiczne i pociski.
- Oba statki mają trzy strefy uderzenia: nos, lewe skrzydło i prawe skrzydło.
- Trafienie w nos to natychmiastowa śmierć.
- Trafienie w jedno ze skrzydeł zmniejsza prędkość obrotu statku kosmicznego i przyspieszenie silnika o połowę.
- Jeśli oba skrzydła zostaną zniszczone, statek kosmiczny nie będzie mógł manewrować i będzie mógł strzelać tylko pociskami.
- Statki mogą się ze sobą zderzać.
- Uderzenie nosa w nos jest śmiertelne dla obu statków.
- Uderzenie nosa w skrzydło niszczy skrzydło.
- Uderzenie skrzydła w skrzydło niszczy oba skrzydła.
- Martwe statki są solidne i zamrożone, aż wybuchną 1 sekundę później.
- Po śmierci co najmniej jednego statku pole resetuje się 3 sekundy później. Do tego czasu słońce i pozostałe pociski są nadal niebezpieczne.
Oryginalna gra ma również śmiertelne i niezniszczalne asteroidy, ale ich nie uwzględnię.
Zasady
- Twój bot musi być napisany w JavaScript.
- Twój bot powinien ograniczyć swoją decyzję do około 10 milisekund. Jeśli zauważę stałe opóźnienie z powodu twojego bota , zdyskwalifikuję go i dam znać, abyś mógł go naprawić.
- Boty będą miały dostęp do następujących elementów:
- Szerokość i wysokość pola
- Pozycja i promień słońca
- Pozycja, obrót, prędkość, kształt, zapas pocisków i status hiperprzestrzeni obu statków
- Pozycja i prędkość wszystkich pocisków
- Po wyświetleniu monitu bot powinien zwrócić listę ciągów znaków.
- Ciągi te powinny być jedną z następujących czynności:
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. Każdy inny ciąg zostanie zignorowany. - Jeśli są jakieś duplikaty, tylko pierwsza zostanie odnotowana.
hyperspace
ma pierwszeństwo przed wszystkimi innymi.turn left
iturn right
jednocześnie nie przyniesie żadnego efektu.fire engine
nie przyniesie żadnego efektu, jeśli statek ma tylko dziób lub jest martwy.fire missile
nie przyniesie efektu, jeśli pocisk został wystrzelony zbyt niedawno.
- Ciągi te powinny być jedną z następujących czynności:
- W odróżnieniu od zwykłego, twój bot może wykorzystywać zachowanie innych botów. Chcę zachęcić do gry metagame.
- Boty nie mogą emulować innych botów. (Tj. Brak czytania w myślach.)
- Boty nie mogą ustawiać żadnych zmiennych używanych przez grę i kod fizyki. (Tj. Bez oszukiwania.)
Szczegóły implementacji bota
Będę przechowywać twojego bota we własnym pliku JavaScript, który jest automatycznie dołączany wraz z nazwą pliku bot_<name>.js
. Nie umieszczaj więc spacji ani znaków, które mogłyby zakłócać to lub nazywanie funkcji w JavaScript. Jest tak, ponieważ powinieneś zdefiniować następujące funkcje: <name>_setup(team)
i <name>_getActions(gameInfo, botVars)
. W dalszej części strony znajdują się obszary tekstowe dla robota użytkownika , które można edytować w celu przetestowania kodu.
<name>_setup(team)
Ta funkcja służy do definiowania dowolnych zmiennych, które chcesz utrwalić. team
będzie albo "red"
albo "blue"
. Ta funkcja musi zwrócić obiekt. Zdefiniuj zmienne w następujący sposób:
var vars = {};
vars['example'] = "example";
return vars;
Ten vars
obiekt zostanie przekazany do innej funkcji:
<name>_getActions(gameInfo, botVars)
botVars
to obiekt zwrócony przez <name>_setup(team)
. gameInfo
to obiekt zawierający następujące zmienne:
redScore
blueScore
timeLeft
fieldWidth
fieldHeight
sun_x
sun_y
sun_r //sun's radius
gravityStrength //acceleration in pixels/frame^2 at 1 pixel away from the sun's center
engineThrust //acceleration in pixels/frame^2
speedLimit //maximum speed under engine power
maxSpeed //maximum speed from gravity boosts
red_x
red_y
red_rot //rotation in degrees
red_xv //x velocity
red_yv //y velocity
red_shape //one of "full ship", "left wing", "right wing", "nose only"
red_missileStock //the number of missiles red has left
red_inHyperspace //true if red is in hyperspace
red_exploded //until red explodes, it is still solid and hazardous
red_alive
// likewise for blue //
numMissiles
missiles //this is a list of objects, each with the following variables
x
y
xv
yv
Twój bot ma do nich pełny dostęp. Jestem pewien , że możesz do nich pisać i nie wpływać na oryginalne zmienne, ale i tak tego nie rób. Uwaga na temat rotacji: statki są skierowane w kierunku + y, w dół, więc wszystko, co chcesz wyrównać ze statkiem, musi być przesunięte o 90 stopni. Ponadto dodatni obrót odbywa się zgodnie z ruchem wskazówek zegara.
Ta funkcja musi zwrócić listę ciągów, reprezentujących działania twojego bota. Na przykład ["turn right","thrust"]
. Więcej informacji na ten temat znajduje się w sekcji Zasady .
Dodatkowe Szczegóły
Możesz także skorzystać z następujących opcji:
LineIntersection(L1, L2)
L1 i L2 są dwuelementowymi tablicami tablic dwuelementowych. To znaczy L1 := [[x1,y1],[x2,y2]]
i L2 := [[u1,v1],[u2,v2]]
. Funkcja ta oblicza punkt przecięcia dwóch prostych i zwraca to: [[x,y], [a,b]]
. [x,y]
są współrzędnymi punktu przecięcia i [a,b]
są parą stosunków, które wyrażają, jak daleko wzdłuż każdej linii znajduje się punkt przecięcia. Jak w, a = 0.25
oznaczałoby, że punkt przecięcia jest czwarta drogi od [x1,y1]
celu [x2,y2]
, a także dla b
. Jeśli nie ma przecięcia, zwracana jest pusta tablica.
window["shipShapes"]
var shipShapes = {
'full ship': [[-8,16],[0,-8],[8,16]],
'left wing': [[-8,16],[0,-8],[4,4],[0,8],[0,16]],
'right wing':[[-4,4],[0,-8],[8,16],[0,16],[0,8]],
'nose only': [[-4,4],[0,-8],[4,4],[0,8]]
};
Są to współrzędne wielokątów statków. Aby ułatwić uzyskanie bieżących współrzędnych, możesz również użyć ...
getShipCoords(<color>)
getShipCoords("red")
zwróci bieżące współrzędne wierzchołków statku Czerwonego, a także dla getShipCoords("blue")
i Niebieskiego. Współrzędne te są na liście tak: [[x1,y1],[x2,y2],[x3,y3],...]
. Wieloboki są domyślnie zamknięte, więc między pierwszą i ostatnią parą współrzędnych istnieje linia.
Nie możesz uzyskiwać dostępu ani zmieniać żadnych innych zmiennych lub funkcji używanych przez grę / stronę internetową. I zdecydowanie nie nazywaj swoich funkcji tak samo. Nie przewiduję, że będzie to problem, ale jeśli twój bot złamie kod gry, to jedna z możliwości. Nie ma rejestrowania ani wyłapywania wyjątków.
Zwycięski
- Każda para botów powinna być odtwarzana co najmniej 10 razy w obie strony. (Tak więc w sumie co najmniej 20 gier.)
- Staraj się osiągnąć najwyższy ogólny stosunek wygranych do przegranych . Jeśli twój bot radzi sobie bardzo dobrze przeciwko drugiemu botowi, ale przegrywa z pozostałymi trzema, nie jest to tak dobre, jak wygrywanie z dwoma i przegrywanie z dwoma (co jest ogólną zasadą).
- Dla każdego bota obliczone zostaną stosunki (wygrane + 1) / (straty + 1), a następnie obliczona zostanie średnia i odchylenie standardowe tych stosunków. Wyższa średnia będzie miała priorytet, a jeśli średnie będą w odległości 1 jednostki od siebie, niższa wariancja będzie miała priorytet.
- Punktacja rozpocznie się za tydzień od dzisiaj lub po trzech dniach braku nowych zgłoszeń. Jest tak, że nie muszę powtarzać żadnej pary botów.
Przede wszystkim baw się dobrze!
Tabela liderów (08.01.2016, 05:15):
# Name Mean StdDev
1. Helios 13.625 6.852
2. EdgeCase 8.335 8.155
3. OpponentDodger 8.415 8.186
4. OrbitBot 5.110 6.294
5. SunAvoider 5.276 6.772
6. DangitBobby 3.320 4.423
7. SprayAndPray 3.118 4.642
8. Engineer 3.903 6.315
9. RighthandedSpasms 1.805 2.477
10. AttackAndComeBack 2.521 2.921
11. PanicAttack 2.622 3.102
12. FullSpeedAhead 2.058 3.295
13. UhhIDKWhatToCallThisBot 2.555 3.406
14. MissilesPlusScore 0.159 0.228
15. Hyper 0.236 0.332
16. RandUmmm 0.988 1.329
17. Kamikaze 0.781 1.793
Uwaga: może to ulec zmianie, gdy uruchamiam więcej gier. Ponadto niepokoi mnie porządkowanie rang 9-13, więc mogę dostosować metodę punktacji, aby lepiej dopasować intuicję do tego, jak powinny być uszeregowane.
(Średnie i standardowe odchylenia zostały zaokrąglone do trzech cyfr dziesiętnych. Hyper
Powinno być, HYPER
ale to pomieszało podświetlanie.: P)
LineIntersection
na nie przecinających się segmentach zwraca pustą tablicę.