File Coverage

lib/Games/PMM/Actions.pm
Criterion Covered Total %
statement 39 40 97.5
branch 8 10 80.0
condition 9 12 75.0
subroutine 10 10 100.0
pod 6 7 85.7
total 72 79 91.1


line stmt bran cond sub pod time code
1             package Games::PMM::Actions;
2              
3 1     1   606 use strict;
  1         3  
  1         284  
4              
5             sub new
6             {
7 1     1 1 1540 my $self = shift;
8 1         4 bless {}, $self;
9             }
10              
11             sub action_forward
12             {
13 2     2 1 4 my ($self, $arena, $monster) = @_;
14 2         7 $arena->forward( $monster );
15             }
16              
17             sub action_reverse
18             {
19 2     2 1 3 my ($self, $arena, $monster) = @_;
20 2         8 $arena->reverse( $monster );
21             }
22              
23             sub action_turn
24             {
25 2     2 1 4 my ($self, $arena, $monster, $direction) = @_;
26 2         6 $monster->turn( $direction );
27             }
28              
29             sub action_scan
30             {
31 1     1 1 2 my ($self, $arena, $monster) = @_;
32 1         7 my @scanned = $arena->scan( $monster );
33 1         4 $monster->seen( \@scanned );
34             }
35              
36             my %move_axis =
37             (
38             north => [qw( y x )],
39             south => [qw( y x )],
40             east => [qw( x y )],
41             west => [qw( x y )],
42             );
43              
44             for my $method (
45             { name => 'charge', direction => 1 },
46             { name => 'retreat', direction => -1 },
47             )
48             {
49 1     1   5 no strict 'refs';
  1         3  
  1         542  
50             my ($type, $dir) = @$method{qw( name direction )};
51              
52             *{ 'action_' . $type } = sub
53             {
54 4     4   6 my ($self, $arena, $monster) = @_;
55              
56 4 50       10 if (my $direction = $self->should_turn( $monster, $arena, $type ))
57             {
58 0         0 return $monster->turn( $direction );
59             }
60              
61 4         13 my $closest = $monster->closest();
62 4         16 my $facing = $monster->facing();
63 4         11 my $pos = $arena->get_position( $monster );
64 4         5 my ($ax1, $ax2) = @{ $move_axis{ $facing } };
  4         11  
65              
66 4 50       13 my $move = ($pos->{ $ax1 } < $closest->{ $ax1 } ? $dir : -$dir);
67 4         13 $arena->move_monster( $monster, $ax1 => $move, $ax2 => 0 );
68             };
69             }
70              
71             my %turns =
72             (
73             north => { greater => 'right', lesser => 'left' },
74             south => { greater => 'left', lesser => 'right' },
75             east => { greater => 'left', lesser => 'right' },
76             west => { greater => 'right', lesser => 'left' },
77             );
78              
79             sub should_turn
80             {
81 8     8 0 16 my ($self, $monster, $arena, $type) = @_;
82              
83 8         19 my $facing = $monster->facing();
84 8         23 my $closest = $monster->closest();
85 8         28 my $pos = $arena->get_position( $monster );
86 8         11 my $axis = $move_axis{ $facing };
87 8         11 my $turn_dir = $turns{ $facing };
88 8         12 my ($ax1, $ax2) = @$axis;
89 8         15 my $limit = "${ax1}_limit";
90              
91             return unless
92 8 100 100     86 ( $type eq 'charge' && $pos->{$ax1} == $closest->{$ax2} )
      66        
      66        
      66        
93             or ( $type eq 'retreat' && ( $pos->{$ax1} == 0
94             or $pos->{$ax1} == $arena->$limit ));
95              
96 3 100       11 my $compare = $type eq 'charge' ?
97             $pos->{$ax2} > $closest->{$ax2} : $pos->{$ax2} < $closest->{$ax2};
98              
99 3 100       24 return $compare ? $turn_dir->{ lesser } : $turn_dir->{ greater };
100             }
101              
102             sub action_attack
103             {
104 3     3 1 2042 my ($self, $arena, $monster) = @_;
105 3         9 $arena->attack( $monster );
106             }
107              
108             1;
109             __END__