use v6-alpha; =head1 NAME Automata::Cellular - Build and render Cellular Automata on a terminal =head1 VERSION Version 0.1 =head1 DESCRIPTION C 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 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