Team of The Hill!


27

Questa sfida è stata ispirata da @HelkaHomba s' eccellente sfida Red vs Blue - Pixel squadra Battlebots . Quella sfida è stata probabilmente la migliore che abbia mai visto su questo sito. Mai.

La mia sfida è ancora molto diversa, ma @HelkaHomba merita credito per l'ispirazione.

Panoramica

Questo è un cui la tua squadra vince avendo tutti i giocatori vivi nella tua squadra. In altre parole, vince l'ultima squadra in piedi. I sorteggi saranno ripetuti.

Sei su una tavola. Conosci la tua posizione al primo turno (spunta 0). Sai anche chi c'è nella zona intorno a te:

Un unico quadrato rosso in una griglia 9x9, circondato da globuli bianchi.

In questo caso, sei tutto solo (o almeno così pensi) con nessuno intorno a te. Puoi vedere gli oggetti circostanti nel primo argomento del tuo ontickgestore. Maggiori informazioni sull'API in seguito.

La tua squadra

Il tuo team è determinato dal tuo ID utente. Per scoprirlo, fai clic sulla tua immagine del profilo:

La mia foto profilo

Quindi trova il tuo ID utente nella barra degli indirizzi:

È compreso tra / utenti / e / nomeutente

Se è strano, sei nella squadra blu.

Se è pari, sei nella squadra rossa.

Prego per i cerchi disegnati a mano.

Il tuo nome (bot)

Il nome del tuo bot inizia con la prima lettera del tuo team ("r" o "b"). Deve corrispondere alla regex /^(r|b)[A-Za-z_-]$/. Oltre a ciò, puoi scegliere il nome del tuo bot. Per favore, non usarne uno già esistente.

Di partenza

I giocatori rossi inizieranno vicino alla parte superiore della mappa e il blu inizierà vicino alla parte inferiore. Vengono fornite informazioni speciali sul primo segno di spunta (giro) nel environmentparametro per la ontickfunzione. Consiglio di conservarlo. Vedi l'API per i dettagli.

Al tuo turno

L'ordine di turno è inizialmente randomizzato, ma rimane lo stesso.

Trasforma le azioni

Puoi fare solo un'azione per turno.

  • Mossa

    Quando desideri spostarti, chiami this.move(num)l'API. numè la cella in cui desideri spostarti:

    0 è in alto a sinistra, 1 è in alto al centro, 2 è in alto a destra, 3 è in mezzo a destra, 4 è in mezzo a sinistra, 5 è in basso a sinistra, 6 è in basso al centro e 7 è in basso a destra.

    Le posizioni relative dei numeri che è possibile spostare vengono memorizzate nella costante globale threeByThree:

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

Se ti muovi in ​​un muro o in un altro giocatore, non succede nulla.

  • Ruotare

    Per ruotare, si chiama this.rotate(num). Num è la direzione che vuoi ruotare:

    0 è in alto, 1 è a destra, 2 è in basso e 3 è a sinistra

    La rotazione è assoluta.

  • Uccidere

    Se un altro giocatore (di un'altra squadra) si trova nella cella che stai affrontando, puoi chiamare this.kill()e ucciderli. Se non c'è nessuno lì, o sono nella tua squadra, questo non fa nulla. Esempio:

    Stessi numeri come sopra, la cella 0 è verde, l'1 è blu, il 2 è arancione e il 3 è giallo

    Se ti rivolgi a 0, puoi uccidere il verde. Se sei trasformato in 1, puoi uccidere il blu. Se sei trasformato in 2, puoi uccidere l'arancia. Se sei trasformato in 3, puoi uccidere giallo.

  • Bomba

    Bombardare uccide tutti i giocatori inclusi te e compagni di squadra nelle 9 caselle intorno a te. Esempio:

    C'è una griglia 9x9 con "x" s in ogni cella.

    Perché mai vorresti farlo? Kamikaze . Se ci sono più giocatori non nella tua squadra nelle 9 celle intorno a te, allora ci sono nella tua squadra, potresti prendere in considerazione un bombardamento. (Ti suggerisco di avvisare prima i tuoi compagni!)

  • Metti una mina

    Questo crea un quadrato della morte per gli altri non nella tua squadra. Quando metti una mina terrestre, ti muovi anche in modo da non calpestarla. Chiami this.landMine(num)dove num è il quadrato in cui vuoi andare. Esempio:

    Un unico quadrato rosso in una griglia 9x9, circondato da globuli bianchi.

    Quindi chiami this.landMine(4):

    [Una griglia 9x9, con una "M" rossa al centro e una cella rossa al centro a destra.

    Vedi quella "M"? È una mina terrestre. Gli altri possono vederlo ... per ora. Chiunque, anche quelli che non fanno parte della tua squadra, può vedere una mina sul segno di spunta in cui è posizionata. Ma dopo che quel segno di spunta è finito, nessuno, nemmeno tu puoi vederlo. Ma esploderà non appena un nemico ci passerà sopra. Esempio:

    Due griglie 9x9, una cella blu nel mezzo a sinistra nel primo, una "M" rossa nel mezzo del primo, una "x" rossa nel mezzo del secondo e una freccia tra di loro.

    Il blu si è mosso sulla tua mina terrestre e BOOM! Hai appena avuto un'altra uccisione.

    Per ogni 2 uccisioni che ricevi (da uccisioni dirette o mine terrestri), ottieni 1 mina aggiuntiva da piazzare. Ne ottieni anche uno all'inizio.

  • Scavare

    Quando scavi, cerchi mine antiuomo in un'area 5x5 centrata intorno a te. Questo non mostra la squadra del robot che ha posizionato la mina. (Ricorda che non puoi essere ucciso da una mina piazzata da qualcuno nella tua squadra.) Ad esempio, se questa era la griglia intorno a te:

    Quindi il valore restituito di this.dig()sarebbe:

[undefined,undefined,undefined,true,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,undefined,true,undefined,undefined,
true,undefined,undefined,undefined,undefined]

Gli indici dell'array provengono dall'avvio in alto a sinistra, andando a destra, poi verso il basso, senza includere te stesso:

Ce ne sono 23 in totale e le loro posizioni relative sono memorizzate nella costante 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]
]

Si noti che lo scavo rivela mine posizionate su tick precedenti, a differenza di aroundMe.

Comunicazione

Quando vuoi parlare con qualcuno, chiami this.sendMessage(recipients, team, data). I dati possono essere tutto ciò che desideri e puoi inviarli a chiunque tu voglia, anche ai giocatori di altre squadre. Questo può essere usato per ingannare i robot mal programmati, ma tutti i giocatori possono vedere chi ha inviato un messaggio e la squadra in cui si trovano.

Esempio:

Invia qualcosa a un bot chiamato "redisbest":

this.sendMessage("redisbest", undefined, "Hi!");

Invia qualcosa a un bot chiamato "redisbest" e "blueiscool":

this.sendMessage(["redisbest", "blueiscool"], undefined, {hello: "there"});

Invia qualcosa a tutta la squadra rossa

this.sendMessage(undefined, "red", {hello: "red"});

Invia qualcosa a tutti

this.sendMessage(undefined, "*", {hello: "everyone"});

Invia qualcosa all'intero team rosso e un bot chiamato "blueiscool":

this.sendMessage("blueiscool", "red", {hello: "bots"});

API

Il codice deve essere costituito da una singola chiamata alla createBotfunzione. Nient'altro. Codice di esempio:

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
    }
});

(Sei libero di copiare e incollare questo. Basta modificarlo per il tuo team, ecc.)

metodi

  • ontick(environment)

    Chiamato quando è il tuo turno. Deve restituire un Promiseerrore che si risolve in 1 secondo o meno o verrà ignorato. Questo per motivi di prestazioni e ha il piacevole effetto collaterale di non avere il blocco della linguetta.

    this (quando in ontick)

    • landMines Quante mine antiuomo ti sono rimaste. Più uccisioni hai, più mine terrestri ottieni. Per ogni 2 robot che uccidi, ottieni 1 ulteriore mine antiuomo. Hai anche 1 per iniziare.
    • direction La direzione verso cui sei rivolto.
    • storage Memoria che persiste tra le chiamate a onTicke onMessage. Un oggetto vuoto all'inizio. Modifica per qualsiasi scopo, ma assicurati che sia sempre un array o un oggetto per assicurarti che persista correttamente.
    • move(num) Passa alla posizione specificata. Non fa nulla se non è valido. Vedi sopra per i dettagli.
    • rotate(num) Ruota nella posizione specificata. Non fa nulla se non è valido. Vedi sopra per i dettagli.
    • kill() Uccide il giocatore che stai affrontando, se esiste e non fa parte della tua squadra. Vedi sopra per i dettagli.
    • bomb() Uccide chiunque nei 9 quadrati intorno a te, incluso te stesso.
    • landMine(num) Posiziona una mina terrestre dove ti trovi, quindi si sposta nella posizione specificata. Non fa nulla se non numè valido o non ne è rimasto nessuno. Vedi sopra per i dettagli.
    • dig() nuovo! Restituisce una serie di informazioni sulle mine antiuomo in un'area 5x5 centrata intorno a te. Vedi sopra per i dettagli.
    • sendMessage(recipients, team, data) recipientspuò essere un singolo bot (stringa), un array di bot o undefined/ null. È chi vorresti inviare il messaggio. teamè una stringa del team a cui desideri inviare il messaggio. Utilizzare "*"per inviare un messaggio a tutti. dataè tutto ciò che può essere passato a una funzione JS. Viene inviato ai destinatari. Se si tratta di un oggetto o di un array, viene passato per riferimento , quindi tu e il destinatario (i) potete salvarlo sul loro storagee qualsiasi modifica all'oggetto influisce su entrambe le copie del bot. Nota che i destinatari che sono sia l'elenco dei bot, bot esatto specificato nella stringa, o un bot sulla squadra specificato, otterrà il messaggio.

environment

Al primo segno di spunta

  • x: Posizione x del tuo giocatore
  • y: Posizione y del tuo giocatore
  • gridWidth: La larghezza della griglia (in celle)
  • gridHeight: L'altezza della griglia (in celle)

    Su tutte le zecche

  • aroundMe: Una serie di giocatori e mine antiuomo. I giocatori sono oggetti che sembrano {name: "bot name", team: "bot team"}e le mine antiuomo {team: "team of bot who placed mine"}. Gli indici dell'array:

    0 è in alto a sinistra, 1 è in alto al centro, 2 è in alto a destra, 3 è in mezzo a destra, 4 è in mezzo a sinistra, 5 è in basso a sinistra, 6 è in basso al centro e 7 è in basso a destra.

    Si noti che le mine antiuomo posizionate su un segno di spunta diverso da quello attuale non verranno visualizzate.

    aroundMe esempio:

    Diciamo che questa è la griglia (sei rosso):

    Una griglia 9x9, con l'azzurro in alto a sinistra, una "M" grigia in alto a destra, il rosso in mezzo, il giallo in mezzo a sinistra e una "M" rossa in basso a sinistra.

    Il tuo aroundMeaspetto sarà questo:

[
    {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.
]

Gli indici dell'array sono spiegati qui:

0 è in alto a sinistra, 1 è in alto al centro, 2 è in alto a destra, 3 è in mezzo a destra, 4 è in mezzo a sinistra, 5 è in basso a sinistra, 6 è in basso al centro e 7 è in basso a destra.

Il tuo bot lo vede efficacemente:

Una scatola azzurra in alto a sinistra con un numero 0 nero, una scatola gialla sul bordo sinistro con un numero nero 4 e una "M" rossa in basso a sinistra con un 5 nero.

  • onmessage(data, fromBot, fromTeam)

    this (in onmessage)

    • sendMessage(recipients, team, data) Funzione di invio messaggio standard.
    • storage Archiviazione standard.

    dataI dati inviati dal mittente. fromPlayerIl giocatore da cui è stato inviato il messaggio. fromTeamLa squadra da cui è stato inviato il messaggio.

  • onkill()

    this (quando in onkill)

    • sendMessage(recipients, team, data) Funzione di invio messaggio standard.

Matrici globali (costanti) convenienti:

threeByThree:

[
    [0, 1, 2],
    [3, undefined, 4],
    [5, 6, 7]
]

Utile per il passaggio di dati alla funzione di spostamento e per l'interpretazione aroundMe. Vedi sopra.

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 per la this.dig()funzione nel ontickgestore.

Provalo!

Il controller verrà eseguito dalla mia macchina su localhost per motivi di prestazioni, ma è possibile utilizzare CodePen per testare il bot.

Si noti che è necessario incollare il codice nella console e premere Enterprima di fare clic su Esegui. Puoi incollare tutti i robot che desideri. I "robot di prova" sono esempi su cui si può provare. Se riesci a batterli o legarli tutti, hai almeno un bot decente.

Inseriti

Regole

Regole (applicate dal controller)

  • Il ontickcodice principale non deve richiedere più di 1 secondo. Non vogliamo che i round durino per sempre. Se il tuo codice impiega> 1 secondo, verrà interrotto.
  • Se provi a fare più di 1 azione per turno o fai un'azione non valida (ad es. this.move(-1)O ti muovi in ​​un muro), verrà ignorato.
  • Più potrebbe venire presto ...

Regole (imposte da me, possono comportare DQ)

  • Non scrivere variabili globali (la lettura va bene ).
  • Il codice deve funzionare in Nodejs (nel caso in cui il controller sia portato su Nodejs), quindi JSON.parse(...)va bene, ma alert()non lo è.
  • Non è consentito chiamare createBoto interferire con il controller in alcun modo .
  • Non utilizzare il codice di qualcun altro senza autorizzazione e modifiche significative. Nessun copybot.
  • Per favore, niente scappatoie!
  • Più potrebbe venire presto ...

I miei robot

Ecco alcuni robot:

Questo bot sceglie casualmente un'azione. Bene, è un caso ponderato, ma comunque piuttosto casuale. Se riesci a uccidere questo bot (alla fine si ucciderà da solo, questo non conta), allora hai almeno un bot decente. Pubblicalo e guarda cosa succede!

I miei robot hanno un nome che inizia con "x" e una squadra di "nessuno". Puoi usare parte di questo codice, ma ti preghiamo di apportare almeno alcune modifiche. Se non puoi essere disturbato a modificare almeno un numero, non vincerai.

Formattazione dell'invio

Si prega di utilizzare questo formato:

# 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...

Richieste di funzionalità, bug, domande, ecc.?

Commenta sotto! Si prega di verificare se è già presente un commento. Se ce n'è già uno, votalo.

Vuoi parlare con la tua squadra?

Usa le chat room per il rosso e il blu .

linguaggio

Attualmente è supportato solo JS e qualcosa che si compila in JS, ma se si conosce un modo per far funzionare altre lingue con Nodejs sarei felice di portare il controller su Nodejs.

Note finali

Idee di strategia

Aiuta la tua squadra! Creazione di un bot progettato per aiutare un altro bot e lavorare insieme. Questa strategia ha funzionato bene per Red vs. Blue - Pixel Team Battlebots

Cercatori di rappresentanti

Accetterò la risposta più votata dalla squadra vincente. Tieni presente che le risposte precedenti tendono a ottenere più voti, ma è più probabile che le loro debolezze vengano individuate e sfruttate.

Inoltre, se rispondi presto, potresti ottenere la taglia +100.


1
I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Dennis,

Posso fare più di un robot? (scusa, so che la conversazione è stata spostata, sono appena stato bandito, quindi sì)
Matthew Roh,

@SIGSEGV sì, ma qualcun altro deve pubblicarlo. Puoi pubblicare un bot e dare il codice di un altro a qualcuno nella tua squadra, ma non puoi pubblicare due volte.
programmatore

Sul posizionamento, dov'è la cella con indice [0, 0], è la cella in alto a sinistra? Inoltre, la messaggistica consuma la tua azione (per turno)? Grazie.
Thrax,

@Thrax sì, e no. Puoi persino inviare un messaggio in risposta a un messaggio.
programmatore

Risposte:


7

xscared (non competitivo)

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(){
    }
});

Molto spaventato dalle persone. Si allontana dalla prima persona (o mina terrestre) che vede. Altrimenti, si muove in modo casuale. Nota che questo non è in competizione, solo un esempio. Prova a batterlo!


6

backup, un bot blu

Come avvertito in chat, non ho mai scritto nulla in javascript in vita mia, quindi se trovi qualche errore, per favore dimmelo! (Grazie a @ programmer5000 per avermi già aiutato)
Il concetto di questo bot è che comunica con altri robot della stessa squadra e invia loro la sua posizione insieme a una mappa delle mine che ha trovato. Cerca di unirsi al bot blu più vicino (se uno invia i suoi dati di posizione [dati come un array [x, y]]) e rimane vicino ad esso (con le spalle il più possibile), uccidendo avvicinandosi ai robot rossi o guardando avanti per le mine.

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']});}
});

Ehi, ti importa se anche io inserisco questo, ma (con un nome diverso) Sono anche in blu
Christopher,

@Christopher No, non mi dispiace, ma sarebbe un po 'più interessante per te e per il team se ne fai uno almeno un po' diverso (almeno per integrare i 2 robot che già esistono).
plannapus,

Lo farà. Lo cambierò
Christopher,

Se provo ad eseguire il tuo bot in codepen, non funziona perché lo stai utilizzando this.xe così via, ma è environment.xo sbaglio?
WasteD

@WasteD, come ho detto, non conosco affatto Javascript, quindi è possibile. Ma se è così, suppongo che dovrebbe essere anche environment.gridHeighte environment.aroundMe? Nel qual caso gli altri robot non dovrebbero funzionare neanche dal momento che usano this.aroundMe.
plannapus,

5

Blu, blu, il mio mondo è blu

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() {}
});

Per lo più casuale, ma bombarderà se circondato, e favorisce il controllo e l'uccisione del movimento.


Inteligente! Ben fatto.
programmatore

3
Ascolta, ecco una storia, su un piccoletto che vive in un mondo blu.
Matthew Roh,

3

Relaxed-Bomber

Questo bot cerca un punto con almeno 1 cella libera su ciascun lato, quindi pianta una miniera. Ci si accampa fino a quando un nemico non si avvicina. Quando qualcuno si avvicina, fa un passo avanti e indietro sulla sua miniera per attirare l'altro robot su di esso. Inoltre ruoterà e ucciderà se necessario. Quando non gli è rimasta alcuna, cercherà rifugio nell'angolo in alto a sinistra con le spalle al muro e si vendicherà se è minacciato.

Nessun gioco di squadra speciale qui, a parte trasmettere la sua posizione alla sua squadra con la selfparola chiave.

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() {}
});

In quale squadra sei?
programmatore

@ programmer5000 Dato che i nomi dei robot devono iniziare con la lettera della squadra, credo di essere Team Red :)
Thrax,

Bel robot! Ti suggerisco di trasmettere anche ciò che ti circonda alla tua squadra.
programmatore

1

Esegui il backup 1 di un altro bot blu (hai dimenticato di farlo prima)

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']});}
});

1

Combattente blu

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(){}
});

Il combattente blu si muove e mina in modo casuale e ruota verso i giocatori rossi. Se i blocchi circostanti hanno più rosso che blu, bombe. Se sta affrontando un giocatore rosso, lo uccide.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.