File Coverage

blib/lib/Game/Life/NDim/Life.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Game::Life::NDim::Life;
2              
3             # Created on: 2010-01-04 18:54:13
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 1     1   1277 use Moose;
  0            
  0            
10             use warnings;
11             use version;
12             use Carp;
13             use Data::Dumper qw/Dumper/;
14             use English qw/ -no_match_vars /;
15             use List::Util qw/sum max min/;
16              
17             use overload '""' => \&to_string;
18              
19             our $VERSION = version->new('0.0.2');
20             our @EXPORT_OK = qw//;
21             our %EXPORT_TAGS = ();
22             #our @EXPORT = qw//;
23              
24             has type => (
25             is => 'rw',
26             isa => 'Str',
27             default => 0,
28             );
29              
30             has next_type => (
31             is => 'rw',
32             isa => 'Str',
33             );
34              
35             has board => (
36             is => 'rw',
37             isa => 'Game::Life::NDim::Board',
38             required => 1,
39             weak_ref => 1,
40             );
41              
42             has position => (
43             is => 'rw',
44             isa => 'Game::Life::NDim::Dim',
45             required => 1,
46             );
47              
48             sub seed {
49             my ($self, $types) = @_;
50             my $new_type;
51              
52             TYPE:
53             while (!defined $new_type) {
54             for my $type (keys %{$types}) {
55             if ( rand() < $types->{$type} ) {
56             $new_type = $type;
57             last TYPE;
58             }
59             }
60             }
61              
62             $self->type($new_type);
63              
64             return $self;
65             }
66              
67             # process
68             sub process {
69             my ($self, $rules) = @_;
70              
71             $self->next_type($self->type);
72              
73             # process the rules in order until a rule is found that returns a type to
74             # change too, rules that maintain status quoe return undef
75             RULE:
76             for my $rule (@{ $rules } ) {
77             my $change = $rule->($self);
78              
79             # next if status quoe
80             next RULE if !defined $change;
81              
82             # stage the changed type
83             $self->next_type($change);
84             last RULE;
85             }
86              
87             return $self;
88             }
89              
90             sub set {
91             my ($self) = @_;
92              
93             $self->type($self->next_type);
94              
95             return $self;
96             }
97              
98             sub surround {
99             my ($self, $level) = @_;
100             my $max = $self->board->dims;
101             my @lives;
102             my $cursor = $self->position->clone;
103              
104             $level ||= 1;
105             my $itter = $self->transformer;
106              
107             while (my $transform = $itter->()) {
108             my $life = eval{ $self->board->get_life($self->position + $transform) };
109             if (!$EVAL_ERROR) {
110             push @lives, $life;
111             }
112             else { warn "Error: $EVAL_ERROR\n"; }
113             }
114              
115             return \@lives;
116             }
117              
118             sub transformer {
119             my ($self) = @_;
120             my @max = @{ $self->board->dims };
121             my $max = @max - 1;
122             my @transform;
123             my @alter;
124             for (0 .. $max) {
125             push @transform, -1;
126             }
127             my $point;
128              
129             my $itter;
130             $itter = sub {
131             if (!defined $point) {
132             $point = 0;
133             return [@transform];
134             }
135              
136             my $done = 0;
137             while (!$done) {
138             if ($transform[$point] + 1 <= 1) {
139             $transform[$point]++;
140             $done = 1;
141             $point = 0;
142             last;
143             }
144             $transform[$point] = -1;
145             $point++;
146             my $undef;
147             return $undef if !exists $transform[$point];
148             }
149              
150             return $itter->() if ($max + 1 == (grep {$_ == 0} @transform));
151              
152             return [@transform];
153             };
154              
155             return $itter;
156             }
157              
158             sub clone {
159             my ($self) = @_;
160              
161             return __PACKAGE__->new(type => $self->type, board => $self->board, position => $self->position);
162             }
163              
164             sub to_string {
165             my ($self) = @_;
166              
167             return $self->type;
168             }
169              
170             1;
171              
172             __END__
173              
174             =head1 NAME
175              
176             Game::Life::NDim::Life - Object representing a life
177              
178             =head1 VERSION
179              
180             This documentation refers to Game::Life::NDim::Life version 0.0.2.
181              
182              
183             =head1 SYNOPSIS
184              
185             use Game::Life::NDim::Life;
186              
187             # Brief but working code example(s) here showing the most common usage(s)
188             # This section will be as far as many users bother reading, so make it as
189             # educational and exemplary as possible.
190              
191              
192             =head1 DESCRIPTION
193              
194             =head1 SUBROUTINES/METHODS
195              
196             =head2 C<seed ( )>
197              
198             =head2 C<process ( )>
199              
200             =head2 C<set ( )>
201              
202             =head2 C<surround ( )>
203              
204             =head2 C<transformer ( )>
205              
206             =head2 C<clone ( )>
207              
208             =head2 C<to_string ( )>
209              
210              
211             =head1 DIAGNOSTICS
212              
213             =head1 CONFIGURATION AND ENVIRONMENT
214              
215             =head1 DEPENDENCIES
216              
217             =head1 INCOMPATIBILITIES
218              
219             =head1 BUGS AND LIMITATIONS
220              
221             There are no known bugs in this module.
222              
223             Please report problems to Ivan Wills (ivan.wills@gmail.com).
224              
225             Patches are welcome.
226              
227             =head1 AUTHOR
228              
229             Ivan Wills - (ivan.wills@gmail.com)
230              
231             =head1 LICENSE AND COPYRIGHT
232              
233             Copyright (c) 2010 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
234             All rights reserved.
235              
236             This module is free software; you can redistribute it and/or modify it under
237             the same terms as Perl itself. See L<perlartistic>. This program is
238             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
239             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
240             PARTICULAR PURPOSE.
241              
242             =cut