File Coverage

blib/lib/Games/Worms/Beeler.pm
Criterion Covered Total %
statement 9 39 23.0
branch 0 22 0.0
condition 0 5 0.0
subroutine 3 5 60.0
pod 0 2 0.0
total 12 73 16.4


line stmt bran cond sub pod time code
1             package Games::Worms::Beeler;
2 1     1   18077 use strict;
  1         3  
  1         68  
3 1     1   6 use vars qw($Debug $VERSION @ISA);
  1         1  
  1         83  
4 1     1   8 use Games::Worms::Base 0.6;
  1         35  
  1         1084  
5             @ISA = ('Games::Worms::Base');
6             $Debug = 0;
7             $VERSION = "0.60";
8              
9             my %let2num = qw(A 1 B 2 C 3 D 4);
10              
11             =head1 NAME
12              
13             Games::Worms::Beeler -- class for Conway/Patterson/Beeler worms
14              
15             =head1 SYNOPSIS
16              
17             perl -MGames::Worms -e worms -- -tTk Games::Worms::Beeler/1a2d3cbaa4b
18              
19             =head1 DESCRIPTION
20              
21             This class implements Conway/Patterson/Beeler worms -- "Beeler worms"
22             for short.
23              
24             See the I reference in L.
25              
26             Note that my notation for rule-strings is directly taken from that
27             article.
28              
29             =cut
30              
31             #--------------------------------------------------------------------------
32             # init rules.
33              
34             sub init {
35 0     0 0   my $worm = $_[0];
36              
37 0           $worm->{'memory'} = {}; # for memoization
38              
39 0   0       $worm->{'rules'} ||= # default to a random rule
40             join('',
41             '1', (qw(A B))[rand 2],
42             '2', (qw(A B C D))[rand 4],
43             '3', (qw(A B C))[rand 3], (qw(A B C))[rand 3],
44             (qw(A B C))[rand 3], (qw(A B C))[rand 3],
45             '4', (qw(A B))[rand 2],
46             );
47              
48 0 0         die "Rule string $worm->{'rules'} is malformed"
49             unless uc($worm->{'rules'}) =~
50             /^1([AB])
51             2([ABCD])
52             3([ABC])([ABC])([ABC])([ABC])
53             4([AB])
54             $
55             /xs;
56 0           @{$worm}{
57 0           qw(beeler_1
58             beeler_2
59             beeler_3a beeler_3b beeler_3c beeler_3d
60             beeler_4
61             )
62             } = map($let2num{$_}, $1, $2, $3, $4, $5, $6, $7);
63              
64 0           $worm->{'name'} .= '/' . $worm->{'rules'};
65            
66 0           $worm->SUPER::init;
67 0           return;
68             }
69              
70             #--------------------------------------------------------------------------
71             # a necessary data table
72              
73             my %group3rules = ( # A B C
74             '00111' => ['beeler_3a', [0,1,2]],
75             '01011' => ['beeler_3a', [2,0,1]],
76              
77             '10011' => ['beeler_3b', [0,1,2]],
78             '01110' => ['beeler_3b', [1,0,2]],
79              
80             '11001' => ['beeler_3c', [0,1,2]],
81             '10101' => ['beeler_3c', [1,0,2]],
82              
83             '11100' => ['beeler_3d', [0,1,2]],
84             '11010' => ['beeler_3d', [0,1,2]],
85              
86             # the two 'unnatural' cases:
87             '01101' => ['beeler_3d', [0,1,2]],
88             '10110' => ['beeler_3d', [0,1,2]],
89              
90              
91             );
92              
93             #--------------------------------------------------------------------------
94              
95             sub which_way { # figure out which direction to go in
96 0     0 0   my($worm, $hash_r, $list_r, $context) = @_;
97              
98 0           my $situation = substr($context,1);
99              
100 0 0         return($worm->{'memory'}{$situation}) # memoization
101             if exists $worm->{'memory'}{$situation};
102              
103 0           my $rules = $worm->{'rules'};
104 0 0         die "No rules for worm $worm?\n" unless $rules;
105              
106 0           my $free_count = grep($_, @$list_r);
107 0           my @avail = grep($list_r->[$_], (1,2,3,4,5));
108 0 0         print "% $free_count nodes free: $situation (@avail) | " if $Debug;
109              
110 0           my($rule, $dir);
111              
112 0 0         if($free_count >= 5) { $rule = 'beeler_1';
  0 0          
    0          
    0          
113 0           splice(@avail,0,3); # leaving just the last 2
114 0           } elsif($free_count == 2) { $rule = 'beeler_4';
115 0           } elsif($free_count == 4) { $rule = 'beeler_2';
116             } elsif($free_count == 3) { # Rule 3...
117 0   0       my $sit_entry = $group3rules{$situation}
118             || die "Tilt! Unknown situation $situation\n";
119 0           $rule = $sit_entry->[0];
120 0           $dir = $avail[
121             $sit_entry->[1]->[ $worm->{$rule} - 1 ]
122             ];
123             }
124              
125 0 0         die "No deciding rule?" unless $rule;
126              
127 0 0         $dir = $avail[ $worm->{$rule} - 1] unless defined($dir);
128 0 0         print " out of ", join('', @avail),
129             ", going R$dir via rule $rule (=", $worm->{$rule}, ")\n"
130             if $Debug;
131              
132 0           return( $worm->{'memory'}{$situation} = $dir );
133             }
134              
135             #--------------------------------------------------------------------------
136             1;
137              
138             __END__