In questa sfida, giocherai al rumoroso dilemma del prigioniero iterato.
Il dilemma del prigioniero è uno scenario nella teoria dei giochi in cui ci sono due giocatori, ognuno con due opzioni: cooperare o difetto. Ogni giocatore fa meglio per se stesso se difettano che se cooperano, ma entrambi i giocatori preferirebbero il risultato in cui entrambi i giocatori cooperano a quello in cui entrambi i giocatori difettano.
Il dilemma del prigioniero ripetuto è lo stesso gioco, tranne per il fatto che giochi ripetutamente contro lo stesso avversario e sai cosa ha giocato il tuo avversario in passato. Il tuo obiettivo è sempre quello di accumulare il punteggio più alto per te, indipendentemente da come lo fa il tuo avversario.
Il rumoroso dilemma del prigioniero ripetuto introduce un po 'di rumore nella comunicazione. La tua conoscenza di ciò che il tuo avversario ha giocato in passato avrà un po 'di rumore introdotto. Saprai anche quali mosse hai fatto in passato. La frequenza del rumore è costante per un round contro lo stesso avversario, ma diversa tra round diversi.
Sfida
In questa sfida, scriverai un programma Python 3 per giocare al rumoroso dilemma del prigioniero iterato.
Il tuo programma riceverà tre input:
Le tue mosse, senza capovolgere casualmente.
Le mosse del tuo avversario, con lanci casuali applicati.
Una variabile di stato, che inizia come un elenco vuoto ogni round e che è possibile modificare se lo si desidera. Puoi ignorarlo se non vuoi usarlo.
Il tuo programma dovrebbe produrre 'c'
per cooperare o 'd'
per difettoso.
Ad esempio, ecco un programma che coopera se l'avversario ha collaborato almeno il 60% delle volte in passato, dopo l'applicazione di lanci casuali, e per i primi 10 lanci:
def threshold(my_plays, their_flipped_plays, state):
if len(their_flipped_plays) < 10:
return 'c'
opp_c_freq = their_flipped_plays.count('c')/len(their_flipped_plays)
if opp_c_freq > 0.6:
return 'c'
else:
return 'd'
Se non conosci Python, scrivi la tua richiesta in pseudocodice e qualcuno (io o un altro membro del sito) può creare il programma Python corrispondente.
gameplay
Il corridore del torneo può essere trovato qui: gioco rumoroso . Corri noisy-game.py
per correre il torneo. Terrò quel repository aggiornato con nuovi invii. Programmi di esempio sono disponibili in basic.py
.
Il punteggio complessivo di un programma è il totale del suo punteggio in 100 partite giocate.
Un gioco consiste in match-round-robin di ciascun giocatore contro ogni giocatore, incluso se stesso. Un matchup è composto da 100 round. Un round è composto da 300 mosse, ognuna delle quali prevede l'output 'c'
o 'd'
.
Il tuo invio giocherà un matchup contro ogni invio, incluso il tuo. Ogni incontro sarà composto da 100 round. Durante ogni round, una probabilità di inversione verrà scelta in modo uniforme in modo casuale [0, 0.5]
.
Ogni round sarà composto da 300 mosse. Ad ogni mossa, entrambi i programmi riceveranno tutte le riproduzioni precedenti che hanno tentato, e tutte le riproduzioni precedenti eseguite dall'altro programma, dopo l'applicazione dei flip, e una variabile di stato, che è un elenco mutabile che il programma può modificare se lo desidera. I programmi produrranno le loro mosse.
Le mosse vengono segnate come segue: se un programma gioca a 'c'
, il programma avversario ottiene 2 punti. Se un programma suona a 'd'
, quel programma ottiene 1 punto.
Quindi, ogni mossa viene lanciata indipendentemente con probabilità pari alla probabilità di ribaltamento e memorizzata per essere mostrata all'avversario.
Dopo che tutti i round sono stati giocati, sommiamo il numero di punti ottenuti da ciascun giocatore in ogni matchup. Quindi, utilizziamo il seguente sistema di punteggio per calcolare il punteggio di ciascun giocatore per il gioco. Questo punteggio viene eseguito dopo che tutti i matchup sono stati completati.
punteggio
Useremo il punteggio evolutivo. Ogni programma inizia con lo stesso peso. Quindi, i pesi vengono aggiornati come segue, per 100 iterazioni, utilizzando i totali dei punti del gioco:
Il nuovo peso di ciascun programma è proporzionale al prodotto del suo peso precedente e al suo punteggio medio totale, ponderato dai pesi dei suoi avversari.
Vengono applicati 100 di questi aggiornamenti e i pesi finali sono il punteggio di ciascun programma per quella corsa del gioco.
I punteggi complessivi saranno la somma di oltre 100 esecuzioni del gioco.
I giocatori avranno tutte le risposte valide a questa sfida, oltre a sei programmi di base per iniziare.
Avvertenze
Non modificare gli ingressi. Non tentare di influire sull'esecuzione di altri programmi, se non attraverso la cooperazione o il difetto. Non fare una sottomissione sacrificale che tenti di riconoscere un'altra sottomissione e avvantaggiare quell'avversario a proprie spese. Le scappatoie standard sono vietate.
EDIT: le presentazioni non possono duplicare esattamente nessuno dei programmi di base o precedenti.
Se avete domande non esitate a chiedere.
Risultati attuali
nicht_genug: 40.6311
stealer: 37.1416
enough: 14.4443
wait_for_50: 6.947
threshold: 0.406784
buckets: 0.202875
change_of_heart: 0.0996783
exploit_threshold: 0.0670485
kickback: 0.0313357
tit_for_stat: 0.0141368
decaying_memory: 0.00907645
tit_for_whoops: 0.00211803
slider: 0.00167053
trickster: 0.000654875
sounder: 0.000427348
tit_for_tat: 9.12471e-05
stubborn_stumbler: 6.92879e-05
tit_for_time: 2.82541e-05
jedi2sith: 2.0768e-05
cooperate: 1.86291e-05
everyThree: 1.04843e-05
somewhat_naive: 4.46701e-06
just_noise: 1.41564e-06
growing_distrust: 5.32521e-08
goldfish: 4.28982e-09
vengeful: 2.74267e-09
defect: 3.71295e-10
alternate: 2.09372e-20
random_player: 6.74361e-21
Risultati con sole risposte a questa domanda e programmi di base che ignorano il gioco dell'avversario:
nicht_genug: 39.3907
stealer: 33.7864
enough: 20.9032
wait_for_50: 5.60007
buckets: 0.174457
kickback: 0.0686975
change_of_heart: 0.027396
tit_for_stat: 0.024522
decaying_memory: 0.0193272
tit_for_whoops: 0.00284842
slider: 0.00153227
sounder: 0.000472289
trickster: 0.000297515
stubborn_stumbler: 3.76073e-05
cooperate: 3.46865e-05
tit_for_time: 2.42263e-05
everyThree: 2.06095e-05
jedi2sith: 1.62591e-05
somewhat_naive: 4.20785e-06
just_noise: 1.18372e-06
growing_distrust: 6.17619e-08
vengeful: 3.61213e-09
goldfish: 3.5746e-09
defect: 4.92581e-10
alternate: 6.96497e-20
random_player: 1.49879e-20
vincente
Il concorso rimarrà aperto a tempo indeterminato, poiché verranno inviati nuovi invii. Tuttavia, dichiarerò un vincitore (accetto una risposta) in base ai risultati 1 mese dopo la pubblicazione della domanda.
exploit_threshold()
più volte come exploit_threshold1()
, ecc. e le ho aggiunte players
all'elenco. Perché ottengo risultati molto diversi per strategie identiche?