Created
September 5, 2009 23:55
-
-
Save masak/181565 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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