Hunger Gaming: Eat or Die
Se non mangi, muori. Se mangi, vivi (fino alla morte). Si dovrà morire, in modo da provare a morire scorso.
Panoramica
C'è un'isola popolata da un branco di animali da preda. Controlli un pacchetto di cinque predatori. Il tuo obiettivo è mantenere vivo il tuo branco. Fallo mangiando una preda. Le prede tendono a scappare dai predatori, altrimenti cercano di rimanere in uno stormo. Ovviamente, il tuo pacco sarà sullo stesso campo di ogni altro pacco , quindi la competizione cercherà di mangiarli prima che tu possa farlo. Non lasciarti scoraggiare, altrimenti morirai di fame.
Come giocare
Crea e invia un programma da riga di comando per dirigere il tuo pacchetto. Riceverà informazioni sullo stato dal programma di controllo su STDIN e emetterà comandi su STDOUT. Il formato è delineato in dettaglio di seguito. Ogni programma verrà eseguito solo una volta e deve rimanere in esecuzione fino a quando non ha più membri del pacchetto in vita. Dovrai leggere l'input appena arriva e rispondere rapidamente. C'è un timeout rigoroso di 200 ms per ogni risposta. Se non hai ancora risposto, il tuo pacco non riceverà nuove istruzioni per il turno in corso.
Se il programma non può essere eseguito dal controller, non sarà considerato valido. Includere la stringa della riga di comando che dovrò utilizzare per eseguire l'invio. Se sono presenti istruzioni speciali (per impostare compilatori, ecc.), Includerle. Se non riesco a farlo funzionare, ti chiederò assistenza nei commenti. Se non rispondi, non sarò in grado di accettare la tua richiesta.
Il torneo si svolgerà su un sistema Linux a 64 bit. Tienilo a mente quando fornisci le indicazioni necessarie.
Dettagli
La posizione e la direzione di ogni creatura hanno la forma di una coppia di numeri in virgola mobile a precisione doppia (ad es.
double
) Che rappresentano rispettivamente le lorox
ey
coordinate.Ogni creatura è considerata un punto. Ciò significa che possono sovrapporsi e occupare lo stesso spazio. Non sarai urtato da parte, e non vi è alcun concetto di collisione con altre creature.
L'isola è una piazza, 500 unità su un lato. Se provi ad avventurarti oltre quei limiti, verrai bloccato sul bordo. L'origine
{0,0}
è in alto a sinistra, con l'x
aumento verso destra ey
verso il basso. Ancora una volta, la mappa non si avvolge .Il gioco inizia con 1500 + (packCount * 50) animali da preda. Saranno riuniti al centro dell'isola, ma presto decideranno di iniziare a muoversi.
I pacchetti saranno disposti in un cerchio distribuito uniformemente attorno al perimetro. L'ordine del pacchetto viene mischiato, quindi non contare sull'avvio in una posizione particolare.
Gli animali da preda possono vedere tutti gli altri animali entro un raggio di 30 unità. Possono muoversi ad un massimo di 6,0 unità per turno.
I predatori possono vedere tutti gli altri animali entro un raggio di 50 unità. Possono muoversi ad un massimo di 6,1 unità per turno. Ciò significa che possono vedere la preda prima di essere visti e (a malapena) superarli.
I predatori vivono e muoiono in base al loro livello di fame . Inizia da 1000 e diminuisce di uno ogni turno. Se, dopo il movimento, un predatore si trova entro 1 unità di preda, lo mangerà automaticamente. Questo rimuove la preda e imposta la fame del predatore su 1000. Ogni predatore può mangiare solo una preda per turno. Se ce ne sono più di uno nel raggio d'azione, mangerà quello che il ciclo raggiunge per primo (non necessariamente il più vicino). Un predatore muore se la sua fame raggiunge lo zero.
I pacchetti iniziano con cinque membri ciascuno. Ogni 5000 turni, tutti i pacchetti ancora in gioco genereranno un nuovo membro. Verrà inserito nel raggio visibile di un membro del pacchetto. Assicurati che le tue voci possano gestire più di cinque membri.
Ogni 1000 turni, si generano più prede. Il numero di nuove prede sarà il numero di predatori viventi meno uno.
I predatori non possono attaccare altri predatori. Mangiano prede quando la prendono. Questo è tutto.
L'ordine in un turno è:
- Tutte le prede prendono decisioni
- Tutti i predatori prendono decisioni
- Tutte le prede si muovono
- Tutti i predatori si muovono / mangiano
L'ordine in cui ogni pacchetto prende le proprie decisioni / mosse sarà randomizzato ad ogni turno.
Protocollo (generale)
Tutte le comunicazioni vengono eseguite in formato stringa US-ASCII
. I numeri vengono convertiti in stringhe utilizzando Java Double.toString()
o Integer.toString()
. L'output deve essere formattato in modo che possa essere letto da Java Double.valueOf(String)
(non verranno emessi numeri interi). Per dettagli sui formati analizzabili, consultare la documentazione perDouble
. Tutti i campi su una linea sono separati dal \t
carattere standard e le nuove linee lo sono \n
. L'intera stringa verrà terminata con un byte nullo \0
.
Negli esempi seguenti, sto usando <>
per contrassegnare i campi per motivi di leggibilità. Questi non sono presenti nelle stringhe effettive.
Protocollo (input)
La stringa di input varia in lunghezza, a seconda di quante creature sono visibili al tuo branco. Può superare i 100k caratteri, quindi preparati. L'impostazione di base è:
Linea 0: informazioni di base sul gioco.
turn
è il numero di turno corrente e i conteggi sono il numero totale di prede e predatori rimasti sul campo. Questi sonointeger
in forma di stringa.<turn>\t<preyCount>\t<predatorCount>\n
Riga 1: ID univoci e livelli di fame dei membri del tuo pacchetto. Questi non sono indicati nello stesso ordine per ogni input. Utilizzare gli ID univoci per tenere traccia dei singoli membri, non nell'ordine in cui vengono visualizzati nell'input. Ancora una volta, questi sono
integer
come stringhe. Per un pacchetto di due, questo sarebbe:<id[0]>\t<hunger[0]>\t<id[1]>\t<hunger[1]>\n
Riga 2: posizioni dei membri del tuo pacchetto, nello stesso ordine indicato nella riga 1 . Questi sono
double
come stringa:<x[0]>\t<y[0]>\t<x[1]>\t<y[1]>\n
Le seguenti righe rappresentano la visibilità di ciascun membro del pacchetto, nello stesso ordine indicato nella riga 1 . Questi saranno indicati come due righe per membro.
Il primo per ciascuno è costituito da posizioni per la preda che può vedere. Il secondo è posizioni per i predatori che può vedere. Queste posizioni non sono uniche nel loro insieme. Ad esempio, se due membri del branco possono vedere lo stesso animale, sarà nella stringa di entrambi i membri. Inoltre, saranno inclusi i membri del tuo pacchetto personale . Se si desidera escluderli, è possibile che si desideri confrontare le posizioni con i propri membri. Tutte le posizioni sono in double
formato stringa.
Per ogni membro vivente:
<prey[0].x>\t<prey[0].y>\t<prey[1].x>\t<prey[1].y>\n
<predator[0].x>\t<predator[0].y>\t<predator[1].x>\t<predator[1].y>\n
Infine, l'ultimo personaggio sarà \0
, all'inizio della riga successiva.
Eccezione: se ricevi l'input dead\0
, il tuo pacchetto è morto. Termina il tuo programma con grazia, per favore. Il controller dovrebbe chiudere tutti i processi viventi quando è chiuso, ma preferirei non avere processi di zombi ovunque. A titolo di cortesia, è possibile includere un timeout di input. Ad esempio, la mia classe di esempio termina se non riceve input per 15 secondi.
Protocollo (uscita)
L'output è semplice. Darai una coppia di double
valori per ciascun membro del live pack. Questi rappresentano il movimento che vorresti che intraprendessero in questo turno. Ad esempio, se la tua creatura è attualmente in posizione {100.0, 100.0}
e tu dai loro un comando di {-1.0, 1.0}
, si sposteranno in {99.0, 101.0}
. Tutti i numeri saranno su una sola riga, separati da tab.
Ad esempio, se avessi 3 membri del pacchetto in vita, questa sarebbe una risposta valida:
1.0\t-1.0\t2.0\t-2.0\t3.0\t-3.0\0
Questo sarebbe spostare le tue creature dai {1.0,-1.0}
, {2.0,-2.0}
e {3.0,-3.0}
. L'ordine è uguale a quello ricevuto nell'input. Non dimenticare il finale \0
!
Se si fornisce un input non valido, seguiranno risultati negativi. Se un singolo numero non può essere analizzato in a double
, diventerà zero. Se la stringa nel suo insieme non può essere analizzata, non verranno fornite nuove istruzioni e l'intero pacchetto utilizzerà le indicazioni della svolta precedente.
Tutte le direzioni saranno bloccate ad una distanza massima di 6,1 unità. Puoi muoverti più lentamente di questo, se lo desideri. Ad esempio, {1, 0}
ti sposterà di un'unità. {6,8}
(distanza 10) ti sposta solo di 6,1 unità e si riduce a circa {3.66, 4.88}
. La direzione rimane costante.
Importante: il programma di controllo legge sia STDOUT che STDERR. Se si genera un'eccezione e si stampa su STDERR, è molto improbabile che il messaggio abbia la forma di una risposta valida. Cerca di evitare di farlo.
Programma di controllo / Test
La fonte per il controller può essere trovata qui su bitbucket.org . Dovrai compilarlo prima di eseguirlo. La classe principale è Game
e tutte le classi sono nel pacchetto predefinito. Per eseguire, includere il comando di ogni pacchetto come argomento separato. Ad esempio, se si desidera eseguire un Java ChaserPack e un Python LazyPack.py, è possibile utilizzare:
java Game "java ChaserPack" "python LazyPack.py"
Sulla mappa, la preda appare in verde e i predatori in rosso. Tuttavia, qualunque pacchetto sia il primo pacchetto dato come argomento verrà invece colorato in blu. Questo ha lo scopo di distinguerli più facilmente a scopo di test. I predatori lampeggeranno anche in bianco per cinque fotogrammi quando mangiano.
Il gioco continuerà fino a quando l'ultimo predatore muore di fame, scrivendo alla console quando si verificano eventi di fame o estinzione. Una volta completato il gioco, il punteggio verrà assegnato per ogni pacchetto. Se vuoi non voler vedere gli eventi di fame / estinzione, puoi usare l' -silent
argomento. Quindi emetterà solo il punteggio finale. Devi passare questo come primo argomento :
java Game -silent "java ChaserCat" "./someOtherPack"
È incluso un pacchetto scheletro Java chiamato GenericPack
. Include le operazioni di base input / output necessarie. È lì per dare un chiaro esempio di come analizzare e rispondere. Se desideri aggiungere un modello in un'altra lingua, fammi sapere.
Inoltre è incluso un predatore basato sul modello, ChaserPack
. Non sarà incluso nel torneo ed è incluso solo a scopo di test. Si comporta abbastanza male, a causa di un difetto di targeting intenzionale. Se non puoi batterlo, continua a provare.
Di seguito è riportato un esempio del programma di controllo (fare clic per il video). La qualità del video non è eccezionale (mi dispiace), ma puoi avere un'idea di come si muovono le prede. ( attenzione: audio )
punteggio
Il vincitore sarà determinato dal torneo, guadagnando punti in ogni round.
Ogni round procede fino alla morte di tutti i predatori. Ogni pacchetto verrà valutato in base alla morte del suo ultimo membro per fame. Verranno quindi assegnati punti in base all'ordine. I punti si accumulano per dieci round e il vincitore è il gruppo con il punteggio totale più alto.
Il primo posto per ogni round riceverà 100 punti. Per ogni luogo successivo, la ricompensa sarà ridotta del 20% (arrotondata per difetto). Questo continuerà fino a quando i punti raggiungono lo zero (dopo il 17 ° posto). I posti 18+ non riceveranno punti per il round. I pacchetti che legano riceveranno punti uguali. Per esempio:
1st : 100
2nd : 80
3rd : 64 (T)
3rd : 64 (T)
4th : 51
...
17th: 1
18th: 0
19th: 0
Il punteggio massimo possibile nel corso del torneo è 1000, dal primo posto tutte e dieci le volte.
Se più programmi terminano il torneo in parità per il primo posto, si terrà un altro torneo da dieci round con solo le iscrizioni al primo posto presentate. Questo continuerà fino a quando non emergerà un vincitore.
Proverò a organizzare un torneo all'incirca settimanalmente o quando arrivano nuovi invii.
Regole aggiuntive (gioca bene!)
Non è possibile leggere o scrivere su risorse esterne. Dato che non invocherai più volte il tuo programma, tutte le informazioni sullo stato possono essere memorizzate internamente.
Non interferire con altri processi / invii. Ciò non significa che non provi a rubare le loro prede, a superarle, ecc. Significa non interferire con l'esecuzione del processo. Questo è a mia discrezione.
I concorrenti sono limitati a un massimo di tre iscrizioni. Se invii di più, segnerò solo i primi tre inviati. Se si desidera revocarne uno, eliminarlo.
Le voci non possono esistere esclusivamente per sostenere altre voci. Ognuno dovrebbe giocare per vincere per il proprio merito.
Il tuo programma può generare un massimo di un processo figlio alla volta ( discendenti totali , non diretti). Ad ogni modo, assicurati di non andare oltre il timeout. Non puoi invocare la
Game
classe stessa in alcun modo.
Risultati - 29 aprile 2014
Ecco i risultati dell'ultimo torneo di dieci round:
Clairvoyant : 1000
EcoCamels : 752
Netcats : 688
RubySpiders : 436
RubyVultures : 431
CivilizedBeasts : 382
LazyPack : 257
I pacchetti inviati prima delle 09:00 EDT 2014/04/29 sono inclusi in questa corsa.
Puoi anche visualizzare i dettagli per ogni round . Per qualche motivo ho deciso di numerare i round all'indietro, quindi inizia con "round 10".
aggiornamenti
23/04/2014: FGreg ha segnalato un bug relativo ai timeout (grazie!). È stata implementata una correzione, quindi i tester vorranno aggiornare il loro codice del programma di controllo.