Friday, April 20, 2007
Deus Ex Automatis, Part V(c)
In our final segment of Part V, we tie together all the code into a single, cohesive whole, and run it. In the interest of getting it done more quickly, and in a literate programming style, I've noted some of the nice features of Perl 6 in the comments.
A simple Copy/Paste should get this code going for you in Pugs:
I may come back later and edit this post to add a bit more commentary. In the meantime, note that this code (in a somewhat complicated, and somewhat slow manner) implements the class of cellular automata we've been discussing through this entire series.
I'm going to move on in the next segment to talking about why it's important.
A simple Copy/Paste should get this code going for you in Pugs:
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();
I may come back later and edit this post to add a bit more commentary. In the meantime, note that this code (in a somewhat complicated, and somewhat slow manner) implements the class of cellular automata we've been discussing through this entire series.
I'm going to move on in the next segment to talking about why it's important.
Labels: cellular automata, deusexautomatis, etech
Subscribe to Posts [Atom]