Chinaunix首页 | 论坛 | 博客
  • 博客访问: 127793
  • 博文数量: 36
  • 博客积分: 155
  • 博客等级: 入伍新兵
  • 技术积分: 282
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-27 20:57
文章分类

全部博文(36)

文章存档

2014年(1)

2013年(21)

2012年(15)

分类: PERL

2013-03-30 19:14:39

Moose, Perl5面向对象,参考Perl6面向对象设计。
参考C++程序设计部分实例使用Moose改写。

模块1: Vector.pm

  1. package Offset;
  2. use Moose;
  3. use Moose::Util::TypeConstraints;

  4. my @aNumbDirection = qw( 0 1 2 3 4 5 6 7 );
  5. my @aCharDirection = qw( N NE E SE S SW W NW );
  6. my %hDirection = map { $aCharDirection[$_] => $aNumbDirection[$_] } 0..$#aNumbDirection;
  7. my @aMove = (
  8.     [ -1, 0 ],
  9.     [ -1, 1 ],
  10.     [ 0, 1 ],
  11.     [ 1, 1 ],
  12.     [ 1, 0 ],
  13.     [ 1,-1 ],
  14.     [ 0,-1 ],
  15.     [ -1,-1 ],
  16. );

  17. # constraint for 'd'
  18. # support for both chars and numbers
  19. enum 'Direction' => @aDirection, @aNumbDireciton;
  20. has 'd' => (
  21.     is => 'rw',
  22.     isa => 'Direction',
  23.     required => 1,
  24.     initializer => sub {
  25.         my ( $self, $value, $set, $attr ) = @_;
  26.         $value = $hDirection{$value} if $value !~ /\d/;
  27.         $set->($value);
  28.     },
  29. );

  30. # action in x direction
  31. sub dx {
  32.     my $self = shift;
  33.     return $aMove[$self->d]->[0];
  34. }
  35. # action in y direction
  36. sub dy {
  37.     my $self = shift;
  38.     return $aMove[$self->d]->[1];
  39. }
  40. # move to next direction
  41. sub move {
  42.     my $self = shift;
  43.     return if $self->end;
  44.     $self->d( $self->d + 1 );
  45. }
  46. # last direction
  47. sub end {
  48.     my $self = shift;
  49.     return $self->d == $#aMove ? 1 : 0;
  50. }
  51. # direction in char
  52. sub direction {
  53.     my $self = shift;
  54.     return $aCharDirection[$self->d];
  55. }

  56. package Point;
  57. use Moose;

  58. has 'x' => ( is => 'rw', isa => 'Int', required => 1 );
  59. has 'y' => ( is => 'rw', isa => 'Int', required => 1 );

  60. package Vector;
  61. use Moose;
  62. extends 'Point', 'Offset';

  63. # point x
  64. sub px {
  65.     my $self = shift;
  66.     return $self->x + $self->dx;
  67. }
  68. # point y
  69. sub py {
  70.     my $self = shift;
  71.     return $self->y + $self->dy;
  72. }
  73. # point message
  74. sub print {
  75.     my $self = shift;
  76.     printf("i=%d,j=%d,dir=%s\n", $self->x, $self->y, $self->direction);
  77. }

  78. 1;
模块2:Stack.pm


  1. package Stack;
  2. use Moose;
  3. use Data::Dumper;

  4. my $top = 0;
  5. my @stack = ();
  6. # stack maxsize;
  7. has 'size' => ( is => 'rw', isa => 'Int', required => 1 );

  8. sub push {
  9.     my $self = shift;
  10.     my $item = shift;
  11.     if ( $self->full ) {
  12.         print "Stack is full!\n";
  13.         return;
  14.     }
  15.     ++$top;
  16.     push @stack, $item;
  17. }

  18. sub pop {
  19.     my $self = shift;
  20.     if ( $self->empty ) {
  21.         print "Stack is empty\n";
  22.         exit(0);
  23.     }
  24.     --$top;
  25.     pop @stack;
  26. }

  27. sub print {
  28.     my $self = shift;
  29.     print "Total : ", $top, "\n";
  30.     print "Items in Stack list:\n";
  31.     foreach my $item (@stack) {
  32.         if ( blessed $item ) {
  33.             $item->print;
  34.         } elsif ( ref $item ) {
  35.             print Dumper $item;
  36.         } else {
  37.             print "$item\n";
  38.         }
  39.     }
  40. }

  41. sub full {
  42.     my $self = shift;
  43.     return $top == $self->size ? 1 : 0;
  44. }

  45. sub empty {
  46.     return $top == 0 ? 1 : 0;
  47. }


  48. =head UT
  49. my ($m, $n) = (5,10);
  50. my $s = Stack->new( size => 5 * 10);
  51. my $v = Vector->new( x => 1, y => 2, d => 'SE' );

  52. #print Dumper $s;
  53. #print Dumper $v;
  54. print "empty:", $s->empty ? 'YES' : 'NO', "\n";
  55. print "full :", $s->full ? 'YES' : 'NO', "\n";
  56. $s->push($v);
  57. print "empty:", $s->empty ? 'YES' : 'NO', "\n";
  58. print "full :", $s->full ? 'YES' : 'NO', "\n";

  59. my $n = $s->pop();
  60. print Dumper $n;
  61. =cut

  62. 1;
主程序:


  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Data::Dumper;
  4. use lib 'E:\\个人笔记\\学习Moose\\迷宫';
  5. use Stack;
  6. use Vector;

  7. my @maze = map { [split] } <DATA>;
  8. path(\@maze);

  9. sub path {
  10.     my $raMaze = shift;
  11.     my $m = @{$raMaze}; # maze width
  12.     my $p = @{$raMaze->[0]}; # maze length
  13.     
  14.     # initial mark array
  15.     my $raMark = [];
  16.     for my $i (0..$m) {
  17.         for my $j (0..$p) {
  18.             $raMark->[$i][$j] = 0;
  19.         }
  20.     }
  21.     # stack for maze path
  22.     my $mazepath = Stack->new( size => $m * $p );
  23.     # entrance point
  24.     $mazepath->push( Vector->new( x => 0, y => 0, d => 'E' ) );
  25.     
  26.     while ( not $mazepath->empty ) {
  27.         my $vector = $mazepath->pop();
  28.         while ( not $vector->end ) {
  29.             my $x = $vector->px;
  30.             my $y = $vector->py;
  31.             # point is out of the maze
  32.             if ( $x < 0 || $y < 0 || $x >= $m || $y >= $p ) {
  33.                 $vector->move();
  34.             } else {
  35.                 # exit point
  36.                 if ( $x == $m - 1 && $y == $p - 1 ) {
  37.                     $mazepath->print;
  38.                     return;
  39.                 }
  40.                 if ( !$raMaze->[$x]->[$y] && !$raMark->[$x]->[$y] ) {
  41.                     $raMark->[$x]->[$y] = 1;
  42.                     $mazepath->push($vector);
  43.                     $vector = Vector->new( x => $x, y => $y, d => 0 );
  44.                     ## below will destroy the data having been pushed in Stack
  45.                     ## recreating a new vector above is a good way to solve it.
  46.                     # $vector->x($x);
  47.                     # $vector->y($y);
  48.                     # $vector->d(0);
  49.                     # $mazepath->print;
  50.                 } else {
  51.                     $vector->move();
  52.                 }
  53.             }
  54.         }
  55.     }
  56.     
  57.     print "No path in the maze!\n";
  58.     
  59. }

  60. __DATA__
  61. 0 1 1 1 1 1 1 1
  62. 1 0 1 1 0 1 0 1
  63. 1 0 1 0 0 1 0 1
  64. 1 1 0 0 1 0 1 1
  65. 1 0 0 1 0 0 0 1
  66. 1 0 0 0 0 1 1 1
  67. 1 0 1 0 0 1 0 1
  68. 1 0 1 0 0 0 1 1
  69. 1 1 1 1 0 0 0 1
  70. 1 1 1 1 1 1 1 0

阅读(1002) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~