AI-Termites

 view release on metacpan or  search on metacpan

lib/AI/Termites.pm  view on Meta::CPAN

package AI::Termites;

use 5.010;

our $VERSION = '0.02';

use strict;
use warnings;

use Math::Vector::Real;
use Math::Vector::Real::Random;

use List::Util;
use Carp;

sub new {
    my ($class, %opts) = @_;
    my ($dim, $box);
    $box = delete $opts{box};
    if (defined $box) {
	$box = V(@$box);
	$dim = @$box;
    }
    else {
	$dim = delete $opts{dim} // 3;
	my $size = delete $opts{world_size} // 1000;
	$box = Math::Vector::Real->cube($dim, $size);
    }

    my $box_vol = 1;
    $box_vol *= $_ for @$box;

    my $n_termites = delete $opts{n_termites} // 50;
    my $n_wood = delete $opts{n_wood} // 200;
    my $iterations = delete $opts{iterations} // 0;
    my $termite_speed = delete $opts{termite_speed} // abs($box)/10;
    my $near = delete $opts{near} // abs($box)/50;
    %opts and croak "unknown parameter(s) ". join(", ", keys %opts);

    my @wood;
    my @termites;

    my $self = { wood => \@wood,
		 termites => \@termites,
		 iteration => 0,
		 speed => $termite_speed,
		 box => $box,
                 box_vol => $box_vol,
                 wood_density => $n_wood/$box_vol,
                 near => $near,
                 inear2 => 1/($near * $near),
                 near_dim => $near ** $dim,
                 taken => 0,
		 dim => $dim };

    bless $self, $class;

    push @wood, $self->new_wood for (1..$n_wood);
    push @termites, $self->new_termite for (1..$n_termites);
    $self->iterate for (1..$iterations);
    $self;
}

sub dim { shift->{dim} }

sub box { shift->{box} }

sub new_wood {
    my $self = shift;
    my $wood = { pos => $self->{box}->random_in_box,
		 taken => 0 };
}

sub new_termite {
    my $self = shift;
    my $termite = { pos => $self->{box}->random_in_box };
}

sub iterate {
    my $self = shift;

    $self->before_termites_move;

    for my $term (@{$self->{termites}}) {
	$self->termite_move($term);
    }
    $self->before_termites_action;
    for my $term (@{$self->{termites}}) {
	$self->termite_action($term);
    }
    $self->after_termites_action;
}

sub termite_move {
    my ($self, $termite) = @_;
    $termite->{pos} = $self->{box}->wrap( $termite->{pos} +
					  Math::Vector::Real->random_normal($self->{dim},
									    $self->{speed}));
}

sub before_termites_move {}
sub before_termites_action {}
sub after_termites_action {}

sub termite_action {
    my ($self, $termite) = @_;
    if (defined $termite->{wood_ix}) {
        if ($self->termite_leave_wood_p($termite)) {
            $self->termite_leave_wood($termite);
        }
    }
    else {
        my $wood_ix = $self->termite_take_wood_p($termite);
        defined $wood_ix and $self->termite_take_wood($termite, $wood_ix);
    }
}



( run in 2.432 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )