NAME

Algorithm::Gutter - cellular automata to simulate rain in a gutter

SYNOPSIS

use Algorithm::Gutter;
my $g = Algorithm::Gutter->new(
    gutter => [ map Algorithm::Gutter::Cell->new, 1 .. 4 ],
    rain   => sub {
        my ($gutter) = @_;
        $gutter->[ rand @$gutter ]->amount += 1 + int( rand 4 );
    },
);
$g->gutter->[1]->enabled = 1;
$g->gutter->[1]->update  = sub {
    my ( $cell, $index, $amount, $stash ) = @_;
    return [ $index, $amount ];    
};
$g->gutter->[1]->threshold = 4;

for my $turn ( 1 .. 20 ) {
    $g->rain;
    my @out = $g->drain;
    if (@out) {
        warn "$turn drains $out[0][0] amount $out[0][1]\n";
    }
    $g->slosh;
}

See also the eg directory of this module's distribution for example scripts.

DESCRIPTION

This module models a rain gutter, composed of discrete cells, where some cells have holes in them, of some threshold value, that when the threshold is reached the fluid will drain from that cell, triggering a piece of code supplied by the caller. Other methods are provided to simulate rain (up to the caller) and to redistribute the fluid between adjacent cells (with a slow and simple algorithm).

Productive uses (dubious--discuss) include procedural generation, in particular music composition where one may want rhythmic effects similar to water accumulating and then dripping out of a rain gutter.

The cells are held in an array reference (the gutter); the caller may need to fiddle around with the cells directly simulate various effects.

Various methods may throw errors, for example if a cell lacks an update callback function. Such callbacks are not mandatory to give the caller flexibility in wiring up the gutter in fancy ways.

FIELDS

gutter

An optional array reference of objects that conform to the Algorithm::Gutter::Cell model. The caller should supply (or populate) this list, as this module will not do much without a list of cells to iterate over.

rain

An optional code reference that the rain convenience method calls to simulate rain falling into the cells of the gutter.

METHODS

drain [ drain-all? [ stash ] ]

Drains any enabled cells with holes in them, triggering a drain method call on any relevant cells. The drain-all? boolean controls whether all of the fluid drains, or only a value equal to the threshold involved. The user may pass an optional stash that is supplied to sub-drain calls.

The return value is whatever the sub-drain calls return.

new [ fields ... ]

Constructor.

rain [ stash ]

A convenience method to call the user-supplied rain callback that presumably adds some amount of fluid to some number of cells.

set_rain [ code-reference ]

Writer method for the rain field.

slosh [ max-iterations [ delta ] ]

Redistributes imbalances in fluid levels between adjacent cells. max-iterations is by default a very large number, though could be set to a much lower strictly positive integer value to make the fluid act in a more viscous manner, or less prone to slosh into adjacent cells during a single call to this method. delta (by default 1) controls when a slosh is triggered, and could be set to higher values to make the fluid behave more like a solid faulting into adjacent cells?

The return value is the number of loops the slosh method took to level out the fluid.

BUGS

These probably should be called errors, not bugs.

SEE ALSO

Object::Pad

AUTHOR

Jeremy Mates

COPYRIGHT AND LICENSE

Copyright (C) 2024 by Jeremy Mates

This module is distributed under the (Revised) BSD License.