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 re della collina in 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:
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 ontick
gestore. 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:
Quindi trova il tuo ID utente nella barra degli indirizzi:
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 environment
parametro per la ontick
funzione. 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: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: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: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:
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:Quindi chiami
this.landMine(4)
: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:
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 createBot
funzione. 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
Promise
errore 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 aonTick
eonMessage
. 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 nonnum
è 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)
recipients
può essere un singolo bot (stringa), un array di bot oundefined
/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 lorostorage
e 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 giocatorey
: Posizione y del tuo giocatoregridWidth
: 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: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):
Il tuo
aroundMe
aspetto 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:
Il tuo bot lo vede efficacemente:
onmessage(data, fromBot, fromTeam)
this
(in onmessage)sendMessage(recipients, team, data)
Funzione di invio messaggio standard.storage
Archiviazione standard.
data
I dati inviati dal mittente.fromPlayer
Il giocatore da cui è stato inviato il messaggio.fromTeam
La 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 ontick
gestore.
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 Enter
prima 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
ontick
codice 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, maalert()
non lo è. - Non è consentito chiamare
createBot
o 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.