my $half = 16; # make 32 for 64-bit perls
####
my $half = 32; # make 32 for 64-bit perls
##
##
package Organism;
use strict;
use warnings;
sub count {
return scalar keys %{ shift->{Cells} };
}
# Input a list of [ x, y ] coords
sub insert_cells {
my $self = shift;
my $cells = $self->{Cells};
for my $r (@_) { $cells->{
(($r->[0] + $self->{fudge}) << $self->{half}) |
($r->[1] + $self->{fudge})
} = undef }
}
# Return sorted list of cells in the Organism.
# Used for verification and testing the state of the organism.
sub get_live_cells {
my $self = shift;
sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] }
map { [
($_ >> $self->{half}) - $self->{fudge},
($_ & (1 << $self->{half}) - 1) - $self->{fudge}
] } keys %{ $self->{Cells} };
}
sub tick {
my $self = shift;
my $cells = $self->{Cells};
my @deltas = @{ $self->{deltas} };
my ( %new_cells, %dead_cells );
for my $c (keys %{ $cells }) {
# Get the (up to 8) dead cells surrounding the cell
$dead_cells{$_}++ for my @zcells =
grep !exists $cells->{$_}, map $c + $_, @deltas;
# Check the live cell
# Note: next line equivalent to nlive == 2 || nlive == 3
@zcells == 5 || @zcells == 6 and $new_cells{$c} = undef;
}
$dead_cells{$_} == 3 and $new_cells{$_} = undef for keys %dead_cells;
$self->{Cells} = \%new_cells;
}
sub new {
my $class = shift;
my $half = 16; # make 32 for 64-bit perls
my $base = 1 << $half;
my $fudge = $base >> 1;
my @deltas = ($base-1, $base, $base+1,
-1, 1, -$base-1, -$base, -$base+1);
my %init_self = ( Cells => {},
fudge => $fudge, half => $half, deltas => \@deltas );
bless \%init_self, $class;
}
1;