Skip to content

Instantly share code, notes, and snippets.

@masak
Created September 5, 2009 23:55
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 masak/181565 to your computer and use it in GitHub Desktop.
Save masak/181565 to your computer and use it in GitHub Desktop.
$ cat theseus.pl
class Labyrinth {
has $.width;
has $.height;
has %!v;
has %!h;
has $!minotaur;
has $!theseus;
has $!exit;
method add-wall-above($row, $col) { ++%!h{"{$row-1}, $col"} }
method add-wall-below($row, $col) { ++%!h{"$row, $col"} }
method add-wall-left-of($row, $col) { ++%!v{"$row, {$col-1}"} }
method add-wall-right-of($row, $col) { ++%!v{"$row, $col"} }
method theseus-moves() {
my ($r, $c) = @($!theseus);
gather for ([$r-1, $c], [$r, $c-1],
[$r, $c+1], [$r+1, $c], [$r, $c]).kv -> $i, $pos {
my ($row, $col) = @($pos);
if $row == $!exit[0] && $col == $!exit[1] {
take $pos;
next;
}
next unless 0 <= $row < $.height;
next unless 0 <= $col < $.width;
next if $i == 0 && %!h{"{$r-1}, $c"};
next if $i == 1 && %!v{"$r, {$c-1}"};
next if $i == 2 && %!v{"$r, $c"};
next if $i == 3 && %!h{"$r, $c"};
take $pos;
}
}
method description() {
"{$!theseus.join(', ')}; {$!minotaur.join(', ')}";
}
method move($pos) {
my ($r, $c) = @($!minotaur);
for ^2 {
if $c < $pos[1] && !%!v{"$r, $c"} {
++$c;
}
elsif $c > $pos[1] && !%!v{"$r, {$c-1}"} {
--$c;
}
elsif $r < $pos[0] && !%!h{"$r, $c"} {
++$r;
}
elsif $r > $pos[0] && !%!h{"{$r-1}, $c"} {
--$r;
}
}
self.clone(:theseus($pos), :minotaur([$r, $c]));
}
method won() {
$!theseus[0] == $!exit[0] && $!theseus[1] == $!exit[1];
}
method dead() {
$!theseus[0] == $!minotaur[0] && $!theseus[1] == $!minotaur[1];
}
}
my Labyrinth $l .= new(:width(3), :height(3),
:minotaur([0,1]), :theseus([2,1]), :exit([1,3]));
$l.add-wall-above(1,1);
$l.add-wall-right-of(1,1);
$l.add-wall-below(1,1);
my %seen;
my ($wtf, $wtw) = 0, 0;
sub ev($l, $level = 0) {
print ' ' x (2*$level), $l.description();
if $l.won() {
say ' -- won';
++$wtw;
return ();
}
if $l.dead() {
say ' -- dead';
++$wtf;
return ();
}
if %seen{$l.description}++ {
say ' -- tried already';
return ();
}
say '';
for $l.theseus-moves() {
ev($l.move($_), $level+1);
}
}
ev($l);
say '';
say "Ways to fail: $wtf";
say "Ways to win: $wtw";
$ perl6 theseus.pl
2, 1; 0, 1
2, 0; 1, 0
1, 0; 1, 0 -- dead
2, 1; 1, 1
2, 0; 2, 0 -- dead
2, 2; 1, 1
1, 2; 1, 1
0, 2; 1, 1
0, 1; 1, 1
0, 0; 0, 0 -- dead
0, 2; 1, 1 -- tried already
0, 1; 1, 1 -- tried already
1, 2; 1, 1 -- tried already
0, 2; 1, 1 -- tried already
1, 3; 1, 1 -- won
2, 2; 1, 1 -- tried already
1, 2; 1, 1 -- tried already
2, 1; 1, 1 -- tried already
2, 2; 1, 1 -- tried already
2, 1; 1, 1 -- tried already
2, 0; 2, 0 -- dead
2, 2; 1, 2
1, 2; 1, 2 -- dead
2, 1; 2, 1 -- dead
2, 2; 2, 2 -- dead
2, 1; 0, 1 -- tried already
Ways to fail: 7
Ways to win: 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment