Ce défi a été inspiré par l 'excellent défi de @HelkaHomba , Red vs Blue - Pixel Team Battlebots . Ce défi était probablement le meilleur que j'ai vu sur ce site. Déjà.
Mon défi est toujours très différent, mais @HelkaHomba mérite le crédit de l'inspiration.
Présentation
Il s'agit d'une équipe roi de la colline où votre équipe gagne en ayant tous les joueurs en vie dans votre équipe. En d'autres termes, la dernière équipe debout gagne. Les tirages seront refaits.
Vous êtes sur un tableau. Vous connaissez votre position au premier tour (cochez 0). Vous savez également qui se trouve dans les environs:
Dans ce cas, vous êtes tout seul (ou du moins vous le pensez) sans personne autour de vous. Vous pouvez voir les éléments environnants dans le premier argument de votre ontick
gestionnaire. Plus d'informations sur l'API plus tard.
Ton équipe
Votre équipe est déterminée par votre ID utilisateur. Pour le savoir, cliquez sur votre photo de profil:
Trouvez ensuite votre ID utilisateur dans la barre d'adresse:
Si c'est étrange, vous faites partie de l'équipe bleue.
Si c'est égal, vous êtes dans l'équipe rouge.
Vous êtes les bienvenus pour les cercles dessinés à la main.
Votre nom (de bot)
Le nom de votre bot commence par la première lettre de votre équipe ("r" ou "b"). Il doit correspondre à l'expression régulière /^(r|b)[A-Za-z_-]$/
. En dehors de cela, vous pouvez choisir le nom de votre bot. Veuillez ne pas en utiliser un déjà existant.
Départ
Les joueurs rouges commenceront près du haut de la carte et le bleu commencera près du bas. On vous donne des informations spéciales sur la première coche (tour) dans le environment
paramètre de la ontick
fonction. Je recommande de stocker cela. Voir l'API pour plus de détails.
À votre tour
L'ordre du tour est initialement aléatoire, mais reste le même.
Actions de virage
Vous ne pouvez effectuer qu'une seule action par tour.
Bouge toi
Lorsque vous souhaitez déménager, vous appelez
this.move(num)
l'API.num
est la cellule vers laquelle vous souhaitez vous déplacer:Les emplacements relatifs des nombres vers lesquels vous pouvez vous déplacer sont stockés dans la constante globale
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Si vous vous déplacez dans un mur ou un autre joueur, rien ne se passe.
Tourner
Pour faire pivoter, vous appelez
this.rotate(num)
. Num est la direction que vous souhaitez faire pivoter:La rotation est absolue.
Tuer
Si un autre joueur (d'une autre équipe) se trouve dans la cellule à laquelle vous faites face, vous pouvez l'appeler
this.kill()
et le tuer. S'il n'y a personne là-bas, ou qu'ils sont dans votre équipe, cela ne fait rien. Exemple:Si vous êtes tourné vers
0
, vous pouvez tuer le vert. Si vous êtes tourné vers 1, vous pouvez tuer le bleu. Si vous êtes tourné vers 2, vous pouvez tuer l'orange. Si vous êtes tourné vers 3, vous pouvez tuer le jaune.Bombe
Le bombardement tue tous les joueurs, y compris vous et vos coéquipiers, dans les 9 cases autour de vous. Exemple:
Pourquoi voudriez-vous jamais faire ça? Kamikaze . S'il y a plus de joueurs qui ne font pas partie de votre équipe dans les 9 cellules autour de vous, alors qu'il y en a dans votre équipe, vous pourriez envisager de bombarder. (Je vous suggère de prévenir d'abord vos camarades!)
Placer une mine terrestre
Cela crée un carré de mort pour les autres personnes qui ne font pas partie de votre équipe. Lorsque vous placez une mine terrestre, vous vous déplacez également pour ne pas marcher dessus. Vous appelez
this.landMine(num)
où num est le carré où vous voulez aller. Exemple:Ensuite, vous appelez
this.landMine(4)
:Tu vois ce "M"? C'est une mine terrestre. D'autres peuvent le voir ... pour l'instant. Tout le monde, même ceux qui ne font pas partie de votre équipe, peut voir une mine terrestre sur la coche où elle est placée. Mais une fois cette tique terminée, personne, même vous ne pouvez la voir. Mais elle explosera dès qu'un ennemi la traversera. Exemple:
Blue s'est déplacé sur votre mine et BOOM! Vous venez de recevoir un autre kill.
Pour chaque 2 tués (tués directement ou mines terrestres), vous obtenez 1 mine supplémentaire à placer. Vous en obtenez également un au début.
Creuser
Lorsque vous creusez, vous recherchez des mines terrestres dans une zone 5x5 centrée autour de vous. Cela ne montre pas l'équipe du bot qui a placé la mine. (N'oubliez pas que vous ne pouvez pas être tué par une mine posée par un membre de votre équipe.) Par exemple, si c'était la grille autour de vous:
La valeur de retour de
this.dig()
serait alors:
[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]
Les index des tableaux commencent en haut à gauche, en allant vers la droite, puis vers le bas, sans vous inclure:
Il y en a 23 au total, et leurs emplacements relatifs sont stockés dans la constante globale fiveByFive
:
[
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, undefined, 12, 13],
[14, 15, 16, 17, 18],
[19, 20, 21, 22, 23]
]
Notez que creuser révèle des mines placées sur les tiques précédentes, contrairement aroundMe
.
la communication
Lorsque vous voulez parler à quelqu'un, vous appelez this.sendMessage(recipients, team, data)
. Les données peuvent être ce que vous voulez et vous pouvez les envoyer à qui vous voulez, même aux joueurs des autres équipes. Cela peut être utilisé pour tromper les bots mal programmés, mais tous les joueurs peuvent voir qui a envoyé un message et à quelle équipe ils appartiennent.
Exemple:
Envoyez quelque chose à un bot nommé "redisbest":
this.sendMessage("redisbest", undefined, "Hi!");
Envoyez quelque chose à un bot nommé "redisbest" et "blueiscool":
this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});
Envoyez quelque chose à toute l'équipe rouge
this.sendMessage(undefined, "red", {hello: "red"});
Envoyez quelque chose à tout le monde
this.sendMessage(undefined, "*", {hello: "everyone"});
Envoyez quelque chose à toute l'équipe rouge et un bot nommé "blueiscool":
this.sendMessage("blueiscool", "red", {hello: "bots"});
API
Votre code doit consister en un seul appel à la createBot
fonction. Rien d'autre. Exemple de code:
createBot({
ontick: function(environment) {
return new Promise((resolve, reject)=>{
this.move(0);//example
resolve();//please call this when you are done
});
},
onmessage: function(data, from, fromBot) {
console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
this.sendMessage(["bot", "otherbot"], "team", "some data");
},
team: "red",//your team
name: "rmyteamname",//team name must begin with the first letter of your team's name
onkill: function(){
//say goodbye
}
});
(Vous êtes libre de copier-coller ceci. Modifiez-le simplement pour votre équipe, etc.)
Les méthodes
ontick(environment)
Appelé quand c'est ton tour. Doit renvoyer un
Promise
qui se résout en 1 seconde ou moins sinon il sera ignoré. Ceci est pour des raisons de performances et a le bel effet secondaire de ne pas faire bloquer la tabulation.this
(quand en ontick)landMines
Combien de mines terrestres il vous reste. Plus vous en tuez, plus vous obtenez de mines terrestres. Pour chaque 2 robots tués, vous obtenez 1 mine supplémentaire. Vous obtenez également 1 pour commencer.direction
La direction à laquelle vous faites face.storage
Stockage qui persiste entre les appels versonTick
etonMessage
. Un objet vide au début. Modifiez pour n'importe quel but, mais assurez-vous qu'il s'agit toujours d'un tableau ou d'un objet pour vous assurer qu'il persiste correctement.move(num)
Déplacer vers la position spécifiée. Ne fait rien si invalide. Voir ci-dessus pour plus de détails.rotate(num)
Tournez à la position spécifiée. Ne fait rien si invalide. Voir ci-dessus pour plus de détails.kill()
Tue le joueur auquel vous êtes confronté, s'il existe et ne fait pas partie de votre équipe. Voir ci-dessus pour plus de détails.bomb()
Tue quiconque dans les 9 cases autour de vous, y compris vous-même.landMine(num)
Place une mine terrestre où vous vous trouvez, puis se déplace vers la position spécifiée. Ne fait rien si invalidenum
ou si vous n'en avez plus. Voir ci-dessus pour plus de détails.dig()
Nouveau! Renvoie un tableau d'informations sur les mines terrestres dans une zone 5x5 centrée autour de vous. Voir ci-dessus pour plus de détails.sendMessage(recipients, team, data)
recipients
peut être soit un seul bot (chaîne), un tableau de bot, ouundefined
/null
. C'est à qui vous souhaitez envoyer le message.team
est une chaîne de l'équipe à laquelle vous souhaitez envoyer le message. Utilisez"*"
pour envoyer un message à tout le monde.data
est tout ce qui peut être passé à une fonction JS. Il est envoyé aux destinataires. S'il s'agit d'un objet ou d'un tableau, il est transmis par référence , vous et le ou les destinataires pouvez donc l'enregistrer dans leurstorage
et toute modification de l'objet affecte les deux copies du bot. Notez que les bénéficiaires qui sont soit la liste des bots, le bot exact spécifié dans la chaîne, ou un bot sur l'équipe que vous avez indiqué, il recevra le message.
environment
Au premier tick
x
: Position x de votre joueury
: Position y de votre joueurgridWidth
: La largeur de la grille (en cellules)gridHeight
: La hauteur de la grille (en cellules)Sur toutes les tiques
aroundMe
: Un éventail de joueurs et de mines terrestres. Les joueurs sont des objets qui ressemblent{name: "bot name", team: "bot team"}
, et les mines terrestres le sont{team: "team of bot who placed mine"}
. Les index du tableau:Notez que les mines terrestres placées sur une tique autre que la actuelle ne seront pas affichées.
aroundMe
Exemple:Disons que c'est la grille (vous êtes rouge):
Votre
aroundMe
ressemblera à ceci:
[
{name: "bexamplebluebot", team: "blue"},
undefined,//sparse array, nothing in index 1
undefined,//there is technically a landmine here, but it wasn't placed this tick, so it is not shown
undefined,//nothing in 3
{name: "yexampleyellowbot", team: "yellow"},
{team: "red"},//this is a landmine, you can tell is not a bot because it has no name. mines have the team name of the player they were placed by. This mine was placed this tick, otherwise you couldn't see it
//nothing else after index 5, so the array's length is 5.
]
Les index du tableau sont expliqués ici:
Votre bot voit effectivement ceci:
onmessage(data, fromBot, fromTeam)
this
(en cas de message)sendMessage(recipients, team, data)
Fonction d'envoi de messages standard.storage
Stockage standard.
data
Les données envoyées par l'expéditeur.fromPlayer
Le joueur à partir duquel le message a été envoyé.fromTeam
L'équipe à partir de laquelle le message a été envoyé.onkill()
this
(quand onkill)sendMessage(recipients, team, data)
Fonction d'envoi de messages standard.
Tableaux globaux pratiques (constants):
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Utile pour transmettre des données à la fonction de déplacement ainsi que pour interpréter aroundMe
. Voir au dessus.
fiveByFive
:
[
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, undefined, 12, 13],
[14, 15, 16, 17, 18],
[19, 20, 21, 22, 23]
]
Utile pour la this.dig()
fonction du ontick
gestionnaire.
Essaye le!
Le contrôleur sera exécuté à partir de ma machine sur localhost pour des raisons de performances, mais vous pouvez utiliser le CodePen pour tester votre bot.
Notez que vous devez coller votre code dans la console et appuyer sur Enter
avant de cliquer sur exécuter. Vous pouvez coller autant de bots que vous le souhaitez. Les "bots de test" sont des exemples pour lesquels vous pouvez tester. Si vous pouvez les battre ou les attacher tous, vous avez au moins un bot décent.
Soumissions
Règles
Règles (appliquées par le contrôleur)
- Votre
ontick
code principal ne doit pas prendre plus d'une seconde. Nous ne voulons pas que les rondes durent éternellement. Si votre code prend> 1 seconde, il sera arrêté. - Si vous essayez de faire plus d'une action par tour, ou effectuez une action invalide (par ex.
this.move(-1)
Ou en vous déplaçant dans un mur), elle sera ignorée. - Plus peut arriver bientôt ...
Règles (appliquées par moi, peuvent entraîner un DQ)
- Ne pas écrire les variables globales ( lecture est très bien ).
- Votre code doit fonctionner dans Nodejs (au cas où le contrôleur est porté sur Nodejs), donc
JSON.parse(...)
c'est bien, mais cealert()
n'est pas le cas. - Vous n'êtes pas autorisé à appeler
createBot
ou à interférer avec le contrôleur de quelque manière que ce soit . - N'utilisez pas le code de quelqu'un d'autre sans autorisation et sans modifications importantes. Pas de copybots.
- S'il vous plaît, pas d'échappatoires!
- Plus peut arriver bientôt ...
Mes robots
Voici quelques bots:
Ce bot choisit au hasard une action. Eh bien, c'est un hasard pondéré, mais toujours assez aléatoire. Si vous pouvez tuer ce bot (il finira par se tuer, cela ne compte pas), alors vous avez au moins un bot décent. Affichez-le et voyez ce qui se passe!
Mes bots ont un nom commençant par "x" et une équipe de "aucun". Vous êtes invités à utiliser une partie de ce code, mais veuillez effectuer au moins quelques modifications. Si vous ne pouvez pas être dérangé au moins pour ajuster un nombre, vous ne gagnerez pas.
Formatage de votre soumission
Veuillez utiliser ce format:
# rmyamazingbot
createBot({
ontick: function(environment) {
return new Promise((resolve, reject)=>{
this.move(0);//example
resolve();//please call this when you are done
});
},
onmessage: function(data, fromTeam, fromBot) {
console.log("onMessage: " + this.name + " from " + this.team + " got message ", data, " from " + from + ", on team " + fromTeam);
this.sendMessage(["bot", "otherbot"], "team", "some data");
},
team: "red",//your team
name: "rmyteamname",//team name must begin with the first letter of your team's name
onkill: function(){
//say goodbye
}
});
Long, but cool explanation...
Demandes de fonctionnalités, bugs, questions, etc.?
Commentaires ci-dessous! Veuillez vérifier s'il y a déjà un commentaire à ce sujet. S'il y en a déjà un, votez-le.
Vous voulez parler à votre équipe?
Utilisez les salles de chat pour le rouge et le bleu .
La langue
Actuellement, seuls JS et quelque chose qui se compile en JS sont pris en charge, mais si vous connaissez un moyen de faire fonctionner d'autres langues avec Nodejs, je serais heureux de porter le contrôleur sur Nodejs.
Notes finales
Idées de stratégie
Aidez votre équipe! Créer un bot conçu pour aider un autre bot et travailler ensemble. Cette stratégie a bien fonctionné pour Red vs. Blue - Pixel Team Battlebots
Demandeurs de représentants
J'accepterai la réponse votée la plus élevée de l'équipe gagnante. Gardez à l'esprit que les réponses antérieures ont tendance à obtenir plus de votes, mais leurs faiblesses sont plus susceptibles d'être trouvées et exploitées.
De plus, si vous répondez rapidement, vous pourriez obtenir la prime de +100.