Diese Aufgabe ist Teil des First Periodic Premier Programming Puzzle Push und soll den neuen König-der-Hügel- Herausforderungstyp- Vorschlag demonstrieren .
Die Aufgabe besteht darin, ein Programm zu schreiben, um das iterierte Gefangenendilemma besser zu spielen als andere Teilnehmer.
Schau, Vinny. Wir kennen Ihren Zellengenossen - wie heißt er? Ja, McWongski, der Nippo-Irisch-Ukrainische Gangster - hat etwas vor und Sie wissen, was es ist.
Wir versuchen hier nett zu sein, Vinnie. Ich gebe dir eine Chance.
Wenn du uns sagst, was er plant, werden wir sehen, dass du einen guten Auftrag bekommst.
Und wenn Sie nicht ...
Die Regeln des Spiels
- Der Wettbewerb besteht aus einem vollständigen Round-Robin (alle möglichen Paarungen) von jeweils zwei Teilnehmern (einschließlich Selbstspielen).
- Zwischen jedem Paar werden 100 Runden gespielt
- In jeder Runde wird jeder Spieler gebeten, zu entscheiden, ob er mit dem anderen Spieler zusammenarbeitet oder ihn verrät, ohne die Absichten der anderen Spieler zu kennen, aber mit einer Erinnerung an die Ergebnisse früherer Runden, die gegen diesen Gegner gespielt wurden.
- Punkte werden für jede Runde basierend auf der kombinierten Auswahl vergeben. Wenn beide Spieler zusammenarbeiten, erhalten sie jeweils 2 Punkte. Gegenseitiger Verrat bringt jeweils 1 Punkt. Im gemischten Fall erhält der betrügerische Spieler 4 Punkte und der Mitwirkende wird mit 1 bestraft.
- Ein "offizielles" Spiel wird nicht früher als 10 Tage nach dem Posten mit allen Einsendungen durchgeführt, die ich zur Arbeit bringen kann, und zur Auswahl des "akzeptierten" Gewinners verwendet. Ich habe eine Mac OS 10.5-Box, daher sollten POSIX-Lösungen funktionieren, aber es gibt Linux-Systeme, die dies nicht tun. Ebenso habe ich keine Unterstützung für die Win32-API. Ich bin bereit, grundlegende Anstrengungen zu unternehmen, um Dinge zu installieren, aber es gibt eine Grenze. Die Grenzen meines Systems stellen in keiner Weise die Grenzen akzeptabler Antworten dar, sondern lediglich die, die in der "offiziellen" Übereinstimmung enthalten sein werden.
Die Programmierschnittstelle
- Einträge sollten in Form von Programmen vorliegen, die über die Befehlszeile ausgeführt werden können. Die Entscheidung muss die (einzige!) Ausgabe des Programms auf der Standardausgabe treffen. Der Verlauf der vorherigen Runden mit diesem Gegner wird als Befehlszeilenargument dargestellt.
- Die Ausgabe ist entweder "c" (für Clam Up ) oder "t" (für Tell All ).
- Der Verlauf ist eine einzelne Zeichenfolge, die frühere Runden darstellt, wobei die letzten Runden am frühesten in der Zeichenfolge erscheinen. Die Charaktere sind
- "K" (für gehalten den Glauben , der gegenseitige Zusammenarbeit bedeutet)
- "R" (für Ratte b @ st @ rd hat mich ausverkauft! )
- "S" (für " Trottel", was bedeutet, dass Sie von einem Verrat profitiert haben)
- "E" (für alle, die auf gegenseitigen Verrat achten)
Die Klammer
Vier Spieler werden vom Autor zur Verfügung gestellt
- Engel - kooperiert immer
- Teufel - redet immer
- TitForTat - kooperiert in der ersten Runde immer so, wie er es in der letzten Runde getan hat
- Zufällig - 50/50
zu denen ich alle Einträge hinzufüge, die ich ausführen kann.
Die Gesamtpunktzahl ist die Gesamtpunktzahl gegenüber allen Gegnern (einschließlich einmaliger Selbstspiele und Verwendung der Durchschnittspunktzahl).
Teilnehmer
(Stand: 2. Mai 2011, 7:00 Uhr)
Der geheime Händedruck | Anti-T42T-Rakete | Misstrauen (Variante) | Anti-Handshake | Der kleine Lisper | Konvergenz | Hai | Probabimatic | Pawlow - Win Stay, Lose Switch | Ehre unter Dieben | Hilf Vampire | Druide | Kleiner Schemer | Vergangenheit | Meise für zwei Tats | Simpleton |
Torschütze
#! /usr/bin/python
#
# Iterated prisoner's dilemma King of Hill Script Argument is a
# directory. We find all the executables therein, and run all possible
# binary combinations (including self-plays (which only count once!)).
#
# Author: dmckee (https://codegolf.stackexchange.com/users/78/dmckee)
#
import subprocess
import os
import sys
import random
import py_compile
###
# config
PYTHON_PATH = '/usr/bin/python' #path to python executable
RESULTS = {"cc":(2,"K"), "ct":(-1,"R"), "tc":(4,"S"), "tt":(1,"E")}
def runOne(p,h):
"""Run process p with history h and return the standard output"""
#print "Run '"+p+"' with history '"+h+"'."
process = subprocess.Popen(p+" "+h,stdout=subprocess.PIPE,shell=True)
return process.communicate()[0]
def scoreRound(r1,r2):
return RESULTS.get(r1[0]+r2[0],0)
def runRound(p1,p2,h1,h2):
"""Run both processes, and score the results"""
r1 = runOne(p1,h1)
r2 = runOne(p2,h2)
(s1, L1), (s2, L2) = scoreRound(r1,r2), scoreRound(r2,r1)
return (s1, L1+h1), (s2, L2+h2)
def runGame(rounds,p1,p2):
sa, sd = 0, 0
ha, hd = '', ''
for a in range(0,rounds):
(na, ha), (nd, hd) = runRound(p1,p2,ha,hd)
sa += na
sd += nd
return sa, sd
def processPlayers(players):
for i,p in enumerate(players):
base,ext = os.path.splitext(p)
if ext == '.py':
py_compile.compile(p)
players[i] = '%s %sc' %( PYTHON_PATH, p)
return players
print "Finding warriors in " + sys.argv[1]
players=[sys.argv[1]+exe for exe in os.listdir(sys.argv[1]) if os.access(sys.argv[1]+exe,os.X_OK)]
players=processPlayers(players)
num_iters = 1
if len(sys.argv) == 3:
num_iters = int(sys.argv[2])
print "Running %s tournament iterations" % (num_iters)
total_scores={}
for p in players:
total_scores[p] = 0
for i in range(1,num_iters+1):
print "Tournament %s" % (i)
scores={}
for p in players:
scores[p] = 0
for i1 in range(0,len(players)):
p1=players[i1];
for i2 in range(i1,len(players)):
p2=players[i2];
# rounds = random.randint(50,200)
rounds = 100
#print "Running %s against %s (%s rounds)." %(p1,p2,rounds)
s1,s2 = runGame(rounds,p1,p2)
#print (s1, s2)
if (p1 == p2):
scores[p1] += (s1 + s2)/2
else:
scores[p1] += s1
scores[p2] += s2
players_sorted = sorted(scores,key=scores.get)
for p in players_sorted:
print (p, scores[p])
winner = max(scores, key=scores.get)
print "\tWinner is %s" %(winner)
total_scores[p] += 1
print '-'*10
print "Final Results:"
players_sorted = sorted(total_scores,key=total_scores.get)
for p in players_sorted:
print (p, total_scores[p])
winner = max(total_scores, key=total_scores.get)
print "Final Winner is " + winner
- Beschwerden über meine schreckliche Python sind willkommen, da ich mir sicher bin, dass dies in mehrfacher Hinsicht scheiße ist
- Bugfixes willkommen
Torschützenkönig:
- Drucke sortierte Spieler und Punktzahlen aus und erkläre einen Gewinner (4/29, Casey)
- Optional können Sie mehrere Turniere ausführen (
./score warriors/ num_tournaments)
Standard = 1), Python-Quellen erkennen und kompilieren (4/29, Casey) - Behebung eines besonders dummen Fehlers, bei dem dem zweiten Spieler ein falscher Verlauf übergeben wurde. (4/30, dmckee; danke Josh)
Anfängliche Krieger
Beispielhaft und damit die Ergebnisse verifiziert werden können
Engel
#include <stdio.h>
int main(int argc, char**argv){
printf("c\n");
return 0;
}
oder
#!/bin/sh
echo c
oder
#!/usr/bin/python
print 'c'
Teufel
#include <stdio.h>
int main(int argc, char**argv){
printf("t\n");
return 0;
}
Zufällig
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char**argv){
srandom(time(0)+getpid());
printf("%c\n",(random()%2)?'c':'t');
return 0;
}
Beachten Sie, dass der Schreiber den Krieger möglicherweise innerhalb einer Sekunde mehrmals erneut aufrufen kann. Daher müssen ernsthafte Anstrengungen unternommen werden, um die Zufälligkeit der Ergebnisse zu gewährleisten, wenn Zeit für die Aussaat des PRNG verwendet wird.
Wie du mir so ich dir
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char**argv){
char c='c';
if (argv[1] && (
(argv[1][0] == 'R') || (argv[1][0] == 'E')
) ) c='t';
printf("%c\n",c);
return 0;
}
Der erste, der tatsächlich etwas mit der Geschichte macht.
Läuft der Torschütze nur auf die zur Verfügung gestellten Kriegererträge
Finding warriors in warriors/
Running warriors/angel against warriors/angel.
Running warriors/angel against warriors/devil.
Running warriors/angel against warriors/random.
Running warriors/angel against warriors/titfortat.
Running warriors/devil against warriors/devil.
Running warriors/devil against warriors/random.
Running warriors/devil against warriors/titfortat.
Running warriors/random against warriors/random.
Running warriors/random against warriors/titfortat.
Running warriors/titfortat against warriors/titfortat.
('warriors/angel', 365)
('warriors/devil', 832)
('warriors/random', 612)
('warriors/titfortat', 652)
Dieser Teufel, er ist ein Handwerker, und nette Leute kommen anscheinend als Letzte rein.
Ergebnisse
des "offiziellen" Laufs
('angel', 2068)
('helpvamp', 2295)
('pavlov', 2542)
('random', 2544)
('littleschemer', 2954)
('devil', 3356)
('simpleton', 3468)
('secrethandshake', 3488)
('antit42t', 3557)
('softmajo', 3747)
('titfor2tats', 3756)
('convergence', 3772)
('probabimatic', 3774)
('mistrust', 3788)
('hyperrationalwasp', 3828)
('bygones', 3831)
('honoramongthieves', 3851)
('titfortat', 3881)
('druid', 3921)
('littlelisper', 3984)
('shark', 4021)
('randomSucker', 4156)
('gradual', 4167)
Winner is ./gradual
return (s1, L1+h1), (s2, L2+h1)
zu return (s1, L1+h1), (s2, L2+h2)
[Notiz L2+h2
statt L2+h1
am Ende] zu wechseln ? // Fehler beim Ausschneiden und Einfügen oder etwas ähnlich idiotisches. Meine Güte!