File Coverage

blib/lib/Games/LMSolve/Tilt/Multi.pm
Criterion Covered Total %
statement 15 81 18.5
branch 0 6 0.0
condition 0 6 0.0
subroutine 5 12 41.6
pod 7 7 100.0
total 27 112 24.1


line stmt bran cond sub pod time code
1             package Games::LMSolve::Tilt::Multi;
2             $Games::LMSolve::Tilt::Multi::VERSION = '0.14.0';
3 1     1   957 use strict;
  1         2  
  1         33  
4 1     1   5 use warnings;
  1         4  
  1         23  
5              
6 1     1   5 use Games::LMSolve::Tilt::Base;
  1         2  
  1         32  
7              
8 1     1   6 use Games::LMSolve::Input;
  1         2  
  1         41  
9              
10 1     1   6 use vars qw(@ISA);
  1         2  
  1         786  
11              
12             @ISA = qw(Games::LMSolve::Tilt::Base);
13              
14             sub input_board
15             {
16 0     0 1   my $self = shift;
17 0           my $filename = shift;
18              
19 0           my $spec = {
20             'dims' => { 'type' => "xy(integer)", 'required' => 1 },
21             'start' => { 'type' => "xy(integer)", 'required' => 1 },
22             'goals' => { 'type' => "array(xy(integer))", 'required' => 1 },
23             'layout' => { 'type' => "layout", 'required' => 1 },
24             };
25              
26 0           my $input_obj = Games::LMSolve::Input->new();
27              
28 0           my $input_fields = $input_obj->input_board( $filename, $spec );
29              
30             my ( $width, $height ) =
31 0           @{ $input_fields->{'dims'}->{'value'} }{ 'x', 'y' };
  0            
32             my ( $start_x, $start_y ) =
33 0           @{ $input_fields->{'start'}->{'value'} }{ 'x', 'y' };
  0            
34              
35 0 0 0       if ( ( $start_x >= $width ) || ( $start_y >= $height ) )
36             {
37 0           die
38             "The Starting position is out of bounds of the board in file \"$filename\"!\n";
39             }
40              
41 0           my @goals_map = map { [ (0) x $width ] } ( 1 .. $height );
  0            
42 0           my $goals = $input_fields->{'goals'}->{'value'};
43 0           my $goal_id = 1;
44 0           foreach my $g (@$goals)
45             {
46 0           my $x = $g->{'x'};
47 0           my $y = $g->{'y'};
48 0 0 0       if ( ( $x >= $width ) || ( $y >= $height ) )
49             {
50 0           die
51             "The goal ($x,$y) is out of bounds of the board in file \"$filename\"!\n";
52             }
53 0           $goals_map[$y]->[$x] = $goal_id;
54 0           $goal_id++;
55             }
56              
57             my ( $horiz_walls, $vert_walls ) =
58             $input_obj->input_horiz_vert_walls_layout( $width, $height,
59 0           $input_fields->{'layout'} );
60              
61 0           $self->{'width'} = $width;
62 0           $self->{'height'} = $height;
63 0           $self->{'horiz_walls'} = $horiz_walls;
64 0           $self->{'vert_walls'} = $vert_walls;
65 0           $self->{'goals_map'} = \@goals_map;
66 0           $self->{'num_goals'} = ( $goal_id - 1 );
67              
68 0           my $reached_goals_bitmap = 0;
69              
70 0           my $dest_goals_bitmap = 0;
71 0           for ( my $i = 1 ; $i < $goal_id ; $i++ )
72             {
73 0           $dest_goals_bitmap |= ( 1 << $i );
74             }
75              
76 0           $self->{'dest_goals_bitmap'} = $dest_goals_bitmap;
77              
78 0           return [ $start_x, $start_y, $reached_goals_bitmap ];
79             }
80              
81             sub pack_state
82             {
83 0     0 1   my $self = shift;
84 0           my $state_vector = shift;
85              
86 0           return pack( "ccL", @$state_vector );
87             }
88              
89             sub unpack_state
90             {
91 0     0 1   my $self = shift;
92 0           my $state = shift;
93 0           return [ unpack( "ccL", $state ) ];
94             }
95              
96             sub display_state
97             {
98 0     0 1   my $self = shift;
99 0           my $state = shift;
100             my ( $x, $y, $reached_goals ) =
101 0           ( map { $_ + 1 } @{ $self->unpack_state($state) } );
  0            
  0            
102             return "($x,$y) Goals Collected=["
103             . join(
104             ",",
105             (
106 0           grep { $reached_goals &= ( 1 << $_ ) }
107 0           ( 1 .. ( $self->{'num_goals'} ) )
108             )
109             ) . "]";
110             }
111              
112             sub check_if_final_state
113             {
114 0     0 1   my $self = shift;
115              
116 0           my $coords = shift;
117              
118 0           return ( $coords->[2] == $self->{'dest_goals_bitmap'} );
119             }
120              
121             sub enumerate_moves
122             {
123 0     0 1   my $self = shift;
124 0           my $coords = shift;
125              
126 0           return (qw(u d l r));
127             }
128              
129             sub perform_move
130             {
131 0     0 1   my $self = shift;
132              
133 0           my $coords = shift;
134 0           my $move = shift;
135              
136 0           my ( $new_coords, $intermediate_states ) =
137             $self->move_ball_to_end( $coords, $move );
138              
139 0           my $goal_bitmap = $coords->[2];
140              
141 0           my $goals_map = $self->{'goals_map'};
142 0           foreach my $state (@$intermediate_states)
143             {
144 0           my ( $x, $y ) = @$state;
145 0           my $goal = $goals_map->[$y]->[$x];
146              
147             #printf("Goal=%i\n", $goal);
148 0 0         if ( $goal > 0 )
149             {
150 0           $goal_bitmap |= ( 1 << $goal );
151             }
152             }
153              
154 0           return [ @$new_coords, $goal_bitmap ];
155             }
156              
157             1;
158              
159             __END__