Test driver • Discussione sulla sfida • Invia avventuriero
( Fonte immagine )
Diversi avventurieri rivali stanno razziando le rovine per il tesoro, ma possono trasportare così tanto alla volta e avere i loro limiti di resistenza. Vogliono ottenere il tesoro più prezioso ed uscire prima di diventare troppo stanchi per continuare. Stanno cercando di diventare il più ricchi possibile dai loro shenanigani saccheggiatori.
gameplay
Ogni avventuriero inizia nella prima stanza della prigione con 1000 punti di resistenza e 50 kg di spazio nel proprio zaino.
Il gioco funziona a turni, con tutti i giocatori che risolvono i loro turni contemporaneamente. Ad ogni turno, puoi effettuare una delle seguenti azioni:
- Passa alla stanza successiva.
- Passa alla stanza precedente.
- Offri resistenza per prendere un tesoro.
- Rilascia un tesoro.
Lo spostamento tra le stanze richiede 10 resistenza, più 1 per ogni 5 kg attualmente nello zaino, arrotondato per eccesso. Ad esempio, un avventuriero che trasporta 3 kg di tesoro richiede 11 resistenza per muoversi e uno che porta 47 kg richiede 20 resistenza per muoversi.
La caduta del tesoro richiede 1 resistenza indipendentemente dal tesoro lasciato cadere.
All'uscita dalle rovine, il giocatore non effettuerà più turni.
Se un giocatore non può compiere nessuna di queste azioni (a causa della mancanza di resistenza o dell'assenza di tesori), il suo avventuriero muore di sfinimento, riversando il tesoro detenuto nella stanza attualmente occupata. Allo stesso modo, se un giocatore tenta di compiere un'azione non valida, il suo avventuriero verrà invece ucciso da una trappola, causando la stessa fuoriuscita di tesori.
offerta
L'offerta minima per un tesoro è di 1 resistenza per 1 kg che pesa il tesoro. Puoi anche offrire punti di resistenza aggiuntivi per avere maggiori probabilità di ottenere il tesoro. La resistenza che è stata offerta viene consumata indipendentemente dal risultato.
Nel caso in cui più giocatori abbiano offerto di prendere lo stesso tesoro, il giocatore che punta più in alto ottiene il tesoro. Se più di un giocatore ha fatto l'offerta più alta, nessuno di loro riceverà il tesoro.
Condizioni di vittoria
Il giocatore con il maggior valore totale di tesori è il vincitore. Nell'improbabile caso di un pareggio, i legami vanno al minor peso totale, quindi al minor numero di tesori, quindi al valore del tesoro più prezioso, il secondo più prezioso, il terzo ... fino a quando il pareggio non viene rotto. Nel caso quasi impossibile che ci sia ancora un pareggio a questo punto, il collaudatore dice "fanculo" e il vincitore viene quindi determinato arbitrariamente.
Nel contesto del torneo, i giocatori saranno classificati con il primo posto che riceve 10 punti, il secondo posto con 9 punti, il terzo posto con 8 punti, ecc ..., con giocatori morti e avventurieri senza tesori che segnano 0 punti.
A proposito delle rovine
- Ogni stanza inizialmente contiene tra e tesori. (Dove è il numero della stanza)
- Ci sono arbitrariamente molte stanze, limitate solo dalla resistenza degli avventurieri e dalla volontà di esplorare.
- Ogni tesoro avrà un valore monetario (in $ interi) e un peso (in kg interi).
- I tesori tendono ad essere più preziosi e abbondanti man mano che approfondisci le rovine.
- Le formule specifiche per generare tesori sono le seguenti: (usando la notazione per i tiri di dado)
- Il peso viene generato per primo utilizzando la formula (minimo 1)
- Il valore del tesoro viene quindi generato tramite (dove è il numero della stanza e è il peso)
Informazioni visibili ai giocatori
Ad ogni turno, i giocatori ottengono le seguenti informazioni:
- Il numero della stanza in cui si trovano attualmente. Questo è 1 indicizzato, quindi concettualmente l'uscita è alla "stanza 0"
- Un elenco di tesori attualmente presenti nella stanza
- Un elenco di altri giocatori che sono anche attualmente nella stanza.
- Il tuo attuale inventario di tesori
- Il tuo attuale livello di resistenza
Coding
Il driver di test può essere trovato qui .
È necessario implementare una sottoclasse di questa Adventurer
classe:
class Adventurer:
def __init__(self, name, random):
self.name = name
self.random = random
def get_action(self, state):
raise NotImplementedError()
def enter_ruins(self):
pass
Hai solo bisogno di sovrascrivere il get_action
metodo. enter_ruins
viene eseguito prima dell'inizio di una partita ed è la tua occasione per preparare tutto ciò che desideri avere pronto per la partita. Non è necessario eseguire l'override __init__
e non è necessario . In caso di __init__
crash, verrai squalificato.
get_action
riceve un singolo argomento che è a namedtuple
con i seguenti campi (in questo ordine, se si preferisce la destrutturazione):
room
: il numero della stanza in cui ci si trova attualmentetreasures
: l'elenco dei tesori nella stanzaplayers
: l'elenco degli altri giocatori nella stanza. Ottieni solo il nome del giocatore in questo modo, quindi non sai quale bot li sta controllando o il loro inventario / resistenza.inventory
: l'elenco dei tesori nel tuo zainostamina
: il tuo attuale livello di resistenza
Questo oggetto fornisce inoltre due proprietà di utilità:
carry_weight
: il peso totale di tutti i tesori che stai trasportandototal_value
: il valore totale di tutti i tesori che stai portando
Gli elenchi treasures
e inventory
contengono namedtuple
s con questi attributi:
name
: il nome del tesoro (per scopi cosmetici)value
: il valore monetario del tesoro in $.weight
: il peso del tesoro in kg
get_action
dovrebbe restituire uno dei seguenti valori / modelli:
'next'
o'previous'
per passare alle stanze successive / precedenti'take', <treasure index>, <bid>
(sì, come una tupla, anche se tecnicamente funzionerà anche una sequenza) per fare offerte sul tesoro all'indice indicato nella lista dei tesori della stanza. Entrambi gli argomenti dovrebbero essere numeri interi. I galleggianti verranno arrotondati per difetto.'drop', <inventory index>
per rilasciare il tesoro trasportato trovato nell'indice indicato. L'indice dovrebbe (naturalmente) essere un numero intero.
Altre restrizioni
- È possibile utilizzare solo l'istanza casuale fornita durante l'inizializzazione per pseudo casualità.
- Qualsiasi altra cosa che potrebbe introdurre il non determinismo comportamentale non è consentita. L'intento qui è di fare in modo che i robot si comportino in modo identico quando viene dato lo stesso seme per aiutare a testare nuovi robot (e potenzialmente bug nel driver di test). Solo la radiazione cosmica dovrebbe causare qualsiasi deviazione / non determinismo.
- Tieni presente che i codici hash sono randomizzati in Python 3, quindi
hash
non è consentito l' utilizzo per qualsiasi processo decisionale.dict
s vanno bene anche quando si utilizza l'ordine di iterazione per le decisioni poiché l'ordine è stato garantito coerente da Python 3.6.
- Non è possibile aggirare il test driver usando
ctypes
hack oinspect
stack voodoo (o qualsiasi altro metodo). Ci sono alcune cose straordinariamente spaventose che puoi fare con quei moduli. Per favore, no.- Ogni bot è sottoposto a sandbox ragionevolmente bene tramite copie difensive e l'immutabilità naturale di
namedtuple
s, ma ci sono alcune lacune / exploit non percorribili. - Altre funzionalità da
inspect
ectypes
possono essere utilizzate purché non vengano utilizzate per eludere la funzionalità del controller. - Non è consentito alcun metodo per catturare istanze di altri robot nel tuo gioco attuale.
- Ogni bot è sottoposto a sandbox ragionevolmente bene tramite copie difensive e l'immutabilità naturale di
- I robot dovrebbero operare da soli e non possono coordinarsi con altri robot in alcun modo per alcuno scopo. Ciò include la creazione di due robot con obiettivi diversi in modo tale che uno si sacrifichi per il successo dell'altro. Una volta che ci sono più di 10 concorrenti, in realtà non avrai la garanzia di avere i due robot nello stesso gioco e i nomi degli avventurieri non daranno alcuna indicazione sulla classe dei bot, quindi questi tipi di strategie sono comunque limitati.
- Al momento non ci sono restrizioni rigide sui tempi di esecuzione, tuttavia mi riservo il diritto di limitarlo duramente in futuro se i tornei iniziano a richiedere troppo tempo. Sii ragionevole e cerca di continuare a girare l'elaborazione a meno di 100 ms , poiché non prevedo la necessità di limitarla al di sotto di tale soglia. (I tornei dureranno circa 2 ore se tutti i robot impiegano circa 100 ms per turno.)
- La tua classe bot deve essere nominata in modo univoco tra tutti gli invii.
- Potresti non ricordare nulla tra i giochi. (Tuttavia, puoi ricordare le cose tra i turni )
- Non modificare sys.modules. Qualsiasi elemento esterno alle variabili di istanza deve essere trattato come una costante.
- Non è possibile modificare il codice di alcun bot a livello di codice, incluso il proprio.
- Ciò include l'eliminazione e il ripristino del codice. Questo per semplificare il debug e i tornei.
- Qualsiasi codice che causa l'arresto anomalo del controller verrà immediatamente squalificato. Sebbene vengano rilevate la maggior parte delle eccezioni, alcune potrebbero scivolare e le segfault non sono raggiungibili. (Sì, puoi segfault in Python grazie a
ctypes
)
Inseriti
Per facilitare lo scraping delle risposte, indica il nome del tuo bot nella parte superiore della risposta con a #Header1
e assicurati che la tua risposta includa almeno un blocco di codice (verrà utilizzato solo il primo nella tua risposta). Non è necessario includere importazioni o documenti, poiché verranno aggiunti automaticamente dal raschietto.
Sarò più propenso a valutare le risposte con spiegazioni dettagliate e comprensibili. Altri probabilmente si comporteranno allo stesso modo.
In parole povere, la tua risposta dovrebbe essere formattata in questo modo:
# Name of Bot
Optional blurb
#imports go here
class BotName(Adventurer):
#implementation
Explanation of bot algorithm, credits, etc...
(reso come)
Nome del Bot
Blurb opzionale
#imports go here class BotName(Adventurer): #implementation
Spiegazione di algoritmo bot, crediti, ecc ...
Esecuzione del test driver localmente
Avrai bisogno di Python 3.7+ e ti consiglio di installarlo anche tabulate
tramite pip. La rimozione di questa pagina per gli invii richiede inoltre lxml
e requests
. Dovresti anche usare un terminale con supporto per le fughe di colore ANSI per i migliori risultati. Informazioni su come configurarlo in Windows 10 sono disponibili qui .
Aggiungi il tuo bot a un file in una sottodirectory nella stessa directory di ruins.py
( ruins_bots
per impostazione predefinita) e assicurati di aggiungere from __main__ import Adventurer
nella parte superiore del modulo. Questo viene aggiunto ai moduli quando lo scraper scarica la tua presentazione e, sebbene sia decisamente confuso, questo è il modo più semplice per assicurarsi che il tuo bot abbia correttamente accesso Adventurer
.
Tutti i robot in quella directory verranno caricati dinamicamente in fase di esecuzione, quindi non sono necessarie ulteriori modifiche.
Torneo
Il vincitore finale sarà determinato in una serie di partite con un massimo di 10 robot in ogni partita. Se ci sono più di 10 invii totali, i primi 10 robot saranno determinati partizionandoli sistematicamente in gruppi di 10 fino a quando ogni bot avrà giocato (esattamente) 20 partite. I primi 10 robot verranno selezionati da questo gruppo con i punteggi di reset e giocheranno fino a quando il primo posto non avrà raggiunto un vantaggio di 50 punti sul secondo posto o fino a quando non saranno state giocate 500 partite.
Fino a quando non ci saranno almeno 10 invii, gli spazi vuoti saranno riempiti con "Drunkards" che vagano casualmente tra le rovine e prendono (e occasionalmente lasciano cadere) tesori casuali fino a quando non si esauriscono la resistenza e devono dirigersi verso l'uscita.
I tornei verranno ripetuti settimanalmente in caso di nuovi invii. Questa è una sfida KOTH aperta senza una data di fine prestabilita.
Classifica
Dalla corsa del 4 maggio 2019 alle 16:25 MDT: (2019-05-04 16:25 -6: 00)
Seed: K48XMESC
Bot Class | Score | Mean Score
--------------+---------+--------------
BountyHunter | 898 | 7.301
Scoundrel | 847 | 6.886
Accountant | 773 | 6.285
Ponderer | 730 | 5.935
Artyventurer | 707 | 5.748
PlanAhead | 698 | 5.675
Sprinter | 683 | 5.553
Accomodator | 661 | 5.374
Memorizer | 459 | 3.732
Backwards | 296 | 2.407
Aggiornamento - 15 aprile: un paio di aggiornamenti / chiarimenti
Aggiornamento - 17 aprile: vietare un paio di casi limite notevoli di azioni nefaste come la modifica del codice di altri robot.
Aggiornamento - 4 maggio: ricompensa assegnata a Sleafar per aver distrutto definitivamente Backwards. Congratulazioni!
pip
installato e attivato PATH
(impostazione predefinita per le nuove installazioni AFAIK), da Windows è possibile eseguire pip install modulename
dal prompt dei comandi. Per altre circostanze (che non conosco), vai su pip , cerca il modulo necessario e scegli un'opzione.