Wenn Sie jemals Spacewar gespielt haben! Weißt du, es war ein lustiges Spiel. Wenn Sie dies nicht getan haben, wissen Sie Folgendes: Es war (und ist) eines der allerersten und wichtigsten Computerspiele. Und es macht trotzdem Spaß! Der Klon, auf dem ich aufgewachsen bin, ist dieser , der anscheinend und leider nur Windows ist. Also habe ich es neu erstellt!
Das KotH wird hier gehostet: PPCG - Spacewar! König des Hügels . Ich ermutige Sie, als Mensch gegen mindestens einen anderen Bot zu spielen, um ein Gefühl dafür zu bekommen, wie das Spiel funktioniert.
Das Spiel
- Ein Frame entspricht 30 Millisekunden (also ungefähr 33 Frames pro Sekunde).
- Das Feld ist 800 Pixel breit und 600 Pixel hoch.
- Das Feld ist toroidal, was bedeutet, dass Raumschiffe und Raketen, die sich außerhalb des Feldes bewegen, auf der gegenüberliegenden Seite wieder erscheinen.
- Es gibt zwei Raumschiffe, rot und blau.
- Rot wird bei x = 50 und zufälligem y zwischen 50 (Feldhöhe - 50) Pixeln positioniert.
- Blau wird bei x = (Feldbreite - 50) und zufälligem y zwischen 50 (Feldhöhe - 50) Pixeln positioniert.
- Beide Flächen x = (Feldbreite) / 2.
- Die verfügbaren Steuerelemente sind:
- Drehen Sie sich nach links - 5 Grad pro Bild gegen den Uhrzeigersinn.
- Drehen Sie nach rechts - 5 Grad pro Bild im Uhrzeigersinn.
- Feuer-Rakete - bewegt sich mit zusätzlichen 10 Pixeln pro Bild zusätzlich zur Geschwindigkeit des Schiffes in die Richtung, in die das Schiff zeigt.
- Feuerwehrauto - beschleunigt das Raumschiff mit 0,30 Pixel pro Frame in die Richtung, in die das Raumschiff zeigt.
- In Hyperspace Jump teleportierst du dich zu zufälligen Koordinaten im Feld, mit einer Wahrscheinlichkeit von 25% zu explodieren. Diese zufälligen Koordinaten können auf der Sonne liegen.
- Die Höchstgeschwindigkeit für Schiffe beträgt 15 Pixel pro Bild bei Motorleistung und 40 Pixel pro Bild bei Schwerkraftverstärkung.
- Wenn der Motor schneller als 15 Pixel pro Bild fährt, ändert er möglicherweise nur die Richtung oder verlangsamt sich.
- In Bezug auf Raketen:
- Raketen bewegen sich in einer geraden Linie.
- Raketen dürfen mit einer maximalen Schussrate von 1 pro 0,1 Sekunden abgefeuert werden.
- Raketen haben eine Lebensdauer von 2,25 Sekunden.
- Schiffe haben jeweils maximal 20 Raketen.
- Raketen sind innerlich Punktpartikel.
- In der Mitte befindet sich eine Sonne, die für Ihr Schiff äußerst gefährlich ist. Der geringste Kontakt ist tödlich. Diese Sonne zerstört auch Raketen.
- Die Sonne hat Schwerkraft. Die resultierende Beschleunigung beträgt 5000 / (Abstand ^ 2) Pixel / Frame ^ 2, wobei der Abstand in Pixel angegeben ist. Raumschiffe und Raketen sind betroffen.
- Beide Schiffe haben drei Angriffszonen: die Nase, den linken und den rechten Flügel.
- Ein Schlag auf die Nase ist der sofortige Tod.
- Ein Treffer auf einem der beiden Flügel reduziert die Drehzahl und die Motorbeschleunigung des Raumschiffs um die Hälfte.
- Wenn beide Flügel zerstört sind, kann das Raumschiff nicht manövriert werden und kann nur Raketen abfeuern.
- Schiffe können miteinander kollidieren.
- Ein Nase-Nase-Aufprall ist für beide Schiffe tödlich.
- Ein Nasenflügelschlag zerstört den Flügel.
- Ein Flügelschlag zerstört beide Flügel.
- Tote Schiffe sind fest und gefroren, bis sie 1 Sekunde später explodieren.
- Nachdem mindestens ein Schiff gestorben ist, wird das Feld 3 Sekunden später zurückgesetzt. Bis dahin sind die Sonne und alle verbleibenden Raketen immer noch gefährlich.
Das ursprüngliche Spiel hat auch tödliche und unzerstörbare Asteroiden, aber ich werde diese nicht einschließen.
Die Regeln
- Ihr Bot muss in JavaScript geschrieben sein.
- Ihr Bot sollte seine Entscheidung auf ungefähr 10 Millisekunden beschränken. Wenn ich aufgrund Ihres Bots eine beständige Verzögerung feststelle , werde ich ihn disqualifizieren und Sie informieren, damit Sie ihn beheben können.
- Bots haben Zugriff auf Folgendes:
- Feldbreite und Feldhöhe
- Sonnenstand und Radius
- Position, Rotation, Geschwindigkeit, Form, Raketenbestand und Status im Hyperraum beider Schiffe
- Die Position und Geschwindigkeit aller Raketen
- Wenn Sie dazu aufgefordert werden, sollte Ihr Bot eine Liste von Zeichenfolgen zurückgeben.
- : Diese Strings sollten Sie eine der folgenden sein
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. Alle anderen Zeichenfolgen werden ignoriert. - Wenn Duplikate vorhanden sind, wird nur das erste vermerkt.
hyperspace
hat Vorrang vor allen anderen.turn left
undturn right
zur gleichen Zeit wird keine Wirkung haben.fire engine
hat keine Auswirkung, wenn das Schiff nur die Nase hat oder tot ist.fire missile
hat keine Auswirkung, wenn eine Rakete zu früh abgefeuert wurde.
- : Diese Strings sollten Sie eine der folgenden sein
- In Abweichung vom Üblichen kann Ihr Bot das Verhalten anderer Bots ausnutzen. Ich möchte ein Metaspiel fördern.
- Bots können nicht andere Bots emulieren. (Dh kein Gedankenlesen.)
- Bots dürfen keine Variablen setzen, die vom Spiel- und Physikcode verwendet werden. (Dh kein Schummeln.)
Details zur Bot-Implementierung
Ich werde Ihren Bot in einer eigenen JavaScript-Datei speichern, die automatisch mit dem Dateinamen enthalten ist bot_<name>.js
. Fügen Sie also keine Leerzeichen oder Zeichen ein, die dies oder die Benennung einer Funktion in JavaScript beeinträchtigen könnten. Das liegt daran, dass Sie die folgenden Funktionen definieren sollten: <name>_setup(team)
und <name>_getActions(gameInfo, botVars)
. Weiter unten auf der Seite gibt es Textbereiche für den Userbot , die Sie bearbeiten können, um Ihren Code zu testen.
<name>_setup(team)
Mit dieser Funktion können Sie alle Variablen definieren, die Sie beibehalten möchten. team
wird entweder "red"
oder sein "blue"
. Diese Funktion muss ein Objekt zurückgeben. Definieren Sie Variablen wie folgt:
var vars = {};
vars['example'] = "example";
return vars;
Dieses vars
Objekt wird an die andere Funktion übergeben:
<name>_getActions(gameInfo, botVars)
botVars
ist das Objekt, das von zurückgegeben wird <name>_setup(team)
. gameInfo
ist ein Objekt mit folgenden Variablen:
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
Ihr Bot hat vollen Zugriff auf diese. Ich bin mir ziemlich sicher, dass Sie darauf schreiben und die ursprünglichen Variablen nicht beeinflussen können, aber tun Sie es trotzdem nicht. Anmerkung zur Drehung: Schiffe zeigen in die + y-Richtung nach unten, sodass alles, was Sie mit dem Schiff ausrichten möchten, um 90 Grad versetzt sein muss. Die positive Drehung erfolgt ebenfalls im Uhrzeigersinn.
Diese Funktion muss eine Liste von Zeichenfolgen zurückgeben, die die Aktionen Ihres Bots darstellen. Zum Beispiel ["turn right","thrust"]
. Weitere Details dazu finden Sie im Abschnitt Regeln .
Zusätzliche Details
Sie können auch Folgendes verwenden:
LineIntersection(L1, L2)
L1 und L2 sind Zwei-Element-Arrays von Zwei-Element-Arrays. Das ist L1 := [[x1,y1],[x2,y2]]
und L2 := [[u1,v1],[u2,v2]]
. Diese Funktion berechnet den Schnittpunkt von zwei Linien und gibt diese: [[x,y], [a,b]]
. [x,y]
sind die Koordinaten des Schnittpunkts und [a,b]
sind ein Paar Verhältnisse, die ausdrücken, wie weit entlang jeder Linie der Schnittpunkt ist. Wie in, a = 0.25
würde bedeuten, dass der Schnittpunkt ein Viertel des Weges von [x1,y1]
nach ist [x2,y2]
, und ebenso für b
. Wenn es keine Schnittmenge gibt, wird ein leeres Array zurückgegeben.
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]]
};
Dies sind die Koordinaten der Schiffspolygone. Um das Abrufen der aktuellen Koordinaten zu vereinfachen, können Sie auch ...
getShipCoords(<color>)
getShipCoords("red")
Liefert die aktuellen Koordinaten der Eckpunkte von Rotes Schiff und ebenso für getShipCoords("blue")
und Blau. Diese Koordinaten sind in einer Liste wie folgt: [[x1,y1],[x2,y2],[x3,y3],...]
. Polygone sind implizit geschlossen, sodass zwischen dem ersten und dem letzten Koordinatenpaar eine Linie besteht.
Sie dürfen nicht auf andere Variablen oder Funktionen zugreifen oder diese ändern, die von dem Spiel / der Website verwendet werden. Und nenne deine Funktionen definitiv nicht gleich. Ich glaube nicht, dass dies ein Problem sein wird, aber wenn Ihr Bot den Spielcode bricht, ist dies eine Möglichkeit. Es werden keine Ausnahmen protokolliert oder abgefangen.
Gewinnen
- Jede Paarung von Bots muss mindestens 10 Mal in beide Richtungen gespielt werden. (Also mindestens 20 Spiele insgesamt.)
- Richten Sie die höchste Gewinn / Verlust - Verhältnisse haben insgesamt . Wenn Ihr Bot gegen einen anderen sehr gut abschneidet, aber gegen die anderen drei verliert, ist das nicht so gut wie gegen zwei zu gewinnen und gegen zwei zu verlieren (als allgemeine Faustregel).
- Für jeden Bot werden die Verhältnisse (Gewinne + 1) / (Verluste + 1) berechnet, dann werden der Mittelwert und die Standardabweichung dieser Verhältnisse berechnet. Ein höherer Mittelwert hat Priorität, und falls die Mittelwerte innerhalb einer Einheit voneinander liegen, hat die niedrigere Varianz Priorität.
- Die Wertung beginnt entweder in einer Woche ab heute oder nach drei Tagen ohne neue Einreichungen. Dies ist so, dass ich keine Paarung von Bots wiederholen muss.
Vor allem viel Spaß!
Bestenliste (08.01.2016, 05:15 Uhr):
# 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
Hinweis: Dies kann sich ändern, wenn ich mehr Spiele spiele. Außerdem stört mich die Reihenfolge der Ränge 9 bis 13, so dass ich die Bewertungsmethode anpassen kann, um der Intuition besser zu entsprechen, wie sie eingestuft werden sollten.
(Mittelwerte und Standardabweichungen wurden auf drei Dezimalstellen gerundet. Außerdem Hyper
sollte das HYPER
aber die Hervorhebung durcheinander bringen.: P)
LineIntersection
von nicht überlappenden Segmenten ein leeres Array zurückgegeben wird.