Whew!use v6-alpha; # By Christmas, we should be able to say "use v6;"
class Rule { # See Deus Ex Automatis Part V(a)
has Int $.number is ro;
has Int $.neighbors is ro;
has Bool %.lookup is rw;
submethod BUILD (:$.number, :$.neighbors) {
for ( 0 .. (2 ** $.neighbors -1) ) -> $key {
my $format = "\%0" ~ $.neighbors ~ "b";
%.lookup{sprintf($format,$key)} = ?($.number +& (1 ~ 0 x $key) );
}
}
}
class Grid {
has Int $.diameter is rw;
has Bool @.state is rw;
submethod BUILD (:$.diameter) {
@.state = 1,;
@.state.push( 0 xx ($.diameter-1) );
}
}
class Automaton does Rule does Grid { # "does" gives us a mix-in pattern
has Rule $.rule is rw; # the "Rule" is a reference to our own class
has Grid $.grid is rw; # as is Grid
submethod BUILD (:$diameter, :$rule) { # new() takes two arguments
$.grid = Grid.new(:$diameter);
$.rule = Rule.new(:number($rule), :neighbors(2));
}
method next { # The "guts" where we apply the rule to the grid
# Also, incidentally, our first method !!
my @old = $.grid.state();
for ( 0 .. $.grid.diameter-1 ) -> $i {
$.grid.state[$i] = ~+$.rule.lookup{ @old[$i] ~ @old[$i-1] };
}
return Bool::True; # Lets us easily use this in a loop
}
}
##
# The script! This will print beautiful cellular automata on your screen.
my Automaton $ca .= new(:diameter(10), :rule(6));
say $ca.grid.state while $ca.next();
Labels: cellular automata, deusexautomatis, etech
Subscribe to
Posts [Atom]