public
Created

Iterated Prisoner's Dilemma in Perl 6

  • Download Gist
prisoners.pl
Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
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;
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.