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)
źródło
LineIntersection
na nie przecinających się segmentach zwraca pustą tablicę.Odpowiedzi:
Helios
Ten bot jest centrum wszechświata, a przynajmniej tak mu się wydaje. Pierwszą rzeczą, którą robi, jest poprawienie poważnego błędu i umieszczenie się na środku układu współrzędnych. Potem obraca wszystko wokół siebie.
Nie lubi drugiego (fałszywego) słońca, dlatego stara się trzymać z dala od niego. Nie lubi też innych botów, dlatego strzela do nich, jeśli jest w dobrej pozycji do strzelania.
źródło
SunAvoider
Ten po prostu stara się trzymać z dala od słońca. Robi to całkiem nieźle ... dopóki nie zostanie zniszczone jedno lub oba skrzydła, wtedy zwykle jest to tylko kwestia czasu, zanim spadnie.
źródło
EdgeCase
Leci z pełną prędkością od słońca w kierunku krawędzi mapy! Kiedy zostanie skierowany w stronę słońca, zacznie strzelać, jednocześnie odwracając się, by wrócić na krawędź. Wchodzi również w nadprzestrzeń, gdy ma uderzyć w słońce.
źródło
OrbitBot
Obecnie nie ma możliwości celowania
ani unikania kolizji. Próbuje okrążyć słońce.Edycja: Teraz przechodzi w nadprzestrzeń, gdy nadciągają uderzenia.
źródło
Skurcze praworęczne
Nazwa jest dość opisowa. Wybiera
turn right
z prawdopodobieństwem 0,5, prawdopodobieństwemfire engine
0,5 ifire missile
prawdopodobieństwem 0,8. Zaskakująco trudne, głównie dlatego, że jest naprawdę nieprzewidywalne.źródło
RandUmmm
To wyzwanie wymagało losowego bota. Punkty bonusowe za golfa?
źródło
Inżynier
Lubi korzystać z hiperprzestrzeni, gdy jest w niebezpieczeństwie. Aby zobaczyć prawdziwą moc, otwórz konsolę przeglądarki i wpisz
overideHyperspace = 0;
. Jeśli zapomnisz średnika, dostaniesz ASI na Boże Narodzenie.źródło
SprayAndPray
Wystrzeliwuje dziko we wszystkich kierunkach. To nie jest bardzo skuteczne!
źródło
Kamikadze
Niezbyt konkurencyjny, ale pomyślałem, że będzie fajnie! Leci prosto w stronę przeciwnika podczas strzelania.
źródło
UhhIDKWhatToCallThisBot
Po prostu losowe rzeczy.
źródło
OpponentDodger
ODDAJ SIĘ OD MNIE PRZECIWNIKA !!!
Dzięki user81655 za trochę kodu!
źródło
Szpieg
Historia
Prototypem tego bota był bot, który miał dwa tryby: tryb szalony i tryb normalny. Gdy był w trybie szalonym, pozostawał tam przez stałą liczbę tyknięć. Prawdopodobieństwo przejścia w tryb szalony było stałe. Przesunął się też hiperprzestrzennie, gdy był blisko słońca. W trybie szalonym celował w drugiego bota i ciągle strzelał. W trybie normalnym odleciał od drugiego bota, nie strzelając.
Ulepszyłem ten prototyp, aby działał w trybie szalonym, gdyby tylko wróg był wystarczająco blisko. Potem wpadłem na szalony pomysł: co, jeśli pozostanie tylko w trybie szalonym? Po kilku eksperymentach (dodałem losowe uruchamianie bota, gdy był on w trybie normalnym), znalazłem nowego bota, który pokonał każdego bota oprócz Heliosa. To jest mój kod na koniec tego procesu, ale przed czyszczeniem.
Cały mój bot napisałem w obszarze tekstowym KotH lub upiększaczu JS. (Podczas czyszczenia użyłem krótko edytora Atom - ale dla dwóch linii kodu)
Bot
Ten bot zawiera dużo kodu zapożyczonego z innych botów. Odwraca kod z Kamikaze, aby uciec od drugiego bota zamiast biegać do drugiego bota, i pobiera kod z EdgeCase do hiperprzestrzeni, gdy jest blisko słońca.
Jego arch-nemezis to Helios. To dziwne i długie rozmowy z martini.
Ucieka od drugiego bota z 70% szansą na wystrzelenie pocisku i hiperprzestrzeni, gdy jest blisko słońca. Tak proste jak to. Tak.
Edycja: Przetestowałem mojego bota z nowym kodem i nie działa dla każdego innego bota. Pracuję nad naprawą. Właśnie potwierdziłem, że to tylko dla mojego nowego bota.
Kod
Misc
Uwaga: Mogłem coś zepsuć podczas czyszczenia kodu, ponieważ nie przetestowałem bota po wyczyszczeniu kodu.
Jest także o wiele znacznie lepszy niż wszystkie moje inne boty - faktycznie pokonał każdego innego bota oprócz Heliosa (edycja) , SetCourseFor30Degrees i OrbitBot! Wiąże się z SunAvoider.
Uwaga dodatkowa: Jestem okropny w javascript, nie wiem dlaczego.
źródło
AttackAndComeBack
Zamiast wirować, wchodzi na górę i wychodzi na dole (wraca na górę), strzelając bardzo szybko. Ogólnie unika słońca.
źródło
Cała naprzód
Zawsze odpala zarówno silniki, jak i pociski, nie obracając się nigdy. Czasami trwa zaskakująco długo przed uderzeniem w słońce.
źródło
Atak paniki
Ma 50% szansy na ostrzał i 80% szansy na skręt w lewo; ale jeśli nie skręci w lewo, skręci w prawo. Po tym, jak zabraknie pocisków, czas ostatecznie zatrzyma go z powodu słońca.
EDYCJA: Dodano trochę logiki, aby nie strzelać, gdy wróg żyje, ponieważ może zostać zabity przez własne pociski.
źródło
DangitBobby
Bobby Hill nie dba o to, co myślą o nim inni - jest zadowolony z tego, że leniwie kołysze się po boisku i cierpliwie czeka, aż jego przeciwnik wyczerpie się, zanim uderzy jak „husky” kobra.
„TO MOJA PRZEKŁADKA! NIE WIEM CIEBIE!”
źródło
Snajper
Przez pewien czas bawiłem się z przewidywaniami, aby stworzyć snajperskiego bota, który snajperuje jego wrogów. Mój javascript jest zbyt duży, aby zmieścił się w odpowiedzi, więc oto link, bot_Sniper .
źródło
SmartArrow
Jak Arrow, ale mądry
źródło
Kamikadze
Również nie zaprojektowany, aby być konkurencyjnym. Dla żartu. Nadprzestrzeń przesuwa się blisko słońca i goni gracza bez wystrzeliwania pocisków. Fajnie jest oglądać tego bota ścigającego nieuzbrojoną wersję Szpiega, ale niestety nie możesz mieć więcej niż jednego użytkownika.
El'endia: kiedykolwiek rozważałeś dodanie więcej niż jednego użytkownika;)
Właśnie wziąłem kod Kamikaze + i pozbyłem się części wystrzeliwującej pocisk.
źródło
MissilesPlusScore
Wymyśliłem jakiś dziwny pomysł, który zakłada, że bezwzględna wartość różnicy wyników i wykorzystuje listę ruchów w sposób losowy w oparciu o sposób gry. Działa dobrze przeciwko botom ze strategią, ale nie sprawdza się w przypadku burz pocisków. Także mój pierwszy król wzgórza .
HYPER
HYPERSPACE JEST CHŁODNE !!!!!!!!!!!!!!!!
CoordinateInfluence
Oparty na współrzędnych, zaskakująco skuteczny:
źródło
SetCourseFor30Degrees
Nie mam pojęcia, dlaczego kapitan tak bardzo nalega na ustawienie statku na kurs o 30 stopni, ale hej, jako mały chorąży, kogo masz pytać? Przynajmniej masz pozwolenie na unikanie słońca! I możesz strzelać z pocisków ... po prostu nie wolno ich celować ...
źródło
Strzałka
Po prostu ścigaj jego wroga, hiperprzestrzeń, gdy jest w niebezpieczeństwie, i bezczynnie, gdy jego wróg nie żyje.
źródło
Kamikaze +
Nie zaprojektowany, aby być konkurencyjnym.Dla żartu. Technicznie robi to odwrotnie niż Szpieg: ściga gracza, hiperprzestrzeń gdy jest blisko słońca, wystrzeliwuje pocisk w 70% przypadków. Po prostu chcę zobaczyć, jak KamikazePlus goni Szpiega i Szpiega uciekającego jak szaleniec.
Zasadniczo po prostu wziąłem kod Szpiega i przerzuciłem „w lewo” i „w prawo”.
źródło
overideHyperspace = 0;
; po prostu zaginęli, kiedy próbowali na siebie rzucić.