Si vous avez déjà joué à Spacewar! , vous savez que c'était un jeu amusant. Sinon, sachez ceci: c’était (et est) l’un des tout premiers et des plus importants jeux d’ordinateur. Et c'est toujours amusant! Le clone sur lequel j'ai grandi est celui-ci , qui n'est, apparemment et malheureusement, que sous Windows. Alors je l'ai recréé!
Le KotH est hébergé ici: PPCG - Spacewar! Roi de la colline . Je vous encourage à jouer en tant qu’être humain contre au moins un autre bot pour avoir une idée du fonctionnement du jeu.
Le jeu
- Une image correspond à 30 millisecondes (soit environ 33 images par seconde).
- Le champ mesure 800 pixels de large et 600 pixels de haut.
- Le champ est toroïdal, ce qui signifie que les vaisseaux spatiaux et les missiles qui se déplacent à l'extérieur du champ réapparaissent de l'autre côté.
- Il y a deux vaisseaux spatiaux, rouge et bleu.
- Le rouge est positionné à x = 50 et le y aléatoire entre 50 pixels (hauteur du champ - 50).
- Le bleu est positionné à x = (largeur de champ - 50) et y aléatoire entre 50 (hauteur de champ - 50) pixels.
- Les deux faces x = (largeur du champ) / 2.
- Les contrôles disponibles sont:
- Tournez à gauche - 5 degrés par image dans le sens antihoraire.
- Tourner à droite - 5 degrés par image dans le sens des aiguilles d'une montre.
- Missile anti-feu - parcourt 10 pixels supplémentaires par image, en plus de la vitesse du navire, dans la direction indiquée par celui-ci.
- Fire engine - accélère le vaisseau spatial à 0,30 pixel par image dans la direction indiquée par le vaisseau spatial.
- Saut hyperespace: téléporte sur des coordonnées aléatoires sur le terrain, avec 25% de chances d’exploser. Ces coordonnées aléatoires peuvent être au-dessus du soleil.
- La vitesse maximale des navires est de 15 pixels par image sous la puissance du moteur et de 40 pixels par image lorsque la gravité est renforcée.
- Lorsque la vitesse de déplacement dépasse 15 pixels par image, la poussée du moteur peut uniquement changer de direction ou ralentir.
- En ce qui concerne les missiles:
- Les missiles se déplacent en ligne droite.
- Les missiles peuvent être lancés à une cadence maximale de 1 toutes les 0,1 secondes.
- Les missiles ont une durée de vie de 2,25 secondes.
- Les navires ont chacun un maximum de 20 missiles.
- Les missiles sont des particules ponctuelles internes.
- Il y a un soleil au centre même qui est extrêmement dangereux pour votre navire. Le moindre contact est fatal. Ce soleil détruit aussi les missiles.
- Le soleil a la gravité. L'accélération résultante est de 5000 / (distance ^ 2) pixels / image ^ 2, où la distance est exprimée en pixels. Les vaisseaux spatiaux et les missiles sont touchés.
- Les deux navires ont trois zones d’attaque: le nez, l’aile gauche et l’aile droite.
- Un coup sur le nez est la mort instantanée.
- Un coup sur l'une ou l'autre aile réduit de moitié le taux de virage et l'accélération du moteur du vaisseau spatial.
- Si les deux ailes sont détruites, le vaisseau spatial ne peut pas être manœuvré et ne peut tirer que des missiles.
- Les navires peuvent entrer en collision les uns avec les autres.
- Un impact nez-nez est fatal pour les deux navires.
- Un impact de nez-aile détruit l'aile.
- Un impact d'aile détruit les deux ailes.
- Les navires morts sont solides et gelés jusqu'à ce qu'ils explosent 1 seconde plus tard.
- Après la mort d'au moins un navire, le champ est réinitialisé 3 secondes plus tard. Jusque-là, le soleil et tous les missiles restants sont toujours dangereux.
Le jeu original a aussi des astéroïdes mortels et indestructibles, mais je ne les inclurai pas.
Les règles
- Votre bot doit être écrit en JavaScript.
- Votre bot devrait limiter sa décision à environ 10 millisecondes. Si je remarque un décalage constant à cause de votre bot , je le disqualifie et vous le fais savoir afin que vous puissiez le réparer.
- Les robots auront accès aux éléments suivants:
- Largeur et hauteur du champ
- Position et rayon du soleil
- La position, la rotation, la vitesse, la forme, le stock de missiles et l'état dans l'hyperespace des deux navires
- La position et la vitesse de tous les missiles
- Lorsque vous y êtes invité, votre bot doit renvoyer une liste de chaînes.
- Ces chaînes devraient être l' un des éléments suivants:
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. Toute autre chaîne sera ignorée. - S'il y a des doublons, seul le premier sera noté.
hyperspace
a priorité sur tous les autres.turn left
etturn right
en même temps n'aura aucun effet.fire engine
n'aura aucun effet si le navire n'a que le nez ou est mort.fire missile
n'aura aucun effet si un missile a été tiré trop récemment.
- Ces chaînes devraient être l' un des éléments suivants:
- Contrairement à l'habitude, votre bot est autorisé à exploiter le comportement des autres robots. Je veux encourager un métagame.
- Les bots ne peuvent pas imiter d'autres bots. (Ie, pas de lecture de l'esprit.)
- Les robots ne peuvent définir aucune variable utilisée par le code du jeu et de la physique. (C'est-à-dire, pas de triche.)
Détails d'implémentation du bot
Je vais stocker votre bot dans son propre fichier JavaScript qui est automatiquement inclus, avec le nom du fichier bot_<name>.js
. Donc, ne mettez pas d'espaces ou de caractères qui pourraient interférer avec cela ou pour nommer une fonction en JavaScript. C'est parce que vous devez définir les fonctions suivantes: <name>_setup(team)
et <name>_getActions(gameInfo, botVars)
. Plus bas dans la page, il existe des zones de texte pour l' utilisateur , que vous pouvez modifier pour tester votre code.
<name>_setup(team)
Cette fonction vous permet de définir les variables que vous souhaitez conserver. team
sera soit "red"
ou "blue"
. Cette fonction doit retourner un objet. Définissez les variables comme suit:
var vars = {};
vars['example'] = "example";
return vars;
Cet vars
objet sera transmis à l'autre fonction:
<name>_getActions(gameInfo, botVars)
botVars
est l'objet renvoyé par <name>_setup(team)
. gameInfo
est un objet contenant les variables suivantes:
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
Votre bot a un accès complet à ceux-ci. Je suis sûr que vous pouvez leur écrire sans affecter les variables d'origine, mais ne le faites pas quand même. Remarque sur les rotations: les navires pointent dans la direction + y, vers le bas, de sorte que tout ce que vous souhaitez aligner sur le navire doit être décalé de 90 degrés. En outre, la rotation positive est dans le sens des aiguilles d'une montre.
Cette fonction doit renvoyer une liste de chaînes, représentant les actions de votre bot. Par exemple, ["turn right","thrust"]
. Plus de détails à ce sujet se trouvent dans la section Règles .
Détails supplémentaires
Vous pouvez également utiliser les éléments suivants:
LineIntersection(L1, L2)
L1 et L2 sont des tableaux à deux éléments de tableaux à deux éléments. C'est, L1 := [[x1,y1],[x2,y2]]
et L2 := [[u1,v1],[u2,v2]]
. Cette fonction calcule l'intersection de deux lignes et renvoie ceci: [[x,y], [a,b]]
. [x,y]
sont les coordonnées du point d'intersection et [a,b]
sont une paire de ratios qui expriment la distance le long de chaque ligne du point d'intersection. Comme dans, a = 0.25
cela signifierait que le point d'intersection est à un quart du chemin de [x1,y1]
à [x2,y2]
, et de même pour b
. S'il n'y a pas d'intersection, un tableau vide est renvoyé.
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]]
};
Ce sont les coordonnées des polygones des navires. Pour obtenir plus facilement les coordonnées actuelles, vous pouvez également utiliser ...
getShipCoords(<color>)
getShipCoords("red")
renverra les coordonnées actuelles des sommets du vaisseau de Red, ainsi que pour getShipCoords("blue")
et Blue. Ces coordonnées sont dans une liste comme ceci: [[x1,y1],[x2,y2],[x3,y3],...]
. Les polygones étant implicitement fermés, il y a une ligne entre la première et la dernière paire de coordonnées.
Vous ne pouvez pas accéder ni modifier aucune autre variable ou fonction utilisée par le jeu / site web. Et ne nommez pas vos fonctions de la même manière. Je ne prévois pas que ce sera un problème, mais si votre bot casse le code du jeu, c'est une possibilité. Il n'y a pas de journalisation ou de capture d'exceptions.
Gagnant
- Chaque paire de robots doit être jouée au moins 10 fois, dans les deux sens. (Donc, au moins 20 jeux au total.)
- Essayez d’obtenir les ratios de gains / pertes les plus élevés au total . Si votre bot réussit très bien contre un autre, mais perd contre les trois autres, ce n'est pas aussi bon que de gagner contre deux et de perdre contre deux (en règle générale).
- Pour chaque bot, les ratios (gains + 1) / (pertes + 1) seront calculés, puis la moyenne et l'écart type de ces ratios seront calculés. Une moyenne plus élevée sera prioritaire, et si les moyennes sont à moins d'une unité les unes des autres, la variance la plus faible aura la priorité.
- La notation commencera soit dans une semaine à compter d’aujourd’hui, soit après trois jours sans nouvelle soumission. C'est pour que je n'ai pas à répéter les paires de robots.
Surtout, amusez-vous!
Classement (2016-01-08 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
Note: Ceci est sujet à changement car je lance plus de jeux. De plus, l'ordre des rangs 9-13 me dérange, je peux donc modifier la méthode de notation pour mieux correspondre à l'intuition de la manière dont elle devrait être classée.
(Les moyennes et les écarts-types ont été arrondis à trois chiffres décimaux. De plus, cela Hyper
devrait être, HYPER
mais cela gâchera la mise en évidence.: P)
la source
LineIntersection
sur des segments ne se croisant pas renvoie un tableau vide.Réponses:
Helios
Ce bot est le centre de l'univers, ou du moins il le pense. La première chose qu'il fait est de corriger une grave erreur et de se placer au centre du système de coordonnées. Puis il tourne n'importe quoi autour de lui.
Il n'aime pas l'autre (faux) soleil, il essaie donc de s'en tenir à l'écart. De plus, il n'aime pas les autres robots, il tire donc dessus s'il est bien placé.
la source
SunAvoider
Celui-ci essaie juste de rester à l'écart du soleil. C’est tellement bien… jusqu’à ce qu’une ou deux ailes soient détruites, il ne faut en général qu’une question de temps avant qu’elle tombe.
la source
Cas particulier
Vole à toute vitesse loin du soleil vers le bord de la carte! Quand il se trouvera dirigé vers le soleil, il commencera à tirer tout en se tournant pour revenir au bord. Il entre également dans l'hyperespace lorsqu'il est sur le point de frapper le soleil.
la source
OrbitBot
N'a actuellement aucun ciblage
ou évitement de collision. Il essaie de tourner autour du soleil.Edit: passe maintenant dans l’hyperespace lorsque l’impact est imminent.
la source
Spasmes Droite
Le nom est assez descriptif. Choisit
turn right
avec une probabilité de 0,5,fire engine
avec une probabilité de 0,5 etfire missile
avec une probabilité de 0,8. Étonnamment difficile, principalement parce que c'est vraiment imprévisible.la source
RandUmmm
Ce défi avait besoin d'un bot aléatoire. Des points bonus pour les golfeuses?
la source
Ingénieur
Aime utiliser l'hyperespace en cas de danger. Pour voir sa véritable puissance, ouvrez la console de votre navigateur et tapez
overideHyperspace = 0;
. Si vous oubliez le point-virgule, vous obtiendrez l'ASI pour Noël.la source
Vaporiser et prier
Tire sauvagement dans toutes les directions. Ce n'est pas très efficace!
la source
Kamikaze
Pas très compétitif mais je pensais que ce serait amusant! Il vole tout droit vers son adversaire pendant le tir.
la source
UhhIDKWhatToCallThisBot
Juste des trucs aléatoires.
la source
OpposantDodger
LANCEZ-VOUS DE MON OPPOSANT !!!
Merci à user81655 pour du code!
la source
Espion
L'histoire
Le prototype de ce bot était un bot qui avait deux modes: le mode fou et le mode normal. Quand il était en mode fou, il restait là pendant un nombre constant de ticks. Il y avait une probabilité constante d'entrer en mode fou. Il a également hyperspacé quand il était près du soleil. En mode fou, il visait l'autre bot et tirait constamment. En mode normal, il s'est envolé de l'autre bot sans tirer.
J'ai peaufiné ce prototype pour qu'il soit en mode fou si et seulement si l'ennemi était suffisamment proche. Ensuite, j'ai eu une idée folle: et si cela restait seulement en mode fou? Après quelques expériences (j'ai ajouté que le bot se mettait à feu de manière aléatoire quand il était en mode normal), je trouvais un nouveau bot qui battait tous les bots sauf Helios. Ceci est mon code à la fin de ce processus, mais avant le nettoyage.
J'ai écrit tout mon bot dans le KotH textarea ou le JS Beautifier. (J'ai brièvement utilisé l'éditeur Atom lors du nettoyage - mais pour deux lignes de code similaires)
Le bot
Ce bot contient beaucoup de code emprunté à d'autres robots. Il retourne le code de Kamikaze pour qu’il fuie l’autre bot au lieu de s’exécuter sur l’autre, et il prend le code d’EdgeCase pour une accélération extrême quand il est proche du soleil.
Son arc némésis est Helios. C'est l'intrus et de longues conversations avec un martini.
Il s'enfuit de l'autre bot avec 70% de chances de tirer un missile et d'hyperspaces lorsqu'il est proche du soleil. Aussi simple que cela. Oui.
Edit: J'ai testé mon bot avec le nouveau code et il échoue pour tous les autres. Je travaille sur le réparer. Je viens de confirmer que ce n'est que pour mon nouveau bot.
Le code
Le misc
Remarque: j'ai peut-être cassé quelque chose lors du nettoyage du code car je n'ai pas testé le bot après le nettoyage du code.
C'est aussi bien meilleur que tous mes autres robots - il bat tous les autres, sauf Helios (edit) , SetCourseFor30Degrees et OrbitBot! Il est lié à SunAvoider.
Note latérale: Je suis horrible en javascript, je ne sais pas pourquoi.
la source
AttackAndComeBack
Au lieu de tourbillonner, il entre par le haut et sort par le bas (en revenant par le haut) en tirant très rapidement. Évite généralement le soleil.
la source
Pleine vitesse
Tire toujours les moteurs et les missiles sans jamais tourner. Parfois dure étonnamment longtemps avant de frapper le soleil.
la source
PanicAttack
A 50% de chances de tirer et 80% de chance de tourner à gauche; mais s'il ne tourne pas à gauche, il tournera à droite. Après avoir manqué de missiles, le temps finira par le faire s'arrêter à cause du soleil.
EDIT: Ajout d'une certaine logique pour ne pas tirer lorsque l'ennemi est en vie, car il pourrait être tué par ses propres missiles.
la source
DangitBobby
Bobby Hill se fiche de ce que les autres pensent de lui - il est plutôt content de balancer paresseusement sur le terrain et d'attendre patiemment que son adversaire s'essouffle avant de frapper comme un cobra "husky".
"C’est mon sac! Je ne vous connais pas!"
la source
Tireur d'élite
Je joue un peu avec la prédiction pour créer un robot tireur d’élite qui snipe ses ennemis. Mon javascript est trop volumineux pour tenir dans une réponse, donc voici un lien, bot_Sniper .
la source
SmartArrow
Comme Arrow, mais intelligent
la source
Kamikaze-
Aussi pas conçu pour être compétitif. Juste pour le fun. Il hyperspace à proximité du soleil et poursuit le joueur sans tirer de balles. C'est amusant de regarder ce bot chasser une version non armée de Spy, mais vous ne pouvez malheureusement pas avoir plus d'un utilisateur.
El'endia: jamais envisagé d'ajouter plus d'un userbot;)
Je viens de prendre le code de Kamikaze + et de me débarrasser de la partie tir de missile.
la source
MissilesPlusScore
Une idée étrange que je suis venu avec qui prend que la valeur absolue de la différence des scores et utilise une liste de coups dans une base aléatoire de la manière de jeu. Cela fonctionne bien contre les robots avec une stratégie mais échoue contre les tempêtes de missiles. Aussi mon premier roi-de-la-colline .
HYPER
HYPERSPACE IS COOL !!!!!!!!!!!!!!!!
CoordinateInfluence
Basé sur les coordonnées, étonnamment efficace:
la source
SetCourseFor30Degrees
Vous ne savez pas pourquoi le capitaine insiste si ardemment pour placer le navire sur une trajectoire de 30 degrés, mais bon, en tant qu'enseigne humble, qui devez-vous interroger? Au moins on vous a donné la permission d'éviter le soleil! Et vous êtes autorisé à tirer les missiles ... mais pas à les viser ...
la source
Flèche
Il suffit de chasser son ennemi, l'hyperespace lorsqu'il est en danger et inactif lorsque son ennemi est mort.
la source
Kamikaze +
Non conçu pour être compétitif. Juste pour le fun. Techniquement, c'est le contraire de Spy: chasser le joueur, hyper-espace à proximité du soleil, lancer un missile 70% du temps. Je veux juste voir KamikazePlus pourchasser Spy et Spy s'enfuyant comme un fou.
Essentiellement, je viens de prendre le code de Spy's et d’inverser «gauche» et «droite».
la source
overideHyperspace = 0;
; ils ne font que disparaître quand ils essaient de s’attaquer.