Perl6-Pugs/ext/Automata-Cellular/lib/Automata/Cellular.pm
use v6-alpha;
=head1 NAME
Automata::Cellular - Build and render Cellular Automata on a terminal
=head1 VERSION
Version 0.1
=head1 DESCRIPTION
C<Automata::Cellular> is the meat of this module; everything you need for
most investigations should be included by:
use Automata::Cellular;
This code makes use of the object-oriented goodness found in the Moose
framework. As such, even if you find A::C useless in terms of performance
or functionality, you should still be able to enjoy reading the code.
=head1 DEPENDENCIES
C<Automata::Cellular> is written in Perl 6, and currently runs via Pugs
=head1 EXAMPLE
my Automata::Cellular::Rule $rule .= new(30);
my Automata::Cellular $ca .= new( :@state, :$rule, :$steps, :$display_width);
while($ca++) {
say $ca.prettystate();
}
=head1 AUTHOR
David Brunton - dbrunton@plusthree.com
=cut
use Automata::Cellular::Rule;
class Automata::Cellular-0.1
does Automata::Cellular::Rule
{
# future enhancement: accept a $rule_number, and build a rule in BUILD
has Automata::Cellular::Rule $.rule;
has Bool @.state is rw;
has Int $.steps;
has Int $.rule_number;
has Int $.display_width;
has Int $.stage is rw;
# used to set initial stage and defaults
submethod BUILD (:$.rule_number,
:$.steps = 10,
:$.display_width = 30,
:$.stage = 1) {
$.rule = Automata::Cellular::Rule.new(:$.rule_number);
my $width = $.display_width + $.steps * 2;
@.state = 0 xx $width;
@.state[int($width/2)] = 1;
}
# "pretty" being a relative term, on a terminal
method prettystate (Str $true = 'x', Str $false = '.') {
my $state = (+<<@.state[$.steps..(@.state.elems() - $.steps)]).join("");
$state ~~ s:g/0/$false/;
$state ~~ s:g/1/$true/;
"Stage $.stage: $state";
}
multi sub *postfix:<++> (Automata::Cellular $self) {
my @old_state = $self.state;
for ( 0 .. (@old_state.elems - 2) ) -> $index {
my $index_key =
:2((+<<@old_state[ $index .. $index + 2 ]).join(""));
$self.state[ $index + 1 ] = $self.rule.rule{$index_key};
}
$self.stage = $self.stage + 1;
if $self.stage >= $self.steps { return Bool::False; }
else { return Bool::True; }
}
} # class Automata::Cellular