Commits

Anonymous committed 578196d

Added the pod.t and pod-coverage.t files, and added full POD coverage.

  • Participants
  • Parent commits 8c28b3d

Comments (0)

Files changed (18)

     - Added the Changes file.
     - Added the jumping_cards.pl example under examples.
     - Added the MIT X11 license as the LICENSE file.
+    - Added the t/pod.t and t/pod-coverage.t tests and added full
+    POD coverage.
 scripts/gen_use_test.pl
 t/00use.t
 TODO
+t/pod-coverage.t
+t/pod.t
 t/regression/regress.sh

lib/Games/LMSolve.pm

 After all that, in your main script initialize a registry object, and
 call the main() method.
 
-=head1 SEE ALSO
+=head1 METHODS
 
-L<Games::LMSolve::Base>
+=cut
 
-=head1 AUTHORS
+=head2 new
 
-Shlomi Fish E<lt>shlomif@vipe.technion.ac.ilE<gt>
+The constructor. Accepts the following named arguments:
+
+=over 4
+
+=item * 'default_variant'
+
+The default variant for the registry to be used in case one is not specified.
+
+=back
 
 =cut
 
     return 0;
 }
 
+=head2 $registry->set_default_variant($variant)
+
+Sets the default variant to $variant.
+
+=cut
+
 sub set_default_variant
 {
     my $self = shift;
     return 0;
 }
 
+=head2 $self->register_solvers(\%solvers)
+
+Adds the %solvers map of names to class names to the registry.
+
+=cut
+
 sub register_solvers
 {
     my $self = shift;
     return 0;
 }
 
+=head2 $self->register_all_solvers()
+
+To be sub-classes to register all the solvers that the registry wants
+to register. Does nothing here.
+
+=cut
+
 sub register_all_solvers
 {
     my $self = shift;
     return 0;
 }
 
+=head2 $self->main()
+
+the main function that handles the command line arguments and runs the
+program.
+
+=cut
+
 sub main
 {
     my $self = shift;
 }
 1;
 
+=head1 SEE ALSO
 
+L<Games::LMSolve::Base>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut

lib/Games/LMSolve/Alice.pm

 
 1;
 
+
+
+=head1 NAME
+
+Games::LMSolve::Alice - driver for solving the Alice
+mazes.
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about Alice mazes see L<http://www.logicmazes.com/alice.html>.
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Base.pm

 Afterwards, its interface functions can be invoked to actually solve
 the game.
 
-=head1 Methods to Override
+=head1 METHODS
+
+=head2 new()
+
+The constructor.
+
+=head2 $self->initialize()
+
+Should be inherited to implement the construction.
 
 =cut
-    
 
 sub new
 {
     return 0;
 }
 
-sub die_on_abstract_function
+=head2 $self->main()
+
+Actually solve the board based on the arguments in the command line.
+
+=cut
+
+my %scan_functions =
+(
+    'dfs' => sub {
+        my $self = shift;
+
+        return $self->_solve_brfs_or_dfs(1, @_);
+    },
+    'brfs' => sub {
+        my $self = shift;
+
+        return $self->_solve_brfs_or_dfs(0, @_);
+    },
+);
+
+sub main
+{
+    my $self = shift;
+
+    # This is a flag that specifies whether to present the moves in Run-Length
+    # Encoding.
+    my $to_rle = 1;
+    my $output_states = 0;
+    my $scan = "brfs";
+    my $run_time_states_display = 0;
+
+    #my $p = Getopt::Long::Parser->new();
+    if (! GetOptions('rle!' => \$to_rle, 
+        'output-states!' => \$output_states,
+        'method=s' => \$scan,
+        'rtd!' => \$run_time_states_display,
+        ))
+    {
+        die "Incorrect options passed!\n"
+    }
+
+    if (!exists($scan_functions{$scan}))
+    {
+        die "Unknown scan \"$scan\"!\n";
+    }
+
+    $self->{'cmd_line'}->{'to_rle'} = $to_rle;
+    $self->{'cmd_line'}->{'output_states'} = $output_states;
+    $self->{'cmd_line'}->{'scan'} = $scan;
+    $self->set_run_time_states_display($run_time_states_display && \&_default_rtd_callback);
+
+    my $filename = shift(@ARGV) || "board.txt";
+
+    my @ret = $self->solve_board($filename);
+
+    $self->display_solution(@ret);
+}
+
+
+=head1 METHODS TO OVERRIDE
+
+=cut
+    
+
+
+
+sub _die_on_abstract_function
 {
     my ($package, $filename, $line, $subroutine, $hasargs,
         $wantarray, $evaltext, $is_require, $hints, $bitmask) = caller(1);
 
 sub input_board
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 pack_state($self, $state_vector)
 # and returns an atom that represents it.
 sub pack_state
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 unpack_state($self, $packed_state)
 # and returns an array ref that represents it.
 sub unpack_state
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 display_state($self, $packed_state)
 # user-readable string that describes it.
 sub display_state
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 check_if_final_state($self, $state_vector)
 
 sub check_if_final_state
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 enumerate_moves($self, $state_vector)
 # one. I.e: it is possible that it is illegal to perform it.
 sub enumerate_moves
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 perform_move($self, $state_vector, $move)
 # Else, it returns undef to indicate that the move is not possible.
 sub perform_move
 {
-    return &die_on_abstract_function();
+    return _die_on_abstract_function();
 }
 
 =head2 check_if_unsolvable($self, $state_vector) (optional over-riding)
 
 =cut
 
-sub solve_brfs_or_dfs
+sub _solve_brfs_or_dfs
 {
     my $self = shift;
     my $state_collection = $self->{'state_collection'};
     return @ret;
 }
 
-sub run_length_encoding
+sub _run_length_encoding
 {
     my @moves = @_;
     my @ret = ();
     return @ret;    
 }
 
-my %scan_functions =
-(
-    'dfs' => sub {
-        my $self = shift;
 
-        return $self->solve_brfs_or_dfs(1, @_);
-    },
-    'brfs' => sub {
-        my $self = shift;
-
-        return $self->solve_brfs_or_dfs(0, @_);
-    },
-);
-
-sub solve_state
+sub _solve_state
 {
     my $self = shift;
     
 
     my $initial_coords = $self->input_board($filename);
 
-    return $self->solve_state($initial_coords, @_);
+    return $self->_solve_state($initial_coords, @_);
 }
 
 =head2 $self->run_scan(%args)
         my $num_state;
         if ($to_rle)
         {
-            my @moves_rle = &run_length_encoding(@moves);
+            my @moves_rle = _run_length_encoding(@moves);
             my ($m);
 
             $num_state = 0;
     print ((" " x $args{depth}) . join(",", @{$args{state}}) . " M=" . $self->render_move($args{move}) ."\n");
 }
 
-sub main
-{
-    my $self = shift;
-
-    # This is a flag that specifies whether to present the moves in Run-Length
-    # Encoding.
-    my $to_rle = 1;
-    my $output_states = 0;
-    my $scan = "brfs";
-    my $run_time_states_display = 0;
-
-    #my $p = Getopt::Long::Parser->new();
-    if (! GetOptions('rle!' => \$to_rle, 
-        'output-states!' => \$output_states,
-        'method=s' => \$scan,
-        'rtd!' => \$run_time_states_display,
-        ))
-    {
-        die "Incorrect options passed!\n"
-    }
-
-    if (!exists($scan_functions{$scan}))
-    {
-        die "Unknown scan \"$scan\"!\n";
-    }
-
-    $self->{'cmd_line'}->{'to_rle'} = $to_rle;
-    $self->{'cmd_line'}->{'output_states'} = $output_states;
-    $self->{'cmd_line'}->{'scan'} = $scan;
-    $self->set_run_time_states_display($run_time_states_display && \&_default_rtd_callback);
-
-    my $filename = shift(@ARGV) || "board.txt";
-
-    my @ret = $self->solve_board($filename);
-
-    $self->display_solution(@ret);
-}
-
 =head2 $self->set_run_time_states_display(\&states_display_callback)
 
 Sets the run time states display callback to \&states_display_callback.
 
 =head1 AUTHORS
 
-Shlomi Fish, E<lt>shlomif@vipe.technion.ac.ilE<gt>
+Shlomi Fish, L<http://www.shlomifish.org/>
 
 =cut 
 

lib/Games/LMSolve/Input.pm

 
 This class implements the C<input_board> method, which enables to read boards
 in "key = value" format. Several types of values are supported.
+
+=head2 METHODS
+
+=head2 $self->new()
+
+Constrcuts a new object. Accepts no meaningful arguments.
+
 =cut
 
 sub new
 
     bless $self, $class;
 
-    $self->initialize(@_);
+    $self->_initialize(@_);
 
     return $self;
 }
 
-sub initialize
+sub _initialize
 {
     my $self = shift;
 
     return 0;
 }
 
-=head1 $self->input_board($file_spec, $spec);
+=head2 $self->input_board($file_spec, $spec);
 
 This method accepts two arguments. C<$file_spec> which is the filename, 
 reference to a filehandle, or reference to the text containing the board 
     return $ret;
 }
 
+=head2 $self->input_horiz_vert_walls_layout($width, $height, \@lines)
+
+Input a horizontal-vertical line layout as exists in a maze.
+
+=cut
+
 sub input_horiz_vert_walls_layout
 {
     my $self = shift;
         $input_horiz_wall->();
         $input_vert_wall->();
     }
-    $input_horiz_wall->();    
+    $input_horiz_wall->();
 
     return (\@horiz_walls, \@vert_walls);
 }
 
 =head1 AUTHORS
 
-Written by Shlomi Fish E<lt>shlomif@vipe.technion.ac.ilE<gt>
+Written by Shlomi Fish ( L<http://www.shlomifish.org/> )
 
 =cut
 

lib/Games/LMSolve/Minotaur.pm

     return [ $thes_x, $thes_y, $mino_x, $mino_y ];
 }
 
-sub mino_move
+sub _mino_move
 {
     my $self = shift;
     my $horiz_walls = $self->{'horiz_walls'};
     my @new_coords = @$coords;
     $new_coords[0] += $offsets->[0];
     $new_coords[1] += $offsets->[1];
-    (@new_coords[2 .. 3]) = $self->mino_move(@new_coords);
+    (@new_coords[2 .. 3]) = $self->_mino_move(@new_coords);
 
     return \@new_coords;
 }
 
 1;
 
+=head1 NAME
+
+Games::LMSolve::Minotaur - driver for solving the "Theseus and the Minotaur"
+mazes.
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+L<http://www.logicmazes.com/theseus.html>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Numbers.pm

 
 1;
 
+
+=head1 NAME
+
+Games::LMSolve::Numbers - driver for solving the number
+mazes.
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+L<http://www.logicmazes.com/n1mz.html>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Plank/Base.pm

     $self->{'plank_lens'} = [ map { $_->{'len'} } @planks ];
     
     my $state = [ 0,  (map { ($_->{'start'}->{'x'}, $_->{'start'}->{'y'}, (($_->{'dir'} eq "E") ? 0 : ($_->{'dir'} eq "SE") ? 2 : 1)) } @planks) ];
-    $self->process_plank_data($state);
+    $self->_process_plank_data($state);
 
     #{
     #    use Data::Dumper;
     return $state;
 }
 
-sub process_plank_data
+sub _process_plank_data
 {
     my $self = shift;
 
 
     my $state = $self->unpack_state($packed_state);
 
-    my $plank_data = $self->process_plank_data($state);
+    my $plank_data = $self->_process_plank_data($state);
 
     my @strings;
     foreach my $p (@$plank_data)
 
     my $state = shift;
 
-    my $plank_data = $self->process_plank_data($state);
+    my $plank_data = $self->_process_plank_data($state);
 
     my $goal_x = $self->{'goal_x'};
     my $goal_y = $self->{'goal_y'};
 
     my $state = shift;
 
-    my $plank_data = $self->process_plank_data($state);
+    my $plank_data = $self->_process_plank_data($state);
 
     # Declare some accessors
     my $board = $self->{'board'};
     my $state = shift;
     my $m = shift;
 
-    my $plank_data = $self->process_plank_data($state);
+    my $plank_data = $self->_process_plank_data($state);
 
     my ($x,$y,$p,$dir) = @{$m}{qw(x y p dir)};
     my $dir_idx;
     @$new_state[0] = $p;
     @$new_state[(1+$p*3) .. (1+$p*3+2)] = ($x,$y,$dir_idx);
 
-    $self->process_plank_data($new_state);
+    $self->_process_plank_data($new_state);
     
     return $new_state;
 }
         return "";
     }
 }
+
+1;
+
+
+=head1 NAME
+
+Games::LMSolve::Plank::Base - driver for solving the rectangular Plank puzzles
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->initialize()
+
+The constructor.
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head2 $self->render_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about Plank puzzles see:
+
+L<http://www.clickmazes.com/planks/ixplanks.htm> .
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Plank/Hex.pm

 
 1;
 
+=head1 NAME
+
+Games::LMSolve::Plank::Hex - driver for solving the hex plank puzzles
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->initialize()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about Plank puzzles see:
+
+L<http://www.clickmazes.com/planks/ixplanks.htm> .
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Registry.pm

 
 use strict;
 
+=head1 NAME
+
+Games::LMSolve::Registry - the registry of all LM-Solve drivers.
+
+=head1 DESCRIPTION
+
+This is a registry of all LM-Solve drivers.
+
+=head1 METHODS 
+=cut
+
 use Games::LMSolve;
 
 use vars qw(@ISA);
 use Games::LMSolve::Tilt::RedBlue;
 use Games::LMSolve::Plank::Hex;
 
+=head2 $self->register_all_solvers()
+
+Register all the solvers.
+
+=cut
+
 sub register_all_solvers
 {
     my $self = shift;
 
 1;
 
+=head1 SEE ALSO
 
+L<Games::LMSolve>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+

lib/Games/LMSolve/Tilt/Base.pm

 }
 
 1;
+
+
+=head1 NAME
+
+Games::LMSolve::Tilt::Base - base class for the tilt mazes' drivers.
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->move_ball_to_end()
+
+Moves the ball to the end.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about tilt mazes see:
+
+http://www.clickmazes.com/indext.htm
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Tilt/Multi.pm

 }
 
 1;
+
+
+=head1 NAME
+
+Games::LMSolve::Tilt::Multi - driver for solving the multiple-goal tilt mazes
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about multiple-goal tilt mazes see:
+
+L<http://www.clickmazes.com/newtilt/ixtilt2d.htm>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Tilt/RedBlue.pm

 }
 
 1;
+
+
+=head1 NAME
+
+Games::LMSolve::Tilt::RedBlue - driver for solving the red blue tilt puzzles
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about red-blue tilt mazes see:
+
+L<http://www.clickmazes.com/newtilt/ixtilt.htm>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+

lib/Games/LMSolve/Tilt/Single.pm

 }
 
 1;
+
+
+=head1 NAME
+
+Games::LMSolve::Tilt::Single - driver for solving the single-goal tilt mazes
+
+=head1 SYNOPSIS
+
+NA - should not be used directly.
+
+=head1 METHODS
+
+=head2 $self->input_board()
+
+Overrided.
+
+=head2 $self->pack_state()
+
+Overrided.
+
+=head2 $self->unpack_state()
+
+Overrided.
+
+=head2 $self->display_state()
+
+Overrided.
+
+=head2 $self->check_if_unsolvable()
+
+Overrided.
+
+=head2 $self->check_if_final_state()
+
+Overrided.
+
+=head2 $self->enumerate_moves()
+
+Overrided.
+
+=head2 $self->perform_move()
+
+Overrided.
+
+=head1 SEE ALSO
+
+L<Games::LMSolve::Base>.
+
+For more about single-goal tilt mazes see:
+
+L<http://www.clickmazes.com/newtilt/ixtilt2d.htm>
+
+=head1 AUTHORS
+
+Shlomi Fish, L<http://www.shlomifish.org/>
+
+=cut
+
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+eval 'use Test::Pod::Coverage 1.04';
+plan skip_all => 'Test::Pod::Coverage 1.04 required for testing POD coverage' if $@;
+all_pod_coverage_ok();
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+eval 'use Test::Pod 1.14';
+plan skip_all => 'Test::Pod 1.14 required for testing POD' if $@;
+all_pod_files_ok();

t/regression/regress.sh

     local method="$1"
     local path="$dir/$T"
     (cd ../../ && perl -I./lib ./lm-solve -g $maze_type --rtd --method $method --output-states t/regression/layouts/$path) | md5sum > checksums/$path.$method.md5.new
-    if ! cmp checksums/$path.brfs.md5.new checksums/$path.brfs.md5 ; then
+    if ! cmp checksums/$path.$method.md5.new checksums/$path.$method.md5 ; then
         echo "$method solutions are not equal for $path"
     fi
 }