Contest concluso! Leggi i commenti sui BLOB per visualizzare il loro punteggio.
Questo KoTH è liberamente ispirato alla simulazione di selezione naturale di Primer . Il tuo bot è un blob. Per sopravvivere, devi mangiare i pellet per recuperare energia, che viene utilizzata per spostarti. Con energia extra, i blob possono essere divisi in due.
Energia e movimento
Il tuo blob inizia ogni round con 100 energia e non ha limiti sulla quantità di energia che può raccogliere. Ogni round viene eseguito a turni, con ogni blob che ha la possibilità di spostarsi a nord, est, sud o ovest in un dato turno o rimanere fermi. Lo spostamento utilizza 1 energia e la posizione eretta utilizza ancora 0,25 energia. La lunghezza del lato della mappa èceil(0.25 * blobCount) * 2 - 1
unità, con un minimo di 9 unità. Tutti i BLOB iniziano sul bordo della mappa, con uno posizionato in ogni angolo e ogni BLOB successivo viene posizionato a 2 unità di distanza da qualsiasi altro. Ogni 30 turni, un'onda di pallini viene posizionata in punti casuali attorno alla mappa, almeno 1 unità da qualsiasi bordo. Ogni volta che appare un'onda di pellet, la quantità di pellet (originariamente il doppio del numero di chiazze o della larghezza della mappa, a seconda di quale sia maggiore) nell'onda successiva viene ridotta di 1, costringendo il numero di chiazze a diminuire nel tempo. Ogni pellet ripristina tra 5 e 15 energia. Quando l'energia di un blob è inferiore o uguale a 0, muore.
Mangiare
Se due o più BLOB tentano di occupare la stessa posizione, quello con più energia mangerà gli altri, ricevendo la loro energia. Se entrambi hanno la stessa energia, entrambi svaniscono.
Rilevamento e informazioni
Le chiazze possono vedere le palline o altre macchie entro una distanza di 4 unità. Quando vengono chiamate le loro funzioni, i BLOB vengono forniti con:
- La lunghezza laterale della mappa
- La posizione del blob sulla mappa
- Le posizioni di tutti i pellet nel loro raggio di ricerca, nonché i loro valori
- Le posizioni di tutti i BLOB nel loro raggio di ricerca, nonché la loro energia e UID
- Energia, UID e posizioni del BLOB di cui viene eseguita la funzione
- Un oggetto di archiviazione univoco per il BLOB
- Un oggetto di archiviazione condiviso da tutti i BLOB correlati al BLOB mediante suddivisione
scissione
Se un blob ha più di 50 energie, può scegliere di dividere. La divisione costa 50 energia e l'eventuale energia rimanente viene suddivisa equamente tra le due chiazze. Tutti i BLOB sono originali o copie divise, con ogni copia risalente a un originale. Tutti insieme sono "parenti". Tutti i parenti hanno un oggetto di archiviazione comune. I parenti possono ancora mangiarsi a vicenda e possono dividere, utilizzare il proprio oggetto di archiviazione o raccogliere energia senza influire sugli altri.
Trasferimento di energia
Se due blob sono uno accanto all'altro (dopo lo spostamento), uno dei robot può trasferire energia all'altro. Questo viene fatto ritornando SendNorth(amt)
, SendEast(amt)
, SendSouth(amt)
, o SendWest(amt)
con amt
essendo un numero che rappresenta l'importo inviato. Questo può essere qualsiasi importo che il mittente può permettersi, compresa tutta la sua energia. Si raccomanda che al blob che sta ricevendo energia venga detto di rimanere fermo attraverso l'archiviazione comune, in modo che non si allontani quando l'energia viene trasferita (anche se in questo caso l'energia non verrebbe detratta dal totale del mittente).
Funzioni, archiviazione e UID
Per consentire comportamenti di apprendimento più complessi, a tutti i BLOB verrà assegnato un UID intero (Unique Identifer). Questi UID verranno generati casualmente su ogni mappa, impedendo strategie basate su singoli target. Quando viene chiamata la funzione di un BLOB, vengono passati quattro argomenti:
- La lunghezza laterale della mappa come numero intero
- Un oggetto con due matrici:,
pellets
eblobs
. Entrambi gli array contengono oggetti, entrambi con unapos
proprietà contenente la posizione della pallina o del blob formattata come[x,y]
. I pellet avranno unaenergy
proprietà, mentre i blob avranno unauid
proprietà e unaenergy
proprietà - Un oggetto che contiene varie proprietà del blob si passa a:
energy
,uid
epos
. L'pos
array è formattato come[x,y]
- Un oggetto contenente i due oggetti di archiviazione del BLOB. Una
self
proprietà contiene un singolo oggetto di archiviazione che può essere modificato nel modo che il BLOB ritiene opportuno (modificando le proprietà dell'oggetto che viene passato) e unacommunal
proprietà che può essere modificata da qualsiasi parente.
I BLOB non vengono spostati immediatamente per evitare che i turni precedenti / successivi abbiano un vantaggio. Tutti i movimenti vengono elaborati in gruppi (tutte le collisioni / alimentazione, quindi tutte le palline, quindi si scindono, ecc.) Se un blob atterra su un pellet o blob più piccolo e, nel processo utilizza la sua ultima energia, il blob consumerà comunque il pellet / energia indipendente dal fatto che ciò porterebbe la sua energia totale al di sopra di 0.
Affinché i BLOB relativi possano riconoscersi reciprocamente, è necessario utilizzare l'archiviazione comune per ciascun BLOB per registrare il proprio UID in un array o tramite un altro sistema.
Valori di restituzione
Per spostare o dividere, viene utilizzato il valore restituito della funzione. Innanzitutto, il significato delle direzioni cardinali in termini di coordinate:
- Nord = -Y
- Est = + X
- Sud = + Y
- Ovest = -X
Si noti che [0,0]
è l' angolo in alto a sinistra e Y aumenta mentre si scende. Il valore di ritorno della funzione dovrebbe seguire queste regole:
- Per non fare nulla: non restituire nulla, 0, null, indefinito, falso o qualsiasi altro valore equivalente a falso
- Per spostare: restituisce una delle quattro variabili globali: Nord, Est, Sud o Ovest, che equivalgono a "nord", "est", "sud" o "ovest" (che potrebbe anche essere usato come valore di ritorno)
- Per dividere: restituire la variabile globale SplitNorth, SplitEast, SplitSouth o SplitWest, la direzione che indica dove posizionare il nuovo BLOB
Se viene restituito un comando diviso e la quantità di energia richiesta è maggiore o uguale all'energia del blob, non accadrà nulla. I BLOB non saranno in grado di lasciare la mappa.
Funzioni di libreria predefinite
Ci sono alcune funzioni di base disponibili per impostazione predefinita, per risparmiare tempo:
taxiDist (pt1, pt2)
Restituisce la distanza del taxi tra due punti (distanza X più distanza Y).
taxiDist([0, 0], [2, 2]) //4
taxiDist([3, 4], [1, 5]) //3
taxiDist([1.25, 1.3], [1.3, 1.4]) //0.15
taxiDist([0, 0], [5, 2.5], 2.5) //3
taxiDist([0, 0], [2, 4], 2.5) //2.4
hypotDist (pt1, pt2)
Restituisce la distanza tra due punti secondo il teorema di Pitagora
hypotDist([0, 0], [5, 12]) //13
hypotDist([4, 6], [8, 9]) //5
hypotDist([0, 1], [2, 1]) //2
hypotDist([1, 1], [2, 2]) //sqrt(2)
modDir (dir, amt)
Prende la direzione immessa, ruota di 90 gradi in senso orario amt
, quindi restituisce il nuovo valore.
modDist(North, 1) //East
modDist(East, 2) //West
modDist(West, 3) //South
modDist(South, 4) //South
BLOB di esempio
Questo blob non si muoverà finché non troverà un pellet nelle vicinanze. Quindi, si sposterà nella direzione che ritiene sia più probabile che lo ricompensi. Se la sua energia è mai superiore a 150, si dividerà.
function(map, near, me, storage) {
if (me.energy > 150)
return SplitNorth;
if (!near.pellets.length)
return null;
var dirs = [0, 0, 0, 0];
for (let p, i = 0; i < near.pellets.length; i++) {
p = near.pellets[i];
dirs[0] += me.pos[1] - p.pos[1];
dirs[1] += p.pos[0] - me.pos[0];
dirs[2] += p.pos[1] - me.pos[1];
dirs[3] += me.pos[0] - p.pos[0];
}
return [North, East, South, West][dirs.indexOf(Math.max(...dirs))];
}
Regole
- Le scappatoie standard sono vietate. Inoltre, nessuna scappatoia non standard.
- Nessun BLOB può tentare di modificare o leggere i dati non trasmessi tramite i suoi parametri
- Nessun BLOB può tentare di modificare una variabile di valore restituito per sabotare altri BLOB
- Un round dura fino a quando le uniche chiazze rimanenti sono parenti
- Nessun BLOB può modificare i dati iniettando funzioni nei suoi parametri che modificano i valori utilizzando la
this
parola chiave - Tutti gli invii devono essere in Javascript o in una lingua che non sia troppo diversa da Javascript (ad esempio Python). Tutte le risposte verranno convertite in Javascript per la competizione.
- Il vincitore è il blob che ha raccolto la più alta quantità di energia in totale in tutti i round (da pallini o consumando blob più piccoli che non sono parenti)
Controller: https://gist.github.com/RedwolfPrograms/1facc0afe24c5dfd3ada8b8a2c493242
Chatroom: https://chat.stackexchange.com/rooms/93370/hungry-blobs-koth