78 lines
1.8 KiB
Perl
78 lines
1.8 KiB
Perl
#!perl
|
|
use strict;
|
|
use warnings;
|
|
|
|
my ($width, $height) = @ARGV;
|
|
$_ ||= 10 for $width, $height;
|
|
|
|
my %visited;
|
|
|
|
my $h_barrier = "+" . ("--+" x $width) . "\n";
|
|
my $v_barrier = "|" . (" |" x $width) . "\n";
|
|
my @output = ($h_barrier, $v_barrier) x $height;
|
|
push @output, $h_barrier;
|
|
my @dx = qw(-1 1 0 0);
|
|
my @dy = qw(0 0 -1 1);
|
|
|
|
sub visit {
|
|
my ($x, $y) = @_;
|
|
$visited{$x, $y} = 1;
|
|
my $rand = int rand 4;
|
|
for my $n ( $rand .. 3, 0 .. $rand-1 ) {
|
|
my ($xx, $yy) = ($x + $dx[$n], $y + $dy[$n]);
|
|
next if $visited{ $xx, $yy };
|
|
next if $xx < 0 or $xx >= $width;
|
|
next if $yy < 0 or $yy >= $height;
|
|
|
|
my $row = $y * 2 + 1 + $dy[$n];
|
|
my $col = $x * 3 + 1 + $dx[$n];
|
|
substr( $output[$row], $col, 2, ' ' );
|
|
|
|
no warnings 'recursion';
|
|
visit( $xx, $yy );
|
|
}
|
|
}
|
|
|
|
visit( int rand $width, int rand $height );
|
|
|
|
print "Here is the maze:\n";
|
|
print @output;
|
|
|
|
%visited = ();
|
|
|
|
my @d = ('>>', '<<', 'vv', '^^');
|
|
sub solve {
|
|
my ($x, $y) = @_;
|
|
return 1 if $x == 0 and $y == 0;
|
|
$visited{ $x, $y } = 1;
|
|
my $rand = int rand 4;
|
|
for my $n ( $rand .. 3, 0 .. $rand-1 ) {
|
|
my ($xx, $yy) = ($x + $dx[$n], $y + $dy[$n]);
|
|
next if $visited{ $xx, $yy };
|
|
next if $xx < 0 or $xx >= $width;
|
|
next if $yy < 0 or $yy >= $height;
|
|
|
|
my $row = $y * 2 + 1 + $dy[$n];
|
|
my $col = $x * 3 + 1 + $dx[$n];
|
|
|
|
my $b = substr( $output[$row], $col, 2 );
|
|
next if " " ne $b;
|
|
|
|
no warnings 'recursion';
|
|
next if not solve( $xx, $yy );
|
|
|
|
substr( $output[$row], $col, 2, $d[$n] );
|
|
substr( $output[$row-$dy[$n]], $col-$dx[$n], 2, $d[$n] );
|
|
return 1;
|
|
}
|
|
0;
|
|
}
|
|
|
|
if( solve( $width-1, $height-1 ) ) {
|
|
print "Here is the solution:\n";
|
|
substr( $output[1], 1, 2, '**' );
|
|
print @output;
|
|
} else {
|
|
print "Could not solve!\n";
|
|
}
|