Se hai mai giocato a Spacewar! , sai che è stato un gioco divertente. Se non lo hai fatto, sappi questo: è stato (ed è) uno dei primissimi e più importanti giochi per computer. Ed è ancora divertente! Il clone su cui sono cresciuto è questo , che è, apparentemente e sfortunatamente, solo Windows. Così l'ho ricreato!
Il KotH è ospitato qui: PPCG - Spacewar! Il re della collina . Ti incoraggio a giocare come umano contro almeno un altro robot per avere un'idea di come funziona il gioco.
Il gioco
- Un frame è di 30 millisecondi (quindi circa 33 frame al secondo).
- Il campo è largo 800 pixel e alto 600 pixel.
- Il campo è toroidale, il che significa che le astronavi e i missili che si muovono fuori dal campo riappaiono sul lato opposto.
- Ci sono due astronavi, rosso e blu.
- Il rosso è posizionato su x = 50 e y casuale tra 50, (altezza del campo - 50) pixel.
- Il blu è posizionato su x = (larghezza del campo - 50) e y casuale tra 50, (altezza del campo - 50) pixel.
- Entrambe le facce x = (larghezza del campo) / 2.
- I controlli disponibili sono:
- Girare a sinistra - 5 gradi per fotogramma in senso antiorario.
- Girare a destra - 5 gradi per fotogramma in senso orario.
- Missile antincendio: viaggia a 10 pixel in più per fotogramma in aggiunta alla velocità della nave, nella direzione in cui puntava la nave.
- Autopompa antincendio: accelera l'astronave di 0,30 pixel per frame nella direzione in cui punta l'astronave.
- Salto nell'iperspazio: si teletrasporta su alcune coordinate casuali sul campo, con una probabilità del 25% di esplodere. Queste coordinate casuali possono essere in cima al sole.
- La velocità massima per le navi è di 15 pixel per frame sotto la potenza del motore e 40 pixel per frame quando potenziata per gravità.
- Quando si viaggia più velocemente di 15 pixel per frame, la spinta del motore può solo cambiare direzione o rallentare.
- Per quanto riguarda i missili:
- I missili viaggiano in linea retta.
- I missili possono essere lanciati alla velocità massima di 1 per 0,1 secondi.
- I missili hanno una durata di 2,25 secondi.
- Le navi hanno un massimo di 20 missili ciascuno.
- I missili sono particelle di punti internamente.
- Al centro c'è un sole estremamente pericoloso per la tua nave. Il minimo contatto è fatale. Questo sole distrugge anche i missili.
- Il sole ha gravità. L'accelerazione risultante è 5000 / (distanza ^ 2) pixel / frame ^ 2, dove la distanza è in pixel. Navi spaziali e missili sono interessati.
- Entrambe le navi hanno tre zone di attacco: il naso, l'ala sinistra e l'ala destra.
- Un colpo al naso è la morte istantanea.
- Un colpo su entrambe le ali riduce della metà la velocità di virata dell'astronave e l'accelerazione del motore.
- Se entrambe le ali vengono distrutte, l'astronave non può essere manovrata e può sparare solo missili.
- Le navi possono scontrarsi.
- Un impatto naso-naso è fatale per entrambe le navi.
- Un impatto al naso distrugge l'ala.
- Un impatto ala-ala distrugge entrambe le ali.
- Le navi morte sono solide e congelate fino a quando non esplodono 1 secondo dopo.
- Dopo la morte di almeno una nave, il campo viene ripristinato 3 secondi dopo. Fino ad allora, il sole e tutti i missili rimanenti sono ancora pericolosi.
Il gioco originale ha anche asteroidi mortali e indistruttibili, ma non includerò quelli.
Le regole
- Il tuo bot deve essere scritto in JavaScript.
- Il tuo bot dovrebbe limitare la sua decisione a circa 10 millisecondi. Se noto un ritardo costante a causa del tuo bot , lo squalificherò e ti farò sapere in modo da poterlo correggere.
- I robot avranno accesso a quanto segue:
- Larghezza e altezza del campo
- Posizione e raggio del sole
- Posizione, rotazione, velocità, forma, stock di missili e stato nell'iperspazio di entrambe le navi
- La posizione e la velocità di tutti i missili
- Quando richiesto, il bot dovrebbe restituire un elenco di stringhe.
- Queste stringhe dovrebbero essere uno dei seguenti:
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. Qualsiasi altra stringa verrà ignorata. - Se ci sono duplicati, verrà notato solo il primo.
hyperspace
ha la precedenza su tutti gli altri.turn left
eturn right
allo stesso tempo non avrà alcun effetto.fire engine
non avrà alcun effetto se la nave ha solo il naso o è morta.fire missile
non avrà alcun effetto se un missile è stato sparato troppo di recente.
- Queste stringhe dovrebbero essere uno dei seguenti:
- In cambio del solito, al tuo bot è permesso sfruttare il comportamento di altri robot. Voglio incoraggiare un metagame.
- I robot non possono emulare altri robot. (Vale a dire, nessuna lettura della mente.)
- I robot non possono impostare alcuna variabile utilizzata dal gioco e dal codice fisico. (Cioè, niente imbrogli.)
Dettagli di implementazione del bot
Conserverò il tuo bot nel suo file JavaScript che viene automaticamente incluso, con il nome del file bot_<name>.js
. Quindi non inserire spazi o caratteri che potrebbero interferire con questo o con la denominazione di una funzione in JavaScript. Questo perché dovresti definire le seguenti funzioni: <name>_setup(team)
e <name>_getActions(gameInfo, botVars)
. Più in basso nella pagina, esistono textareas per userbot , che è possibile modificare per testare il codice.
<name>_setup(team)
Questa funzione consente di definire tutte le variabili che si desidera persistere. team
sarà o "red"
o "blue"
. Questa funzione deve restituire un oggetto. Definire le variabili in questo modo:
var vars = {};
vars['example'] = "example";
return vars;
Questo vars
oggetto verrà passato all'altra funzione:
<name>_getActions(gameInfo, botVars)
botVars
è l'oggetto restituito da <name>_setup(team)
. gameInfo
è un oggetto contenente le seguenti variabili:
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
Il tuo bot ha pieno accesso a questi. Sono abbastanza sicuro che puoi scrivergli e non influenzare le variabili originali, ma non farlo comunque. Una nota sulle rotazioni: le navi puntano nella direzione + y, verso il basso, quindi tutto ciò che si desidera allineare con la nave deve essere spostato di 90 gradi. Inoltre, la rotazione positiva è in senso orario.
Questa funzione deve restituire un elenco di stringhe, che rappresentano le azioni del bot. Ad esempio ["turn right","thrust"]
,. Maggiori dettagli su questo sono nella sezione Regole .
dettagli aggiuntivi
È inoltre possibile utilizzare quanto segue:
LineIntersection(L1, L2)
L1 e L2 sono matrici a due elementi di matrici a due elementi. Cioè, L1 := [[x1,y1],[x2,y2]]
e L2 := [[u1,v1],[u2,v2]]
. Questa funzione calcola l'intersezione di due linee e restituisce questo: [[x,y], [a,b]]
. [x,y]
sono le coordinate del punto di intersezione ed [a,b]
è una coppia di rapporti che esprimono quanto lontano è lungo ogni linea il punto di intersezione. Come in, a = 0.25
significherebbe che il punto di intersezione è un quarto della strada da [x1,y1]
a [x2,y2]
, e allo stesso modo per b
. Se non c'è intersezione, viene restituita una matrice vuota.
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]]
};
Queste sono le coordinate dei poligoni delle navi. Per semplificare il recupero delle coordinate correnti, puoi anche utilizzare ...
getShipCoords(<color>)
getShipCoords("red")
restituirà le coordinate correnti dei vertici della nave di Red, e allo stesso modo per getShipCoords("blue")
e Blue. Queste coordinate sono in una lista in questo modo: [[x1,y1],[x2,y2],[x3,y3],...]
. I poligoni sono implicitamente chiusi, quindi esiste una linea tra la prima e l'ultima coppia di coordinate.
Non è possibile accedere o alterare altre variabili o funzioni in uso dal gioco / sito Web. E sicuramente non nominare le tue funzioni allo stesso modo. Non prevedo che questo sarà un problema, ma se il tuo bot rompe il codice di gioco, questa è una possibilità. Non vi è alcuna registrazione o rilevazione di eccezioni.
vincente
- Ogni abbinamento di robot deve essere giocato almeno 10 volte, in entrambi i modi. (Quindi, almeno 20 giochi in totale.)
- Cerca di avere il più alto rapporto vincite / perdite nel complesso . Se il tuo bot fa molto bene contro un altro bot, ma perde contro gli altri tre, non è buono come vincere contro due e perdere contro due (come regola generale).
- Per ogni bot, verranno calcolati i rapporti (vittorie + 1) / (perdite + 1), quindi verranno calcolate la media e la deviazione standard di questi rapporti. Una media più alta avrà la priorità e, nel caso in cui le medie siano entro 1 unità l'una dall'altra, la varianza inferiore avrà la priorità.
- Il punteggio inizierà tra una settimana da oggi o dopo tre giorni senza nuovi invii. Questo è quindi non devo ripetere l'associazione dei bot.
Soprattutto, buon divertimento!
Classifica (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
Nota: questo è soggetto a modifiche quando corro più giochi. Inoltre, l'ordinamento dei gradi 9-13 mi dà fastidio, quindi potrei modificare il metodo di punteggio per abbinare meglio la propria intuizione su come dovrebbero essere classificati.
(Le medie e le deviazioni standard sono state arrotondate a tre cifre decimali. Inoltre, Hyper
dovrebbe essere HYPER
ma ciò incasina l'evidenziazione.: P)
LineIntersection
su segmenti non intersecanti restituisce una matrice vuota.