Moose, Perl5面向对象,参考Perl6面向对象设计。
参考C++程序设计部分实例使用Moose改写。
模块1: Vector.pm
-
package Offset;
-
use Moose;
-
use Moose::Util::TypeConstraints;
-
-
my @aNumbDirection = qw( 0 1 2 3 4 5 6 7 );
-
my @aCharDirection = qw( N NE E SE S SW W NW );
-
my %hDirection = map { $aCharDirection[$_] => $aNumbDirection[$_] } 0..$#aNumbDirection;
-
my @aMove = (
-
[ -1, 0 ],
-
[ -1, 1 ],
-
[ 0, 1 ],
-
[ 1, 1 ],
-
[ 1, 0 ],
-
[ 1,-1 ],
-
[ 0,-1 ],
-
[ -1,-1 ],
-
);
-
-
# constraint for 'd'
-
# support for both chars and numbers
-
enum 'Direction' => @aDirection, @aNumbDireciton;
-
has 'd' => (
-
is => 'rw',
-
isa => 'Direction',
-
required => 1,
-
initializer => sub {
-
my ( $self, $value, $set, $attr ) = @_;
-
$value = $hDirection{$value} if $value !~ /\d/;
-
$set->($value);
-
},
-
);
-
-
# action in x direction
-
sub dx {
-
my $self = shift;
-
return $aMove[$self->d]->[0];
-
}
-
# action in y direction
-
sub dy {
-
my $self = shift;
-
return $aMove[$self->d]->[1];
-
}
-
# move to next direction
-
sub move {
-
my $self = shift;
-
return if $self->end;
-
$self->d( $self->d + 1 );
-
}
-
# last direction
-
sub end {
-
my $self = shift;
-
return $self->d == $#aMove ? 1 : 0;
-
}
-
# direction in char
-
sub direction {
-
my $self = shift;
-
return $aCharDirection[$self->d];
-
}
-
-
package Point;
-
use Moose;
-
-
has 'x' => ( is => 'rw', isa => 'Int', required => 1 );
-
has 'y' => ( is => 'rw', isa => 'Int', required => 1 );
-
-
package Vector;
-
use Moose;
-
extends 'Point', 'Offset';
-
-
# point x
-
sub px {
-
my $self = shift;
-
return $self->x + $self->dx;
-
}
-
# point y
-
sub py {
-
my $self = shift;
-
return $self->y + $self->dy;
-
}
-
# point message
-
sub print {
-
my $self = shift;
-
printf("i=%d,j=%d,dir=%s\n", $self->x, $self->y, $self->direction);
-
}
-
-
1;
模块2:Stack.pm
-
package Stack;
-
use Moose;
-
use Data::Dumper;
-
-
my $top = 0;
-
my @stack = ();
-
# stack maxsize;
-
has 'size' => ( is => 'rw', isa => 'Int', required => 1 );
-
-
sub push {
-
my $self = shift;
-
my $item = shift;
-
if ( $self->full ) {
-
print "Stack is full!\n";
-
return;
-
}
-
++$top;
-
push @stack, $item;
-
}
-
-
sub pop {
-
my $self = shift;
-
if ( $self->empty ) {
-
print "Stack is empty\n";
-
exit(0);
-
}
-
--$top;
-
pop @stack;
-
}
-
-
sub print {
-
my $self = shift;
-
print "Total : ", $top, "\n";
-
print "Items in Stack list:\n";
-
foreach my $item (@stack) {
-
if ( blessed $item ) {
-
$item->print;
-
} elsif ( ref $item ) {
-
print Dumper $item;
-
} else {
-
print "$item\n";
-
}
-
}
-
}
-
-
sub full {
-
my $self = shift;
-
return $top == $self->size ? 1 : 0;
-
}
-
-
sub empty {
-
return $top == 0 ? 1 : 0;
-
}
-
-
-
=head UT
-
my ($m, $n) = (5,10);
-
my $s = Stack->new( size => 5 * 10);
-
my $v = Vector->new( x => 1, y => 2, d => 'SE' );
-
-
#print Dumper $s;
-
#print Dumper $v;
-
print "empty:", $s->empty ? 'YES' : 'NO', "\n";
-
print "full :", $s->full ? 'YES' : 'NO', "\n";
-
$s->push($v);
-
print "empty:", $s->empty ? 'YES' : 'NO', "\n";
-
print "full :", $s->full ? 'YES' : 'NO', "\n";
-
-
my $n = $s->pop();
-
print Dumper $n;
-
=cut
-
-
1;
主程序:
-
#!/usr/bin/perl -w
-
use strict;
-
use Data::Dumper;
-
use lib 'E:\\个人笔记\\学习Moose\\迷宫';
-
use Stack;
-
use Vector;
-
-
my @maze = map { [split] } <DATA>;
-
path(\@maze);
-
-
sub path {
-
my $raMaze = shift;
-
my $m = @{$raMaze}; # maze width
-
my $p = @{$raMaze->[0]}; # maze length
-
-
# initial mark array
-
my $raMark = [];
-
for my $i (0..$m) {
-
for my $j (0..$p) {
-
$raMark->[$i][$j] = 0;
-
}
-
}
-
# stack for maze path
-
my $mazepath = Stack->new( size => $m * $p );
-
# entrance point
-
$mazepath->push( Vector->new( x => 0, y => 0, d => 'E' ) );
-
-
while ( not $mazepath->empty ) {
-
my $vector = $mazepath->pop();
-
while ( not $vector->end ) {
-
my $x = $vector->px;
-
my $y = $vector->py;
-
# point is out of the maze
-
if ( $x < 0 || $y < 0 || $x >= $m || $y >= $p ) {
-
$vector->move();
-
} else {
-
# exit point
-
if ( $x == $m - 1 && $y == $p - 1 ) {
-
$mazepath->print;
-
return;
-
}
-
if ( !$raMaze->[$x]->[$y] && !$raMark->[$x]->[$y] ) {
-
$raMark->[$x]->[$y] = 1;
-
$mazepath->push($vector);
-
$vector = Vector->new( x => $x, y => $y, d => 0 );
-
## below will destroy the data having been pushed in Stack
-
## recreating a new vector above is a good way to solve it.
-
# $vector->x($x);
-
# $vector->y($y);
-
# $vector->d(0);
-
# $mazepath->print;
-
} else {
-
$vector->move();
-
}
-
}
-
}
-
}
-
-
print "No path in the maze!\n";
-
-
}
-
-
__DATA__
-
0 1 1 1 1 1 1 1
-
1 0 1 1 0 1 0 1
-
1 0 1 0 0 1 0 1
-
1 1 0 0 1 0 1 1
-
1 0 0 1 0 0 0 1
-
1 0 0 0 0 1 1 1
-
1 0 1 0 0 1 0 1
-
1 0 1 0 0 0 1 1
-
1 1 1 1 0 0 0 1
-
1 1 1 1 1 1 1 0
阅读(1045) | 评论(0) | 转发(0) |