Diese Herausforderung wurde von @HelkaHombas hervorragender Herausforderung " Red vs. Blue - Pixel Team Battlebots" inspiriert . Diese Herausforderung war wahrscheinlich die beste, die ich auf dieser Website gesehen habe. Je.
Meine Herausforderung ist immer noch sehr unterschiedlich, aber @HelkaHomba verdient Anerkennung für die Inspiration.
Überblick
Dies ist ein Team King-of-the-Hill, in dem Ihr Team gewinnt, indem alle Spieler in Ihrem Team am Leben sind. Mit anderen Worten, das letzte stehende Team gewinnt. Die Ziehungen werden wiederholt.
Du bist auf einem Brett. Sie kennen Ihre Position in der ersten Runde (Häkchen 0). Sie wissen auch, wer sich in Ihrer Nähe befindet:
In diesem Fall sind Sie ganz alleine (oder so, wie Sie denken) und niemand um Sie herum. Sie können umgebende Elemente im ersten Argument für Ihren ontick
Handler sehen. Mehr über die API später.
Dein Team
Ihr Team wird durch Ihre Benutzer-ID bestimmt. Um das herauszufinden, klicken Sie auf Ihr Profilbild:
Dann finden Sie Ihre Benutzer-ID in der Adressleiste:
Wenn es seltsam ist, bist du im blauen Team.
Wenn es gerade ist, bist du im roten Team.
Gern geschehen für die handgezeichneten Kreise.
Dein (Bot) Name
Der Name Ihres Bots beginnt mit dem ersten Buchstaben Ihres Teams ("r" oder "b"). Es muss mit dem regulären Ausdruck übereinstimmen /^(r|b)[A-Za-z_-]$/
. Ansonsten können Sie den Namen Ihres Bots auswählen. Bitte verwenden Sie kein bereits vorhandenes.
Beginnend
Die roten Spieler beginnen am oberen Rand der Karte und die blauen am unteren Rand. Beim ersten Häkchen (Turn) im environment
Parameter für die ontick
Funktion erhalten Sie spezielle Informationen . Ich empfehle das aufzubewahren. Einzelheiten finden Sie in der API.
Du bist dran
Die Reihenfolge der Runden ist anfangs zufällig, bleibt dann aber gleich.
Aktionen drehen
Du darfst nur eine Aktion pro Spielzug ausführen.
Bewegung
Wenn Sie umziehen möchten, rufen Sie
this.move(num)
die API auf.num
ist die Zelle, in die Sie verschieben möchten:Die relativen Positionen der Nummern, zu denen Sie verschieben können, werden in der globalen Konstante gespeichert
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Wenn Sie in eine Wand oder in einen anderen Spieler ziehen, passiert nichts.
Drehen
Zum Drehen rufst du an
this.rotate(num)
. Num ist die Richtung, in die Sie drehen möchten:Die Drehung ist absolut.
Töten
Wenn sich ein anderer Spieler (von einem anderen Team) in der Zelle befindet, der Sie gegenüberstehen, können Sie ihn anrufen
this.kill()
und töten. Wenn niemand da ist oder sie in Ihrem Team sind, hat dies nichts zu bedeuten. Beispiel:Wenn Sie zu gedreht werden,
0
können Sie Grün töten. Wenn Sie auf 1 gedreht sind, können Sie Blau töten. Wenn Sie auf 2 gedreht sind, können Sie Orange töten. Wenn Sie auf 3 gedreht sind, können Sie gelb töten.Bombe
Durch Bombenangriffe werden alle Spieler, einschließlich Sie und Ihre Teamkollegen, auf den 9 Feldern um Sie herum getötet. Beispiel:
Warum würdest du das jemals tun wollen? Kamikaze . Wenn sich in den 9 Zellen um Sie herum mehr Spieler in Ihrem Team befinden, als in Ihrem Team, könnten Sie eine Bombardierung in Betracht ziehen. (Ich schlage vor, Sie benachrichtigen zuerst Ihre Kameraden!)
Platziere eine Landmine
Dies schafft ein Todesfeld für andere, die nicht in Ihrem Team sind. Wenn Sie eine Landmine platzieren, bewegen Sie sich auch, damit Sie nicht darauf treten. Sie rufen an,
this.landMine(num)
wo num das Quadrat ist, zu dem Sie gehen möchten. Beispiel:Dann rufst du an
this.landMine(4)
:Siehst du das "M"? Es ist eine Landmine. Andere können es sehen ... vorerst. Jeder, auch diejenigen, die nicht zu Ihrem Team gehören, kann eine Landmine auf der Zecke sehen, auf der sie platziert ist. Aber nachdem das Häkchen vorbei ist, kann es niemand mehr sehen. Aber es wird explodieren, sobald ein Feind darüber läuft. Beispiel:
Blue hat deine Landmine in Bewegung gesetzt und BOOM! Du hast gerade einen weiteren Kill bekommen.
Für jede 2 Kills, die Sie erhalten (durch direkte Tötung oder Landminen), erhalten Sie 1 zusätzliche Landmine, die Sie platzieren müssen. Sie erhalten auch eine am Start.
Graben
Wenn Sie graben, suchen Sie nach Landminen in einem 5x5-Gebiet, das sich um Sie herum befindet. Dies zeigt nicht das Team des Bots, der die Landmine platziert hat. (Denken Sie daran, dass Sie nicht von einer Landmine getötet werden können, die von jemandem in Ihrem Team platziert wurde.) Wenn dies beispielsweise das Raster um Sie herum wäre:
Dann wäre der Rückgabewert von
this.dig()
:
[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]
Die Array-Indizes beginnen von links oben nach rechts unten und schließen sich nicht selbst ein:
Insgesamt gibt es 23, und ihre relativen Positionen werden in der globalen Konstante gespeichert 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]
]
Beachten Sie, dass Dig im Gegensatz zu Minen, die auf vorherigen Ticks platziert wurden, enthüllt aroundMe
.
Kommunikation
Wenn Sie mit jemandem sprechen möchten, rufen Sie an this.sendMessage(recipients, team, data)
. Die Daten können , was Sie wollen, und Sie können es schicken jemand Sie, auch die Spieler auf andere Teams wollen. Dies kann verwendet werden, um schlecht programmierte Bots auszutricksen, aber alle Spieler können sehen, wer eine Nachricht gesendet hat und in welchem Team sie sind.
Beispiel:
Sende etwas an einen Bot namens "redisbest":
this.sendMessage("redisbest", undefined, "Hi!");
Sende etwas an einen Bot namens "redisbest" und "blueiscool":
this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});
Sende etwas an das gesamte rote Team
this.sendMessage(undefined, "red", {hello: "red"});
Schicken Sie jedem etwas
this.sendMessage(undefined, "*", {hello: "everyone"});
Sende etwas an das gesamte rote Team und einen Bot namens "blueiscool":
this.sendMessage("blueiscool", "red", {hello: "bots"});
API
Ihr Code muss aus einem einzelnen Aufruf der createBot
Funktion bestehen. Nichts anderes. Beispielcode:
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
}
});
(Sie können diese kopieren und einfügen. Ändern Sie sie einfach für Ihr Team usw.)
Methoden
ontick(environment)
Wird gerufen, wenn Sie an der Reihe sind. Muss ein zurückgeben
Promise
, das in 1 Sekunde oder weniger aufgelöst wird, oder es wird ignoriert. Dies ist aus Performancegründen und hat den netten Nebeneffekt, dass der Tab nicht hängt.this
(wenn in ontick)landMines
Wie viele Landminen hast du noch? Je mehr Kills du hast, desto mehr Landminen bekommst du. Für jeweils 2 Bots, die Sie töten, erhalten Sie 1 weitere Landmine. Sie erhalten auch 1, um zu beginnen.direction
Die Richtung, in die Sie schauen.storage
Speicher, der zwischen Anrufen vononTick
und bestehen bleibtonMessage
. Ein leeres Objekt beim Start. Ändern Sie sie für jeden Zweck, stellen Sie jedoch sicher, dass es sich immer um ein Array oder Objekt handelt, um sicherzustellen, dass es ordnungsgemäß erhalten bleibt.move(num)
An die angegebene Position verschieben. Tut nichts, wenn ungültig. Siehe oben für Details.rotate(num)
In die angegebene Position drehen. Tut nichts, wenn ungültig. Siehe oben für Details.kill()
Tötet den Spieler, mit dem Sie konfrontiert sind, sofern er existiert und nicht zu Ihrem Team gehört. Siehe oben für Details.bomb()
Tötet jeden auf den 9 Feldern um dich herum, auch dich selbst.landMine(num)
Platziert eine Landmine dort, wo Sie sich befinden, und bewegt sich dann an die angegebene Position. Tut nichts wenn ungültignum
oder du hast keine mehr. Siehe oben für Details.dig()
Neu! Gibt eine Reihe von Informationen zu den Landminen in einem 5x5-Bereich um Sie herum zurück. Siehe oben für Details.sendMessage(recipients, team, data)
recipients
kann entweder ein einzelner Bot (String), ein Array von Bot oderundefined
/ seinnull
. An wen möchten Sie die Nachricht senden?team
ist eine Zeichenfolge des Teams, an das Sie die Nachricht senden möchten. Verwenden Sie"*"
diese Option , um eine Nachricht an alle zu senden.data
ist alles, was an eine JS-Funktion übergeben werden kann. Es wird an die Empfänger gesendet. Wenn es sich um ein Objekt oder Array handelt, wird es als Referenz übergeben , sodass Sie und der / die Empfänger dies speichernstorage
können. Änderungen am Objekt wirken sich auf beide Bot-Kopien aus. Beachten Sie, dass Empfänger, die entweder in der Liste der Bots, dem in der Zeichenfolge angegebenen genauen Bot oder einem Bot des von Ihnen angegebenen Teams aufgeführt sind, die Nachricht erhalten.
environment
Beim ersten Tick
x
: Die x-Position Ihres Spielersy
: Die y-Position Ihres SpielersgridWidth
: Die Breite des Gitters (in Zellen)gridHeight
: Die Höhe des Rasters (in Zellen)Bei allen Zecken
aroundMe
: Eine Reihe von Spielern und Landminen. Die Spieler sind Objekte, die aussehen{name: "bot name", team: "bot team"}
, und die Landminen sind{team: "team of bot who placed mine"}
. Die Indizes des Arrays:Beachten Sie, dass Landminen, die auf einem anderen als dem aktuellen Tick platziert sind, nicht angezeigt werden.
aroundMe
Beispiel:Angenommen, dies ist das Raster (Sie sind rot):
Ihr
aroundMe
wird so aussehen:
[
{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.
]
Die Indizes des Arrays werden hier erklärt:
Ihr Bot sieht dies effektiv:
onmessage(data, fromBot, fromTeam)
this
(wenn in onmessage)sendMessage(recipients, team, data)
Standardfunktion zum Senden von Nachrichten.storage
Standardspeicher.
data
Die vom Absender gesendeten Daten.fromPlayer
Der Spieler, von dem die Nachricht gesendet wurde.fromTeam
Das Team, von dem die Nachricht gesendet wurde.onkill()
this
(wenn in onkill)sendMessage(recipients, team, data)
Standardfunktion zum Senden von Nachrichten.
Praktische (konstante) globale Arrays:
threeByThree
:
[
[0, 1, 2],
[3, undefined, 4],
[5, 6, 7]
]
Nützlich zum Übergeben von Daten an die Verschiebungsfunktion sowie zum Interpretieren aroundMe
. Siehe oben.
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]
]
Nützlich für die this.dig()
Funktion im ontick
Handler.
Versuch es!
Der Controller wird aus Performancegründen von meinem Rechner auf localhost ausgeführt, aber Sie können den CodePen verwenden , um Ihren Bot zu testen.
Beachten Sie, dass Sie Ihren Code in die Konsole einfügen und drücken müssen, Enter
bevor Sie auf Ausführen klicken. Sie können beliebig viele Bots einfügen. Die "Test Bots" sind Beispiele, gegen die Sie testen können. Wenn Sie alle schlagen oder binden können, haben Sie mindestens einen anständigen Bot.
Einreichungen
Regeln
Regeln (vom Controller durchgesetzt)
- Ihr
ontick
Hauptcode darf nicht länger als 1 Sekunde dauern. Wir wollen nicht, dass Runden für immer dauern. Wenn Ihr Code länger als 1 Sekunde dauert, wird er gestoppt. - Wenn Sie versuchen, mehr als eine Aktion pro Spielzug auszuführen, oder eine ungültige Aktion ausführen (z. B.
this.move(-1)
oder in eine Wand eindringen), wird diese ignoriert. - Weitere könnten bald kommen ...
Regeln (von mir durchgesetzt, kann zu DQ führen)
- Schreiben Sie keine globalen Variablen ( Lesen ist in Ordnung ).
- Ihr Code muss in Nodejs funktionieren (falls der Controller auf Nodejs portiert ist),
JSON.parse(...)
ist also in Ordnung, ist es aberalert()
nicht. - Sie dürfen
createBot
den Controller in keiner Weise anrufen oder stören . - Verwenden Sie den Code eines anderen nicht ohne dessen Erlaubnis und ohne wesentliche Änderungen. Keine Nachahmer.
- Bitte keine Lücken!
- Weitere könnten bald kommen ...
Meine Bots
Hier sind einige Bots:
Dieser Bot wählt zufällig eine Aktion aus. Nun, es ist ein gewichteter Zufall, aber immer noch ziemlich zufällig. Wenn Sie diesen Bot töten können (es wird sich schließlich selbst töten, das zählt nicht), dann haben Sie mindestens einen anständigen Bot. Poste es und schau was passiert!
Meine Bots haben einen Namen, der mit "x" beginnt, und ein Team von "none". Sie können gerne einen Teil dieses Codes verwenden, aber bitte nehmen Sie zumindest einige Änderungen vor. Wenn Sie sich nicht die Mühe machen, mindestens eine Zahl zu ändern, werden Sie nicht gewinnen.
Formatieren Sie Ihre Einreichung
Bitte verwenden Sie dieses 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...
Feature Requests, Bugs, Fragen, etc?
Kommentiere unten! Bitte überprüfen Sie, ob dies bereits kommentiert wurde. Wenn es bereits einen gibt, stimme ihm zu.
Möchten Sie mit Ihrem Team sprechen?
Benutze die Chatrooms für Rot und Blau .
Sprache
Derzeit wird nur JS und etwas unterstützt, das mit JS kompiliert werden kann. Wenn Sie jedoch wissen, wie Sie andere Sprachen für die Arbeit mit Nodejs einsetzen können, würde ich den Controller gerne auf Nodejs portieren.
Schlussnoten
Strategie-Ideen
Helfen Sie Ihrem Team! Erstellen eines Bots, der einem anderen Bot helfen und zusammenarbeiten soll. Diese Strategie hat sich für die Red vs. Blue - Pixel Team Battlebots bewährt
Wiederholungssucher
Ich werde die am höchsten bewertete Antwort des Gewinnerteams akzeptieren. Denken Sie daran, dass frühere Antworten tendenziell mehr Stimmen erhalten, ihre Schwächen jedoch eher entdeckt und ausgenutzt werden.
Wenn Sie demnächst antworten, erhalten Sie möglicherweise das Kopfgeld von +100.