Team von The Hill!

27

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 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:

Ein einzelnes rotes Quadrat in einem 9x9-Raster, umgeben von weißen Zellen.

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 ontickHandler 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:

Mein Profilbild

Dann finden Sie Ihre Benutzer-ID in der Adressleiste:

Es ist zwischen / users / und / yourusername

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 environmentParameter für die ontickFunktion 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. numist die Zelle, in die Sie verschieben möchten:

    0 ist oben links, 1 ist oben in der Mitte, 2 ist oben rechts, 3 ist Mitte rechts, 4 ist Mitte links, 5 ist unten links, 6 ist unten in der Mitte und 7 ist unten rechts.

    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:

    0 ist oben, 1 ist rechts, 2 ist unten und 3 ist links

    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:

    Gleiche Zahlen wie oben, die 0-Zelle ist grün, die 1 ist blau, die 2 ist orange und die 3 ist gelb

    Wenn Sie zu gedreht werden, 0kö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:

    In jeder Zelle befindet sich ein 9x9-Raster mit "x".

    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:

    Ein einzelnes rotes Quadrat in einem 9x9-Raster, umgeben von weißen Zellen.

    Dann rufst du an this.landMine(4):

    [Ein 9x9-Raster mit einem roten "M" in der Mitte und einem roten Feld in der Mitte rechts.

    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:

    Zwei 9x9-Gitter, eine blaue Zelle in der Mitte links in der ersten, ein rotes "M" in der Mitte der ersten, ein rotes "x" in der Mitte der zweiten und ein Pfeil dazwischen.

    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 createBotFunktion 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 von onTickund bestehen bleibt onMessage. 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ültig numoder 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) recipientskann entweder ein einzelner Bot (String), ein Array von Bot oder undefined/ sein null. An wen möchten Sie die Nachricht senden? teamist eine Zeichenfolge des Teams, an das Sie die Nachricht senden möchten. Verwenden Sie "*"diese Option , um eine Nachricht an alle zu senden. dataist 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 speichern storagekö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 Spielers
  • y: Die y-Position Ihres Spielers
  • gridWidth: 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:

    0 ist oben links, 1 ist oben in der Mitte, 2 ist oben rechts, 3 ist Mitte rechts, 4 ist Mitte links, 5 ist unten links, 6 ist unten in der Mitte und 7 ist unten rechts.

    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):

    Ein 9x9-Raster, mit hellblau oben links, einem grauen "M" oben rechts, rot in der Mitte, gelb in der Mitte links und einem roten "M" unten links.

    Ihr aroundMewird 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:

0 ist oben links, 1 ist oben in der Mitte, 2 ist oben rechts, 3 ist Mitte rechts, 4 ist Mitte links, 5 ist unten links, 6 ist unten in der Mitte und 7 ist unten rechts.

Ihr Bot sieht dies effektiv:

Ein hellblaues Kästchen oben links mit der schwarzen Zahl 0, ein gelbes Kästchen am linken Rand mit der schwarzen Zahl 4 und ein rotes "M" unten links mit der schwarzen Zahl 5.

  • onmessage(data, fromBot, fromTeam)

    this (wenn in onmessage)

    • sendMessage(recipients, team, data) Standardfunktion zum Senden von Nachrichten.
    • storage Standardspeicher.

    dataDie vom Absender gesendeten Daten. fromPlayerDer Spieler, von dem die Nachricht gesendet wurde. fromTeamDas 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 ontickHandler.

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, Enterbevor 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 ontickHauptcode 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 aber alert()nicht.
  • Sie dürfen createBotden 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.

programmer5000
quelle
1
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Dennis
Darf ich mehr als einen Bots machen? (Entschuldigung, ich weiß, dass die Unterhaltung verschoben wurde, ich bin nur gesperrt, also ja)
Matthew Roh
@SIGSEGV ja, aber jemand anderes muss es posten. Sie können einen Bot posten und jemandem in Ihrem Team den Code eines anderen geben, aber Sie können nicht zweimal posten.
programmer5000
Wo befindet sich die mit [0, 0] indizierte Zelle? Ist dies die Zelle oben links? Verbraucht Messaging auch Ihre Aktion (pro Runde)? Vielen Dank.
Thrax
@Thrax ja und nein. Sie können sogar als Antwort auf eine Nachricht eine Nachricht senden.
programmer5000

Antworten:

7

xscared (nicht konkurrierend)

createBot({
    ontick: function(environment) {
        var reverse = [0, 1, 2, 3, 4, 5, 6, 7].reverse();
        return new Promise((resolve, reject)=>{
            (this.aroundMe || []).forEach((item,idx)=>{
                this.move(reverse[idx]);
                return resolve();
            });
            this.move(~~(Math.random() * 8));
            return resolve();
        });
    },
    onmessage: function() {
    },
    team: "none",
    name: "xscared",
    onkill: function(){
    }
});

Sehr ängstlich vor Menschen. Geht weg von der ersten Person (oder Landmine), die es sieht. Ansonsten bewegt es sich zufällig. Beachten Sie, dass dies kein Wettbewerb ist, sondern nur ein Beispiel. Versuchen Sie es zu schlagen!

programmer5000
quelle
6

Backup, ein blauer Bot

Wie im Chat gewarnt, habe ich in meinem Leben noch nie etwas in Javascript geschrieben. Wenn Sie also einen Fehler finden, sagen Sie es mir bitte! (Dank an @ programmer5000, der mir bereits dabei geholfen hat)
Das Konzept dieses Bots ist, dass er mit anderen Bots desselben Teams kommuniziert und ihnen seine Position zusammen mit einer Karte der gefundenen Minen sendet. Es versucht, sich dem nächsten blauen Bot anzuschließen (wenn man seine Positionsdaten sendet [als [x, y] -Array angegeben]) und bleibt in der Nähe (so weit wie möglich mit dem Rücken dazu), tötet sich nähernde rote Bots oder schaut voraus für Minen.

createBot({
    team: 'blue',
    name: 'backup',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});
Plannapus
quelle
Hey, es ist dir egal, ob ich das auch eingebe, aber (mit anderem Namen) ich bin auch auf blau
Christopher
@Christopher Nein, es macht mir nichts aus, aber das wäre ein bisschen interessanter für dich und das Team, wenn du einen zumindest ein bisschen anders machst (zumindest um die 2 Bots zu ergänzen, die bereits existieren).
Plannapus
Wird das machen. Ich werde es ändern
Christopher
Wenn ich versuche, Ihren Bot in Codepen auszuführen, funktioniert es nicht, weil Sie this.xusw. verwenden, aber es ist environment.xoder irre ich mich?
WasteD
@WasteD Wie gesagt, ich kenne kein Javascript, also ist es möglich. Aber wenn es so ist, dann sollte es wohl auch so sein environment.gridHeightund environment.aroundMe? In diesem Fall sollten die anderen Bots ebenfalls nicht funktionieren, da sie verwendet werden this.aroundMe.
Plannapus
5

Blau, blau, meine Welt ist blau

createBot({
    team: 'blue',
    name: 'blue-blue-my-world-is-blue',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            var red = 0;
            // See who's around me
            (this.aroundMe || []).forEach((item, idx) => {
                if (item && item.team == 'red') red++;
            });
            // If surrounded, take one for the team
            if (red >= 6) this.bomb();
            else {
                // Translate direction into position
                var kill = [1, 4, 6, 3][this.direction];
                // Random values
                var move = Math.floor(Math.random() * 8);
                var nsew = Math.floor(Math.random() * 4);
                // Lay a landmine if possible
                if (this.landMines) this.landMine(move);
                // Kill if someone is in the way
                else if (this.aroundMe && this.aroundMe[kill] && this.aroundMe[kill].team == 'red' && this.aroundMe[kill].name) this.kill();
                else {
                    // Move somewhere if already in the requested direction
                    if (nsew == this.direction) this.move(move);
                    // Otherwise just rotate to the requested direction
                    else this.rotate(nsew);
                }
            }
            resolve();
        });
    },
    onmessage: function(data, from, fromBot) {},
    onkill: function() {}
});

Meistens zufällig, wird aber bombardiert, wenn er umzingelt ist.


quelle
Clever! Schön.
programmer5000
3
Hör zu, hier ist eine Geschichte über einen kleinen Kerl, der in einer blauen Welt lebt.
Matthew Roh
3

Entspannter Bomber

Dieser Bot sucht nach einem Platz mit mindestens 1 freien Zelle auf jeder Seite und pflanzt dann eine Mine. Es lagert darauf, bis sich ein Feind nähert. Wenn sich jemand nähert, geht er auf seiner Mine hin und her, um den anderen Bot darauf anzulocken. Er wird sich auch drehen und töten, wenn nötig. Wenn er keine Mine mehr hat, sucht er Zuflucht in der oberen linken Ecke mit dem Rücken zur Wand und rächt sich, wenn er bedroht wird.

Hier gibt es kein besonderes Teamplay, abgesehen davon, dass er seine Position mit einem selfKeyword an sein Team überträgt .

createBot({
    team: 'red',
    name: 'relaxed-bomber',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            if (typeof this.storage['dropped'] == "undefined") {
                this.storage['dropped'] = false;
                this.storage['covered'] = false;
                this.storage['baited'] = false;
            }
            if (typeof environment.x != "undefined" && typeof environment.y != "undefined") {
                this.storage['pos'] = [environment.x, environment.y];
            }
            if (typeof environment.gridWidth != "undefined" && typeof environment.gridHeight != "undefined") {
                this.storage['grid'] = [environment.gridWidth, environment.gridHeight];
            }
            var x = this.storage['pos'][0];
            var y = this.storage['pos'][1];
            var x0 = this.storage['grid'][0];
            var y0 = this.storage['grid'][1];
            var source = [1, 4, 6, 3];
            var dest = [6, 3, 1, 4];
            var rot = [0, 1, 2, 3];
            var movex = [-1, 0, 1, -1, 1, -1, 0, 1];
            var movey = [-1, -1, -1, 0, 0, 1, 1, 1];
            var action = false;
            if (this.landMines > 0) { 
                var move = [false, false, false, false];
                var moveIndex = -1;
                if (x <= 0) { move[1] = true; }
                if (x >= x0 - 1) { move[3] = true; }
                if (y <= 0) { move[2] = true; }
                if (y >= y0 - 1) { move[0] = true; }    
                if (move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 0; }
                if (move[0] && !move[1] && !move[2] && !move[3]) { moveIndex = 1; }
                if (move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 2; }
                if (!move[0] && !move[1] && !move[2] && move[3]) { moveIndex = 3; }
                if (!move[0] && move[1] && !move[2] && !move[3]) { moveIndex = 4; }
                if (!move[0] && !move[1] && move[2] && move[3]) { moveIndex = 5; }
                if (!move[0] && !move[1] && move[2] && !move[3]) { moveIndex = 6; }
                if (!move[0] && move[1] && move[2] && !move[3]) { moveIndex = 7; }  
                if (moveIndex >= 0) {
                    this.storage['pos'] = [ x + movex[moveIndex], y + movey[moveIndex]];
                    this.move(moveIndex);
                } else {
                    this.storage['dropped'] = true;
                    this.storage['covered'] = false;
                    this.landMine(1);
                }
            } else {
                if (this.storage['dropped']) {
                    this.storage['dropped'] = false;
                    this.storage['covered'] = true;
                    this.storage['pos'] = [ x + movex[6], y + movey[6]];
                    this.move(6);
                } else if (this.storage['covered']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            this.storage['covered'] = false;
                            this.storage['baited'] = true;
                            this.storage['mine'] = this.storage['pos'].slice();
                            this.storage['reverse'] = source[dest[i]];
                            this.storage['pos'] = [ x + movex[dest[i]], y + movey[dest[i]]];
                            this.move(dest[i]);
                            action = true;
                        }
                    }
                    if (!action) {
                        this.dig();
                    }
                } else if (this.storage['baited']) {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (this.storage['mine'][0] == this.storage['pos'][0] && this.storage['mine'][1] == this.storage['pos'][1]) {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = source[this.storage['reverse']];
                        } else {
                            this.storage['pos'] = [ x + movex[this.storage['reverse']], y + movey[this.storage['reverse']]];
                            this.move(this.storage['reverse']);
                            this.storage['reverse'] = dest[this.storage['reverse']];
                        }
                    }
                } else {
                    for (var i = 0; i < source.length; i++) {
                        if (typeof environment.aroundMe[source[i]] != "undefined" && typeof environment.aroundMe[source[i]].team != "undefined" && environment.aroundMe[source[i]].team == "blue" && typeof environment.aroundMe[source[i]].name != "undefined") {
                            if (this.direction == rot[source[i]]) {
                                this.kill();
                                this.storage['baited'] = false;
                                action = true;
                            } else {
                                this.rotate(rot[source[i]]);
                                action = true;
                            }
                        }
                    }
                    if (!action) {
                        if (x > 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[0], y + movey[0]];
                            this.move(0);
                        } else if (x > 0 && y == 0) {
                            this.storage['pos'] = [ x + movex[3], y + movey[3]];
                            this.move(3);
                        } else if (x == 0 && y > 0) {
                            this.storage['pos'] = [ x + movex[1], y + movey[1]];
                            this.move(1);
                        } else {
                            this.rotate(1);
                        }
                    }
                }
            }
            this.sendMessage(undefined, "red", {'self': this.storage['pos'] });
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {},
    onkill: function() {}
});
Thrax
quelle
In welchem ​​Team bist du?
programmer5000
@ programmer5000 Da die Namen der Bots mit dem Buchstaben des Teams beginnen müssen, denke ich, dass ich Team Red bin :)
Thrax
Netter Bot! Ich schlage vor, dass Sie Ihrem Team auch mitteilen, was um Sie herum ist.
programmer5000
1

1 weiteren blauen Bot sichern (vorher vergessen)

createBot({
    team: 'blue',
    name: 'backup1',
    ontick: function(environment) {
        return new Promise((resolve, reject) => {
            //if (typeof this.x != "undefined") this.storage['position'] = [this.x, this.y];
            if (typeof environment.x != "undefined") this.storage['position'] = [environment.x, environment.y]; //Modified according to @WasteD
            if (typeof this.storage['map'] == "undefined") { //Create empty map
                var map = [[]];
                //for(i=0;i<this.gridHeight;i++) map[i]=[];
                for(i=0;i<environment.gridHeight;i++) map[i]=[]; //Modified according to @WasteD
                this.storage['map'] = map;
            }
            var blue = []
            var red = []
            var x = this.storage['position'][0];
            var y = this.storage['position'][1];
            var dx = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
            var dy = [1, 1, 1, 0, 0, 0, -1, -1, -1]
            (this.aroundMe || []).forEach((item, idx) => { // Update map and list positions of surrounding blues and reds
                if (item && item.team == 'red' && typeof item.name != "undefined") red += idx;
                if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx[idx]][y+dy[idx]] = 'M';
                if (item && item.team == 'blue' && typeof item.name != "undefined") blue += idx;
            });
            this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']}); //Send to buddies my position and the map
            if (red.indexOf([1, 4, 6, 3][this.direction]) > -1) this.kill() ; //If red guy is in front of
            else if (red.indexOf([1,4,6,3]) > -1) this.rotate(red.indexOf([1,4,6,3])); //If red guy is next but not in front of
            else if (blue.indexOf(3) > -1){ //If blue buddy on the left
                if (blue.indexOf(4) > -1){ //If another one is on the right
                    if (blue.indexOf(1) > -1 && this.direction != 2) this.rotate(2); //...and a third one at the top
                    else var digging = this.dig();
                    }
                else if (this.direction != 1) this.rotate(1);
                else var digging = this.dig();
            }
            else if (blue.indexOf(1) > -1){
                if (blue.indexOf(6) > -1 && this.direction != 3) this.rotate(3);
                else if (this.direction != 2) this.rotate(2);
                else var digging = this.dig();
            }
            else if (blue.indexOf(4) > -1){
                if (this.direction != 3) this.rotate(3);
                else var digging = this.dig();
            }
            else if (blue.indexOf(6) > -1 && this.direction != 0) this.rotate(0);
            else if (blue.indexOf([0,2]) > -1){ //If no blue next to me but one in diagonal, move next
                this.move(1);
                this.storage['position'][1] = y+1; //Update position
            }
            else if (blue.indexOf([5,7]) > -1){
                this.move(6);
                this.storage['position'][1] = y-1;
            }
            else if (typeof this.storage['other_blue'] != "undefined"){ //Check if buddies said where they were, try to go near the closest one
                var dmin = 99999;
                var pos = []
                (this.storage['other_blue'] || {}).forEach((item, idx) => {
                    var d = Math.sqrt(Math.pow(item['position'][0]-x,2) + Math.pow(item['position'][1]-y,2));
                    if (d < dmin){
                        dmin = d;
                        pos = item['position'];
                        }
                });
                if (pos[0]-x > 0){
                    this.move(4);
                    this.storage['position'][0] = x+1
                }
                else if (pos[0] < 0){
                    this.move(3);
                    this.storage['position'][0] = x-1
                }
                else if (pos[1] > 0){
                    this.move(1);
                    this.storage['position'][1] = y+1
                }
                else{
                    this.move(6);
                    this.storage['position'][1] = y-1
                }
            }
            else var digging = this.dig();
            if (typeof digging != "undefined"){ //Check out surroundings if dig() was played and update the map accordingly
                var dx2 = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2];
                var dy2 = [2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2];
                (digging || []).forEach((item, idx) => {
                    //if (item && item.team == 'red' && typeof item.name == "undefined") this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M';
                    if (item) this.storage['map'][x+dx2[idx]][y+dy2[idx]] = 'M'; //previously misread what dig() returned
                });
            }
            resolve();
        });
    },
    onmessage: function(data, fromTeam, fromBot) {
        if (typeof data['position'] != "undefined" && fromTeam == 'blue') { //If position sent by a blue bot
            if (typeof this.storage['other_blue'] == "undefined") this.storage['other_blue'] = [];
            for (i in this.storage['other_blue']){
                var found = false;
                if ('name' in i){
                    if (i['name'] == fromBot){
                        i['position'] = data['position'];
                        found = true; //Update if position already known from previous ticks
                        }
                }
            }
            if (!found) this.storage['other_blue'] += {'position':data['position'], 'name':fromBot}; //Add position if previously unknown
            this.sendMessage(fromBot, undefined, "roger.");
        }
    },
    onkill: function() {this.sendMessage(undefined, "blue", {"position": this.storage['position'], 'map': this.storage['map']});}
});
Christopher
quelle
1

Blauer Kämpfer

createBot({
  team: "blue",
  name: "blue-fighter",
  ontick: function(environment) {
    return new Promise((resolve, reject)=>{
      let map = environment.aroundMe;
      let sides = [1, 4, 6, 3];
      let facing = sides[this.direction];
      let isTeam = (team,a) => a && a.team === team;
      let isRed = (a)=>isTeam("red",a);
      let isBlue = (a)=>isTeam("blue",a);
      let randomSquare = ()=>Math.floor(Math.random()*8);
      let redNum = map.filter(isRed).length;
      let blueNum =  map.filter(isBlue).length;
      if(redNum > blueNum && redNum > 2){
        this.bomb();
      }else if(isRed(map[facing])){
        this.kill();
      }else if(sides.includes(map.findIndex(isRed))){
        this.rotate(sides.indexOf(map.findIndex(isRed)));
      }else if(Math.random() < 0.5 && this.landMines > 0){
        this.landMine(randomSquare());
      }else{            
        this.move(randomSquare());
      }
      resolve();
    });
  },
  onmessage: function(data, from, fromBot) {},
  onkill: function(){}
});

Blaue Kämpfer bewegen und landen zufällig und drehen sich zu roten Spielern. Wenn die umliegenden Blöcke mehr rot als blau sind, werden sie bombardiert. Wenn es einem roten Spieler gegenübersteht, tötet es ihn.

SuperStormer
quelle