Dilemma del prigioniero v.2 - Battle Royale


15

In questa domanda , è stato ideato un gioco in cui i giocatori si affronterebbero a coppie in coppia nel Dilemma del Prigioniero, per determinare quale strategia iterativa ha segnato il punteggio più alto contro gli altri.

In questa domanda , ho escogitato un modo per più persone di giocare il dilemma dei prigionieri l'una contro l'altra allo stesso tempo. In questa variante, la matrice di payoff non è necessaria, con ogni risultato tra ogni coppia di due giocatori che è la somma di due decisioni funzionalmente indipendenti.

Il tuo compito è costruire un'intelligenza artificiale per giocare a questa versione simmetrica e generalizzata del dilemma del prigioniero multiplayer che raggiungerà il punteggio più alto possibile.


Le regole del gioco

In ogni round di questo multiplayer, il multi-round Dilemma del prigioniero, un giocatore Apuò decidere di "prendere 1" da un altro giocatore B. In questa circostanza, Ail punteggio aumenta di 1, mentre Bil punteggio diminuisce di 2. Questa decisione può avvenire tra ogni coppia di giocatori ordinata.

Questa è l'unica decisione presa per ogni giocatore - o "prendere 1" o non "prendere 1" da ogni altro giocatore, che sono omologhi rispettivamente alla defezione e alla cooperazione. La matrice di payoff effettiva tra due giocatori P1e si P2presenta come segue:

  P1/P2     P1 Take1   P1 Don't
P2 Take1     -1/-1      -2/+1
P2 Don't     +1/-2       0/ 0

Procedura del torneo

Il gioco consisterà in P * 25round, dove Pè il numero di giocatori partecipanti. Tutti i giocatori iniziano con un punteggio di 0. Ogni round consisterà nella seguente procedura:

All'inizio di un round, a ciascun programma verrà fornita una cronologia dei round precedenti dall'input standard , nel seguente formato:

  • Una linea che contiene 3 numeri, P, D, e N.

    • Pè il numero totale di giocatori nel gioco. Ad ogni giocatore viene assegnato in modo casuale un numero ID da 1a Pall'inizio del gioco.

    • D è l'ID del giocatore corrente.

    • N è il numero di round giocati.

  • Nlinee, ciascuna linea che rappresenta i risultati di un round. Sulla linea kdi N, ci sarà un certo numero n_kdi coppie ordinate (a, b), separate da spazi, che indicano che il giocatore con ID a"ha preso 1" dal giocatore con ID bin quel round.

  • Un numero uniformemente casuale Rda 0a 18446744073709551615(2 64 - 1), per agire come seme pseudocasuale. Questi numeri verranno letti da un file pre-generato, che verrà rilasciato alla fine del torneo in modo che le persone possano verificare i risultati da soli.

  • Una riga aggiuntiva che rappresenta una qualche forma di stato da leggere nel tuo programma, se il tuo programma ha prodotto un simile output nel round precedente. All'inizio del gioco, questa riga sarà sempre vuota. Questa riga non verrà modificata né dal codice di punteggio né da altri programmi.

Ogni programma utilizzerà quindi la propria strategia per produrre quanto segue allo standard output :

  • Un elenco di Knumeri, che sono gli ID dei programmi che "prenderà 1" da questo round. Un output vuoto significa che non farà nulla.

  • Facoltativamente, una riga aggiuntiva che rappresenta una qualche forma di stato da passare ai round successivi. Questa riga esatta verrà restituita al programma nel turno successivo.

Di seguito è riportato un esempio di input per l'inizio del gioco per un giocatore ID 3in una partita a 4 giocatori:

4 3 0
4696634734863777023

Di seguito è riportato un esempio di input per lo stesso gioco con alcuni round già giocati:

4 3 2
(1, 2) (1, 3) (1, 4) (4, 2)
(1, 3) (2, 1) (2, 4) (3, 1) (4, 1)
4675881156406346380

Ad ogni programma verrà fornito esattamente lo stesso input per un round tranne il numero ID Dche è univoco per ciascun programma.

Di seguito è riportato un esempio di output in cui il giocatore 3prende 1 da tutti gli altri:

1 2 4

Alla fine di tutti i round richiesti, il giocatore con il punteggio finale più alto sarà il vincitore.


Sequenza temporale

La codifica per questo torneo durerà per un totale di 7 giorni. La scadenza per la presentazione è 2014-05-09 00:00 UTC.

Non pubblicare programmi effettivi prima di questa data: pubblica l'hash SHA256 del codice sorgente del tuo programma come impegno. Puoi modificare questo hash in qualsiasi momento prima della scadenza, ma gli impegni pubblicati dopo la scadenza non saranno accettati per il giudizio. (Si prega di utilizzare la notazione di base 64 per gli hash, poiché il mio programma di verifica sputa la base 64 ed è una notazione più compatta.)

Al termine della scadenza, avrai 1 giorno (fino a 2014-05-10 00:00 UTC) per pubblicare il codice sorgente effettivo del tuo programma per l'invio. Se l'hash SHA256 del tuo codice sorgente pubblicato non corrisponde ad alcun hash che hai pubblicato prima della scadenza, il tuo codice non verrà accettato nel torneo.

Dopodiché, scaricherò tutte le presentazioni sul mio computer ed eseguirò tutte le voci del torneo in questo battle royale, sperando di pubblicare i risultati entro 2 giorni da allora, entro 2014-05-12 00:00 UTC.

Accetterò la risposta con il punteggio più alto e assegnerò una taglia di +100 a quella risposta se il suo punteggio finale è maggiore di 0.

Al termine del torneo, posterò il file seme casuale utilizzato per eseguire la competizione e le persone potrebbero iniziare a pubblicare altre soluzioni cercando di superare quelle utilizzate nel torneo. Tuttavia, non contano per l'accettazione o la generosità.

La macchina host

Eseguirò queste soluzioni su una macchina virtuale sul mio computer. Questa macchina virtuale eseguirà Ubuntu Linux 14.04, con 2 gigabyte di RAM. La mia macchina base ha un processore Intel i7-2600K a 3,40 GHz.

Requisiti

Il tuo programma deve essere scritto in una lingua per la quale esiste un compilatore o un interprete che compilerà il tuo programma ed è prontamente disponibile per l'ultima versione di Ubuntu Linux, in modo che io possa eseguire tutti gli invii e giudicarli in una macchina virtuale.

Il tuo programma non deve richiedere altro che 2.000 secondseseguire ogni round. Se il tuo programma si esaurisce o produce un errore, il suo output verrà considerato vuoto per quel round.

Il tuo programma deve essere deterministico; cioè, deve sempre restituire lo stesso output per lo stesso input. Sono consentite soluzioni pseudocasuali; tuttavia, la loro casualità deve dipendere dal seme casuale datogli come input e nient'altro. Il file seme è stato generato usando Python os.urandom. Contiene un totale di 500 righe (se necessario ne verranno generate altre) e l'hash SHA256 lo è K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=. Verrà caricato qui una volta terminato il torneo.


Impianti

Per dare il via alle cose, ci saranno quattro "piante", che rappresentano strategie ingenui iniziali. Questi giocheranno nel torneo insieme ai tuoi invii. Tuttavia, nel caso improbabile che uno di loro vinca, il punteggio più alto ottenuto da un giocatore diverso da una pianta sarà considerato il vincitore.

Per calcolare l'hash del file di ogni impianto, sostituisci ogni gruppo di 4 spazi con una scheda, dal momento che al formattatore qui non piacciono i caratteri di tabulazione.

The Lazy - non fa mai niente.

n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=

pass

The Greedy : ne prende sempre 1 da tutti gli altri.

+k0L8NF27b8+Xf50quRaZFFuflZhZuTCQOR5t5b0nMI=

import sys

line1 = sys.stdin.readline()
n = [int(i) for i in line1.split()]
for i in range(n[0]):
    if i+1 != n[1]:
        print i+1,
print

The Wrathful : prende 1 da tutti gli altri nel primo round e ne prende 1 da tutti quelli che ne hanno preso 1 nel round precedente in seguito.

Ya2dIv8TCh0zWzRfzUIdFKWj1DF9GXWhbq/uN7+CzrY=

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []

if rounds == 0:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        lines.append(sys.stdin.readline())
    lastline = lines[-1]
    takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
    for take in takes:
        sides = [int(i) for i in re.findall(r'[0-9]+', take)]
        if sides[1] == pid:
            print sides[0],
    print

The Envious : prende 1 dal 50% dei giocatori con il punteggio più alto attualmente escluso, arrotondando per difetto.

YhLgqrz1Cm2pEcFlsiIL4b4MX9QiTxuIOBJF+wvukNk=

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []
scores = [0] * players

if rounds == 0:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        takes = re.findall(r'\([0-9]+, [0-9]+\)', sys.stdin.readline())
        for take in takes:
            sides = [int(i) for i in re.findall(r'[0-9]+', take)]
            scores[sides[0] - 1] += 1
            scores[sides[1] - 1] -= 2
    score_pairs = [(i+1, scores[i]) for i in range(players)]
    score_pairs.sort(key=lambda x:(x[1], x[0]))
    score_pairs.reverse()
    taken = 0
    j = 0
    while taken < (players) / 2:
        if score_pairs[j][0] != pid:
            print score_pairs[j][0],
            taken += 1
        j += 1

In un torneo di 100 round proprio tra questi quattro, ricevono punteggi di:

Lazy: -204
Greedy: -100
Wrathful: -199
Envious: -199

Programma di valutazione

Ho pubblicato il programma del giudice che userò su Github . Scaricalo e provalo. (E magari correggere un bug o due se ne trovi uno.: P)

Al momento non ha opzioni di compilazione per nient'altro che Python. Includerò quelli in seguito - se le persone potessero contribuire con script di compilazione o interpretazione per altre lingue, sarei molto grato.


Fase 2: invio del codice sorgente

Ho pubblicato un nuovo ramo tournamentnel repository Github per il contest, contenente il file pd_rand e altre voci di impianto. Puoi pubblicare qui il tuo codice sorgente o inviarlo a quel ramo come richiesta pull.

L'ordine dei concorrenti sarà il seguente:

'begrudger'
'regular'
'patient'
'lazy'
'backstab'
'bully'
'lunatic'
'envious'
'titfortat'
'greedy'
'wrathful'
'judge'
'onepercent'

Punteggi finali

L'output del mio programma di test:

Final scores:
begrudger -2862
regular -204
patient -994
lazy -2886
backstab -1311
bully -1393
lunatic -1539
envious -2448
titfortat -985
greedy -724
wrathful -1478
judge -365
onepercent -1921

Classifica:

 1. regular      -204
 2. judge        -365
 3. greedy       -724
 4. titfortat    -985
 5. patient      -994
 6. backstab    -1311
 7. bully       -1393
 8. wrathful    -1478
 9. lunatic     -1539
10. onepercent  -1921
11. envious     -2448
12. begrudger   -2862
13. lazy        -2886

Quindi si scopre che il vincitore è davvero un giocatore - è The Regular, con -204 punti!

Sfortunatamente, il suo punteggio non era positivo, ma non possiamo aspettarci che in una simulazione del dilemma del prigioniero iterato in cui tutti giocano per vincere.

Alcuni risultati sorprendenti (almeno che pensavo fossero sorprendenti):

  • The Greedy ha segnato più di Tit per Tat e, in effetti, è generalmente più alto della maggior parte dei marcatori.

  • Il Judge, che doveva essere una sorta di personaggio di "moralità" (in pratica ne prendeva 1 da chiunque avesse preso 1 da qualcuno un numero superiore alla media) finì per segnare un punteggio piuttosto alto, mentre nei test di simulazione, in realtà ottenere un punteggio piuttosto basso.

E altri che (pensavo) non erano così sorprendenti:

  • Il paziente ha segnato ben 484 punti in più di The Wrathful. Vale davvero la pena collaborare quella prima volta.

  • L'uno per cento molto rapidamente non aveva quasi nessuno a calciare mentre erano giù. Sembra che l'1% sia in grado di rimanere tale solo perché hanno più giocatori nel gioco.

Ad ogni modo, ora che il torneo è finito, sentiti libero di pubblicare tutti i giocatori extra che desideri e provalo con loro usando il programma arbitrale.


3
Pubblicare la fonte nel programma di controllo e / o negli impianti danneggerebbe qualsiasi cosa? Sappiamo comunque cosa fanno e preferirei essere in grado di provare qualcosa senza scrivere cinque programmi extra.
Geobits

2
Non capisco. C'è una sorta di penalità per tutti coloro che prendono 1 per tutto il tempo? Non sarebbe il più vantaggioso prenderne sempre 1?
DankMemes,

1
Come può l'avido non massimizzare il danno? Se prendiamo da un altro giocatore, l'altro giocatore può ottenere solo -1 o -2, mentre se non lo prendiamo, l'altro giocatore può ottenere 1 o 0. Ovviamente prendere 1 da un altro giocatore massimizzerà il danno. E così Greedy non perderà mai. E vincerà quasi sempre, a meno che anche tutti gli avversari non siano avidi, come hai detto tu.
solo

1
@Trimsty Quando la sfida è iniziata per la prima volta, il codice per le piante non è stato mostrato. Durante l'intera fase di codifica, non abbiamo potuto vedere altre risposte. I duplicati avrebbero potuto accadere puramente per caso, scegliendo l' ovvia strategia molto ovvia .
Geobits

2
@justhalf Se in realtà hai letto qualche ricerca sulle strategie nel dilemma del prigioniero ripetuto, sapresti che quello che stai dicendo è falso. L' articolo di Wikipedia è un buon punto di partenza.
Joe Z.

Risposte:


3

The Regular

La versione di questa voce che ho scelto per il torneo (SHA-256 :)ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc= usa la strategia " Random sucker " di Joey (anche se con un cambiamento minore e probabilmente insignificante), che è arrivata al secondo posto nell'ultimo contest. Sfortunatamente, una versione più recente ed efficace è stata inviata solo 3 minuti e 25 secondi prima della scadenza ha un bug grave, quindi non può essere utilizzata. Tuttavia, questa versione funziona ancora relativamente bene.

<?php

$secretKey = '95CFE71F76CF4CD2';
$hashOutput = '';
$hashSeq = 0;
$hashIndex = 64;

function psRand($min = null, $max = null) {
    global $secretKey, $state, $hashOutput, $hashSeq, $hashIndex;
    if ($hashIndex > 56) {
        $hashOutput = hash_hmac('sha256', ++$hashSeq . ' ' . $state['rand'], $secretKey);
        $hashIndex = 0;
    }

    $num = (int)(hexdec(substr($hashOutput, $hashIndex, 8)) / 2);
    $hashIndex += 8;

    return $min === null ? $num : (int)($min + $num * ($max - $min + 1) / 2147483648);
}

$line = fgets(STDIN);
sscanf($line, "%d %d %d", $numPlayers, $myPlayerId, $roundsPlayed);
$roundsCount = 25 * $numPlayers;
$roundsRemaining = $roundsCount - $roundsPlayed - 1;

$betrayalCount = array_fill(1, $numPlayers, 0);
for ($round = 0; $round < $roundsPlayed; ++$round) {
    $line = fgets(STDIN);
    preg_match_all('/\((\d+), (\d+)\)/', $line, $matches, PREG_SET_ORDER);
    foreach ($matches as $m) {
        $defector = (int)$m[1];
        $victim = (int)$m[2];
        if ($victim === $myPlayerId) {
            ++$betrayalCount[$defector];
        }
    }
}

$hashOutput = rtrim(fgets(STDIN), "\n");
$state = unserialize(rtrim(fgets(STDIN), "\n"));
if (!$state) {
    $state = ['rand' => ''];
}

$state['rand'] = hash_hmac('sha256', $state['rand'] . $line, $secretKey);
$victims = [];

if ($roundsPlayed > 1) {
    for ($other = 1; $other <= $numPlayers; ++$other) {
        if ( $other === $myPlayerId) {
            continue;
        }

        if ($betrayalCount[$other] > 7 || psRand() % 1024 < 32 || !$roundsRemaining ) {
            $victims[] = $other;
        }
    }
}

echo implode(' ', $victims), "\n", serialize($state), "\n";

La versione buggy ha un hash SHA-256 di 2hNVloFt9W7/uA5aQXg+naG9o6WNmrZzRf9VsQNTMwo=:

<?php

$secretKey = '95CFE71F76CF4CD2';
$hashOutput = '';
$hashSeq = 0;
$hashIndex = 64;

function psRand($min = null, $max = null) {
    global $secretKey, $state, $hashOutput, $hashSeq, $hashIndex;
    if ($hashIndex > 56) {
        $hashOutput = hash_hmac('sha256', ++$hashSeq . ' ' . $state['rand'], $secretKey);
        $hashIndex = 0;
    }

    $num = (int)(hexdec(substr($hashOutput, $hashIndex, 8)) / 2);
    $hashIndex += 8;

    return $min === null ? $num : (int)($min + $num * ($max - $min + 1) / 2147483648);
}

$line = fgets(STDIN);
sscanf($line, "%d %d %d", $numPlayers, $myPlayerId, $roundsPlayed);
$roundsCount = 25 * $numPlayers;
$roundsRemaining = $roundsCount - $roundsPlayed - 1;

$betrayalCount = array_fill(1, $numPlayers, 0);
$scoreWindow = array_fill(1, $numPlayers, array_fill(1, $numPlayers, 0));
$lastMove = array_fill(1, $numPlayers, array_fill(1, $numPlayers, false));
for ($round = 0; $round < $roundsPlayed; ++$round) {
    $line = fgets(STDIN);
    preg_match_all('/\((\d+), (\d+)\)/', $line, $matches, PREG_SET_ORDER);
    foreach ($matches as $m) {
        $defector = (int)$m[1];
        $victim = (int)$m[2];
        if ($victim === $myPlayerId) {
            ++$betrayalCount[$defector];
        }
TAB>TAB>if ($round >= $roundsPlayed - 10) {
TAB>TAB>TAB>$scoreWindow[$defector][$victim] -= 2;
TAB>TAB>TAB>$scoreWindow[$victim][$defector] += 1;
TAB>TAB>}
TAB>TAB>if ($round === $roundsPlayed - 1) {
TAB>TAB>TAB>$lastMove[$defector][$victim] = true;
TAB>TAB>}
    }
}

$line .= fgets(STDIN);
$state = unserialize(rtrim(fgets(STDIN), "\n"));
if (!$state) {
    $state = ['rand' => '', 'copying' => array_fill(1, $numPlayers, 0)];
}

$state['rand'] = hash_hmac('sha256', $state['rand'] . $line, $secretKey);
$victims = [];

if ($roundsPlayed > 1) {
    for ($other = 1; $other <= $numPlayers; ++$other) {
        if ($other === $myPlayerId) {
            continue;
        }

TAB>TAB>if ($roundsPlayed >= 10) {
TAB>TAB>TAB>$myScore = $scoreWindow[$other][$myPlayerId];
TAB>TAB>TAB>foreach ($scoreWindow[$other] as $betterPlayer => $betterScore) {
TAB>TAB>TAB>TAB>if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {
TAB>TAB>TAB>TAB>TAB>$state['copying'][$other] = $betterPlayer;
TAB>TAB>TAB>TAB>}
TAB>TAB>TAB>}
TAB>TAB>}

TAB>TAB>if ($state['copying'][$other]) {
TAB>TAB>TAB>if ($lastMove[$state['copying'][$other]][$other]) {
TAB>TAB>TAB>TAB>$victims[] = $other;
TAB>TAB>TAB>}
        } elseif ($betrayalCount[$other] > 7 || psRand() % 1024 < 32 || !$roundsRemaining ) {
            $victims[] = $other;
        }
    }
}

echo implode(' ', $victims), "\n", serialize($state), "\n";

Per risolverlo, effettuare queste sostituzioni:

  • Sostituisci $hashOutput = rtrim(fgets(STDIN), "\n");con $line .= fgets(STDIN);(non quello che conta davvero).
  • Sostituisci if ($betterScore >= 3 * $myScore) {con if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {(questo è ciò che l'ha ucciso).

1
3 minuti e 25 secondi prima della scadenza. Sono impressionato.
Joe Z.

Solo un promemoria amichevole: la fase di programmazione è terminata; hai un giorno per pubblicare il tuo codice sorgente. (La procedura è in fondo alla domanda.)
Joe Z.

Indipendentemente dal fatto che io utilizzi la tua vecchia versione o la tua nuova versione, il tuo programma esce comunque per primo. Congratulazioni!
Joe Z.

2

Uno percento

b61189399ae9494b333df8a71e36039f64f1d2932b838d354c688593d8f09477

Guarda in basso quei prigionieri che considera sotto di lui.


Prende semplicemente da chiunque abbia punti inferiori o uguali a se stesso. Il presupposto è che quei prigionieri hanno meno probabilità di ricevere in cambio (o ne avrebbero di più). Non so quanto sia buono un presupposto, ma è su questo che sta operando.

Prende anche da tutti nell'ultimo round. Non c'è letteralmente un aspetto negativo in questo, dal momento che nessuno può vendicarsi-rubare dopo quello.

Se hai problemi a ottenere l'hash a causa di tab / spazi dal codice incollato, ecco un link al file stesso.

import java.io.BufferedReader;
import java.io.InputStreamReader;

class OnePercent {

    static int numPlayers;
    static int me;
    static int turn;
    static int[] values;

    public static void main(String[] args) {
        if(!readInput())
            return;
        String out = "";
        for(int i=1;i<values.length;i++){
            if(i != me && (values[i] <= values[me] || turn > (numPlayers*25-2)))
                out += i + " ";
        }
        out.trim();
        System.out.print(out);
    }

    static boolean readInput(){
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String line = reader.readLine();
            if(line == null)
                return false;
            String[] tokens = line.split(" ");
            if(tokens.length < 3)
                return false;
            numPlayers = Integer.valueOf(tokens[0]);
            me = Integer.valueOf(tokens[1]);
            turn = Integer.valueOf(tokens[2]);
            values = new int[numPlayers+1];
            for(int i=0;i<values.length;i++)
                values[i]=0;

            for(int i=0;i<turn;i++){
                line = reader.readLine();
                line = line.replaceAll("[)]",",");
                line = line.replaceAll("[( ]", "");
                tokens = line.split(",");
                for(int j=0;j<tokens.length-1;j+=2){
                    int thief = Integer.valueOf(tokens[j]);
                    int poor = Integer.valueOf(tokens[j+1]);
                    if(thief<1||poor<1||thief>numPlayers||poor>numPlayers)
                        continue;
                    values[thief]++;
                    values[poor] -= 2;
                }
            }
            reader.close();
        } catch(Exception e) {
            return false;
        }
        return true;
    }

}

Ricordate che potete continuare a apportare miglioramenti alle vostre soluzioni fino alla 05-09 00:00scadenza.
Joe Z.

Sì. Se penso a qualcos'altro, lo farò. Tuttavia, faccio fatica a credere che qualcuno reclamerà quella generosità. Andare positivo in questo gioco sarebbe ... insolito.
Geobits

Sì, non mi aspetto che qualcuno raggiunga effettivamente quella taglia. Sarebbe davvero un risultato che sfida la teoria dei giochi, probabilmente vale la pena di soldi veri in possibilità di ricerca (una soluzione che funziona meglio di due persone che collaborano sempre! Immagina!) Invece di una misera reputazione di 100 su Exchange Exchange.
Joe Z.

1
@JoeZ. Con la consapevolezza di cosa farebbero gli altri, certo;) Contro voci sconosciute, non riesco a vedere una strategia molto affidabile . Gli outlier saranno outlier, immagino.
Geobits

1
Penso che lo accetterò ancora questa volta, dal momento che la strategia del tuo codice non sembra essere nulla di malevolo e ci sono troppi pochi partecipanti per importare comunque.
Joe Z.

1

Ecco alcune altre piante che parteciperanno al gioco. Questi sono più avanzati e il loro codice sorgente non verrà rivelato fino alla fine della fase di codifica.

Proprio come i quattro impianti nella domanda, se riescono a segnare un punteggio più alto di tutti gli altri giocatori, solo il punteggio più alto raggiunto da un concorrente reale sarà considerato un vincitore.


Il bullo

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

Prende in giro le persone.


Il giudice

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

Punisce i trasgressori.


The Lunatic

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

Non ha idea di cosa stia facendo.


Il paziente

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

Non fa mai la prima mossa.


Se queste sono solo piante, non vedo alcun motivo per non permetterle. Se sono concorrenti che possono vincere , penso che sia giusto che tu ottenga una sola iscrizione per i commenti sopra.
Geobits

Ho brevemente considerato di avere il mio ingresso, quindi ho deciso che si trattava di una proposta ingiusta del tutto anche se ne avessi inserito uno solo, poiché troppi altri elementi del gioco sono sotto il mio controllo. Quindi tutte le voci che inserisco qui saranno solo piante.
Joe Z.

La ragione per cui pensavo che le persone non le avrebbero volute anche come piante è perché rappresenta un cambiamento piuttosto radicale nei giocatori di base che sono disponibili (e quindi nelle strategie di base) che non era disponibile all'inizio del gioco. Ma se supponiamo che le soluzioni debbano essere codificate per essere ottimali indipendentemente dai giocatori inseriti come piante, suppongo che potrei inserirle anche io.
Joe Z.

Bene, le voci dovrebbero essere codificate su "ottimale" (se esiste qui) indipendentemente dai giocatori coinvolti semplicemente perché non possiamo comunque vedere le altre risposte. Non fa differenza se si trattava di piante o altre risposte al programma, tranne per il fatto che non possono "vincere". Supponendo che il vincitore sia definito come non-pianta con il punteggio più alto, non vedo quanto sarà importante. Dico di farli entrare.
Geobits

1

Tit-for-tat

9GkjtTDD2jrnMYg/LSs2osiVWxDDoSOgLCpWvuqVmSM=

Simile a Wrathful, con alcune modifiche (si spera) che migliorano le prestazioni.

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []

if rounds == 0:
    print
elif rounds == 25 * players - 1:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        lines.append(sys.stdin.readline())
    lastline = lines[-1]
    takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
    for take in takes:
        sides = [int(i) for i in re.findall(r'[0-9]+', take)]
        if sides[1] == pid:
            print sides[0],
    print

Hai ricevuto il mio indirizzo email?
Joe Z.

@ Joe; sì; Grazie. (Non sono sicuro che ne avrò bisogno, ma grazie per essere accomodante.)
Ypnypn,

Bene, volevo solo sapere in modo da poterlo eliminare.
Joe Z.

1
@luserdroog Le persone pubblicano hash del codice sorgente del loro programma anziché del programma stesso. Una volta scaduti i 7 giorni per scrivere il codice, le persone riveleranno i loro programmi reali per i test.
Joe Z.

1
Sì è vero. Una presentazione dovrebbe probabilmente avere un titolo e almeno uno slogan come quello di Geobits lassù.
Joe Z.

1

Backstab

Python 3

Nonostante il nome, questo bot è in realtà abbastanza gentile. Ma non spuntare.

import sys, math

inp = [int(i) for i in sys.stdin.readline().split()]
inp.append([])
for i in range(inp[2]):
    inp[3].append(
        [eval(i+')') for i in sys.stdin.readline().split(')')[:-1]]
    )
inp += sys.stdin.readline()

# inp is [P, D, N, [M1, M2...], R]

dat = [[], inp[2] % 2] # average runlength take and don't per player, parity of round

lastatk = []

for i in range(inp[0]):
    dat[0].append([])
    lastatk.append(0)

for i,r in enumerate(inp[3]): # each round
    for m in r: # each move
        if m[1] == inp[1]:
            dat[0][m[0]-1].append(i) # round num they attacked
            lastatk[m[0]-1] = i # keep track of last attack

# now that we know who attacked me when, i can do some stats

nav = []
rl = []

for i in range(inp[0]):
    nav.append([[0], False])
    rl.append([[], []]) # attack, don't

for i in range(inp[2]): # each round
    for p in range(1, inp[0]+1): # each player
        if p != inp[1]: # let's not judge ourselves
            if i in dat[0][p-1]: # p attacked me in round i
                if nav[p-1][1]: # attack chain?
                    nav[p-1][0][-1] += 1
                else: # start attack chain!
                    rl[p-1][1] += [nav[p-1][0][-1]] # copy peace chain
                    nav[p-1][0].append(1)
                    nav[p-1][1] = True
            else: # peace!
                if not nav[p-1][1]: # peace chain?
                    nav[p-1][0][-1] += 1
                else: # peace to all!
                    rl[p-1][0] += [nav[p-1][0][-1]] # copy atk chain
                    nav[p-1][0].append(1)
                    nav[p-1][1] = False

print(nav)

print(inp[3])

# now, rl has runlengths for each player.

print(rl)

rl = [[sum(i[0])/len(i[0]+[0]), sum(i[1])/len(i[1]+[0])] for i in rl]

# rl now contains the averages w/ added zero.

# So, now we have average runtime and last attack. Let's quickly make some descisions.

out = []

for p in range(1, inp[0]+1): # each player
    if p != inp[1]: # again, let's not judge ourselves
        if lastatk[p-1] == inp[0]-1: # they attacked us!
            out.append(p)
        else: # whew, we can recover
            if inp[0] - lastatk[p-1] > rl[p-1][0]: # they're due to defend!
                out.append(p)
            elif int(__import__('binascii').b2a_hex(inp[-1].encode()), 16) % 4 == 0: # 1 in 4 chance of doing this
                out.append(p) # backstab!!1!!1one!!!1!!

print(*out)

EDIT 2 : fonte pubblicata. Sìì.

EDIT : Dopo alcuni test ho risolto alcuni difetti che ho riscontrato. Non sono algoritmici, solo alcuni problemi che leggono l'input.


Solo un promemoria amichevole: la fase di programmazione è terminata; hai un giorno per pubblicare il tuo codice sorgente. (La procedura è in fondo alla domanda.)
Joe Z.

@JoeZ. Pubblicato. Spero di essere in tempo. : P
cjfaure,

P, D, N, R sembrano le unità in cui un'auto può spostarsi.
Joe Z.

1
@JoeZ. xD Sono dal tuo post, quindi; 3
cjfaure

Oh mio Dio. Scusa: S
Joe Z.

1

Il Begrudger

g1TXBu2EfVz/uM/RS24VeJuYMKLOaRatLxsA+DN1Mto=

Codice

Devo ammettere che non ho trascorso molto tempo su questo ...

import sys
p, d, n, o = input().split(' ') + ['']
p, d, n = int(p), int(d), int(n)
for i in range(n):
    r = input()
    r = r[1:len(r)-1].split(') (')
    for a in r:
        if int(a.split(', ')[1]) == d and not a.split(', ')[0] in o:
            o += a.split(', ')[0] + " "

input()
print(o)

Solo un promemoria amichevole: la fase di programmazione è terminata; hai un giorno per pubblicare il tuo codice sorgente. (La procedura è in fondo alla domanda.)
Joe Z.

Ho provato a eseguirlo e ho riscontrato il seguente bug: o += a.split(', ')[0]non lascia spazio tra i numeri.
PleaseStand,

@PleaseStand L'ho risolto, ma penso che la versione testata finirà con il bug perché la concorrenza è finita.
kitcar2000,

Sì, il tuo codice produceva un bug ogni volta che lo eseguivo e non riuscivo a capire come risolverlo. Ha fatto leggermente meglio di The Lazy, però.
Joe Z.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.