File Coverage

blib/lib/Games/BonDigi.pm
Criterion Covered Total %
statement 49 49 100.0
branch 10 10 100.0
condition 4 6 66.6
subroutine 10 10 100.0
pod 2 2 100.0
total 75 77 97.4


line stmt bran cond sub pod time code
1             # $Id: BonDigi.pm 17 2008-01-13 14:23:52Z Cosimo $
2              
3             package Games::BonDigi;
4              
5 4     4   10595 use strict;
  4         7  
  4         181  
6 4     4   23 use warnings;
  4         7  
  4         132  
7 4     4   22 use Carp qw(croak);
  4         15  
  4         324  
8              
9             our $VERSION = '0.02';
10              
11 4     4   22 use constant HEADER => 0;
  4         8  
  4         226  
12 4     4   19 use constant PAYLOAD => 1;
  4         6  
  4         203  
13 4     4   19 use constant REPEAT_WORD => 0;
  4         7  
  4         157  
14 4     4   17 use constant REPEAT_SEQ => 1;
  4         6  
  4         1651  
15              
16              
17             #
18             # Class constructor
19             #
20             sub new
21             {
22 3     3 1 498 my($class) = @_;
23 3   33     25 $class = ref($class) || $class;
24 3         7 my $self = [];
25 3         13 bless $self, $class;
26             }
27              
28             #
29             # Build and return an iterator for the Bon-Digi-... sequence
30             # Every time you call it, it gives you the right word
31             # to be said. Hopefully.
32             #
33             # Sequence is: Bon, Digi, Bon, Digi (header)
34             # Bon, Bon, Digi, Digi (payload x 2),
35             # Bon, Digi, Bon, Digi (header again),
36             # Bon, Bon, Bon, Digi, Digi, Digi (payload x 3),
37             # Bon, Digi, Bon, Digi (header again),
38             # <...> (payload x 4),
39             # <...>
40             # <...> (payload x n),
41             #
42             sub sequence
43             {
44 5     5 1 313 my($self, $start, $end, @words) = @_;
45 5 100       16 $start = 2 unless defined $start;
46 5 100       17 $end = 0 unless defined $end;
47 5 100       19 @words = qw(bon digi) unless @words;
48              
49             #
50             # Message structure is composed of:
51             #
52             # [HEADER] (fixed: "bon digi bon digi") +
53             # [PAYLOAD] (grows over time: "bon bon digi digi", "bon bon bon digi digi digi")
54             #
55 5         20 my @repeats = (
56             # This is the HEADER definition. Each word is repeated once,
57             # 2 repeats of entire sequence (ex. "bon digi bon digi")
58             [1, 2],
59              
60             # This is the PAYLOAD definition
61             # each word is repeated '$start' times (and that keeps growing)
62             # only 1 repeat of entire sequence (ex.: "bon bon digi digi")
63             [$start, 1],
64             );
65              
66             #
67             # Define static vars for the iterator sub
68             #
69 5         9 my $rep =
70             my $word =
71             my $i =
72             my $seq = 0;
73              
74             my $iterator = sub
75             {
76 178     178   772 SEQUENCE: while($seq < $repeats[$rep][REPEAT_SEQ])
77             {
78 190         358 while($word < @words)
79             {
80 225         508 while($i++ < $repeats[$rep][REPEAT_WORD])
81             {
82 155         633 return $words[$word];
83             }
84 70         76 $i = 0;
85 70         136 $word++;
86             }
87 35         36 $seq++;
88 35         37 $i = 0;
89 35         73 $word = 0;
90             }
91              
92             # Reinitialize sequence and restart
93 23         27 $rep = 1 - $rep;
94 23         30 $seq = $i = $word = 0;
95              
96             # Payload now must grow by 1
97 23 100       47 if($rep == HEADER)
98             {
99 11         16 $repeats[PAYLOAD][REPEAT_WORD]++;
100              
101             # Check for sequence termination.
102             # We don't want to generate more than `$end' repetitions
103             # If $end == 0, sequence is unterminated
104 11 100 100     41 if($end > 0 && $repeats[PAYLOAD][REPEAT_WORD] > $end)
105             {
106 1         4 return undef;
107             }
108             }
109              
110             # Yes, a GOTO here
111 22         44 goto SEQUENCE;
112 5         41 };
113              
114 5         18 return $iterator;
115             }
116              
117             1;
118              
119             __END__