Це завдання є частиною першого періодичного прем'єр - програмування головоломка Пуш і призначена як демонстрація нового короля-оф-хілл виклик типу пропозиції .
Завдання - написати програму, щоб відтворити повторену дилему в'язня краще, ніж інші учасники.
Подивися, Вінні. Ми знаємо вашого співмешканця --- як його звати? Так, Маквонгський, ніпопо-ірландсько-український гангстер - щось до чого, і ви знаєте, що це таке.
Ми намагаємось бути приємно тут, Вінні. Дай вам шанс.
Якщо ви скажете нам, що він планує, ми побачимо, що ви отримаєте хорошу роботу.
А якщо ви цього не зробите ...
Правила гри
- Конкурс складається з повноцінного кругообігу (усі можливі пари) одночасно з двома учасниками (включаючи самостійні ігри).
- Між кожною парою проводиться 100 раундів
- У кожному раунді кожному гравцеві пропонується вибирати співпрацювати з іншим гравцем або зраджувати їх, не знаючи намірів інших гравців у цьому питанні, але пам’ятаючи про результати попередніх раундів, зіграних проти цього суперника.
- Очки присвоюються за кожен раунд на основі комбінованого вибору. Якщо обидва гравці співпрацюють, кожен отримує 2 бали. Взаємна зрада дає 1 бал кожній. У змішаному випадку гравцеві, який зраджує, присуджується 4 бали, а кооператор накладається штраф 1.
- "Офіційний" матч буде проведений не раніше ніж через 10 днів після публікації з усіма поданнями, які я можу взяти на роботу, і буду використаний для вибору "прийнятого" переможця. У мене є Mac OS 10.5 вікно, тому рішення POSIX повинні працювати, але є Linuxx, які цього не роблять. Так само я не підтримую API Win32. Я готовий докласти основних зусиль для встановлення речей, але є обмеження. Межі моєї системи жодним чином не представляють межі прийнятних відповідей, просто тих, які будуть включені у "офіційну" відповідність.
Інтерфейс програміста
- Записи повинні бути у вигляді програм, які можна запустити з командного рядка; рішення повинно бути (єдиним!) результатом програми на стандартному виході. Історія попередніх раундів з цим опонентом буде представлена як аргумент командного рядка.
- Вихідні дані є "c" (для підключення ) або "t" (для всіх ).
- Історія - це єдиний рядок символів, що представляє попередні раунди, причому останні раунди виходять найчастіше в рядку. Персонажі є
- "K" (бо зберегли віру, що означає взаємну співпрацю)
- "R" (для щура b @ st @ rd мене продали! )
- "S" (для присосок! Означає, що ви виграли від зради)
- "Е" (бо всі шукають номер один про взаємну зраду)
Кронштейн
Чотири гравці будуть надані автором
- Ангел - завжди співпрацює
- Чорт - завжди розмовляє
- TitForTat - Співпрацює в першому раунді, тоді завжди робить так, як це робилося в останньому раунді
- Випадкові - 50/50
до якого я додам усі записи, які можу отримати для запуску.
Загальний бал буде підсумовувати бал проти всіх супротивників (включаючи самостійні ігри лише один раз та використання середнього балу).
Вступники
(чинний станом на 2 травня 2011 р. 7:00)
Таємне рукостискання | Ракета проти Т42Т | Недовіра (варіант) | Анти-рукостискання | Маленький Лиспер | Конвергенція | Акула | Імовірний | Павлов - Виграй, залишайся, програй перемикач | Честь серед злодіїв | Допомога Вампіру | Друїд | Маленький Шемер | Тимчасові | Синиця на двох татів | Простий |
Бомбардир
#! /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
- Скарги на мій жахливий пітон вітаються, тому що я впевнений, що це не більше ніж один спосіб
- Виправлення помилок вітаються
Бортовий список змін:
- Роздрукуйте відсортованих гравців та забийте гравців та оголосіть переможця (4/29, Кейсі)
- Необов’язково проводити кілька турнірів (
./score warriors/ num_tournaments)
) за замовчуванням = 1, виявляти та компілювати джерела пітона (4/29, Кейсі) - Виправте особливо тупу помилку, у якій другому гравцеві передавали неправильну історію. (4/30, dmckee; дякую Джошу)
Початкові воїни
Як приклад, і щоб результати можна було перевірити
Ангел
#include <stdio.h>
int main(int argc, char**argv){
printf("c\n");
return 0;
}
або
#!/bin/sh
echo c
або
#!/usr/bin/python
print 'c'
Чорт
#include <stdio.h>
int main(int argc, char**argv){
printf("t\n");
return 0;
}
Випадкові
#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;
}
Зауважте, що бомбардир може повторно викликати воїна багато разів за одну секунду, тому необхідно докласти серйозних зусиль, щоб забезпечити випадковість результатів, якщо буде використаний час для засіву PRNG.
TitForTat
#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;
}
Перший, який насправді щось робить з історією.
Запуск бомбардира тільки за забезпеченими врожаями воїнів
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)
Цей чорт, він ремісничий, і приємні хлопці, мабуть, приходять останніми.
Результати
"офіційного" пробігу
('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)
на return (s1, L1+h1), (s2, L2+h2)
[Примітка L2+h2
замість L2+h1
кінця]? // Помилка вирізання-вставки або щось настільки ж ідіотське. Sheesh!