Skip to content

Instantly share code, notes, and snippets.

@moritz
Created January 31, 2012 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moritz/1710688 to your computer and use it in GitHub Desktop.
Save moritz/1710688 to your computer and use it in GitHub Desktop.
Iterated Prisoner's Dilemma in Perl 6
use v6;
# by convention, True means cooperate, False means defect
my %scoring =
'True True' => [4, 4],
'True False' => [0, 6],
'False True' => [6, 0],
'False False' => [1, 1],
;
# basic, well-known strategies
my %strategies =
good => -> *% { True },
bad => -> *% { False },
random => -> *% { Bool.pick },
tit-for-tat => -> :@theirs, *% { @theirs[*-1] // True },
evil-tit-for-tat => -> :@theirs, *% { @theirs[*-1] // False },
;
sub compete(&a, &b, :$count = 20) {
my @a;
my @b;
my @scores = (0, 0);
for 1..$count {
my $current-a = a(:theirs(@b), :mine(@a), :total($count));
my $current-b = b(:theirs(@a), :mine(@b), :total($count));
@a.push: $current-a;
@b.push: $current-b;
@scores = @scores Z+ %scoring{"$current-a $current-b"}.list;
}
return @scores;
}
sub tournament($count = 50) {
my %results;
my @names = %strategies.keys.sort;
for @names.keys -> $idx-a {
for $idx-a .. @names.end -> $idx-b {
my $a = @names[$idx-a];
my $b = @names[$idx-b];
my @r = compete(|%strategies{$a, $b}.list, :$count);
# say "$a : $b @r[0] : @r[1]";
%results{$a} //= 0;
%results{$b} //= 0;
%results{$a} += @r[0];
%results{$b} += @r[1];
}
}
%results;
}
sub MAIN($laps = 50) {
my %results = tournament($laps);
say 'SUMMARY';
for %results.sort(-*.value) -> $p {
say $p.value, "\t", $p.key;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment