Game-DijkstraMap
view release on metacpan or search on metacpan
lib/Game/DijkstraMap.pm view on Meta::CPAN
my $badcost = $self->bad_cost;
my $maxcol = $dimap->[0]->$#*;
for my $r ( 0 .. $dimap->$#* ) {
for my $c ( 0 .. $maxcol ) {
$dimap->[$r][$c] = $maxcost
if $dimap->[$r][$c] != $mincost and $dimap->[$r][$c] != $badcost;
}
}
$self->_set_iters(
$self->normfn->( $dimap, $mincost, $maxcost, $self->bad_cost ) );
$self->dimap($dimap);
return $self;
}
sub str2map {
my ( $self_or_class, $str, $lf ) = @_;
croak "no string given" if !defined $str;
$lf //= $/;
my @map;
for my $line ( split $lf, $str ) {
push @map, [ split //, $line ];
}
return \@map;
}
sub to_tsv {
my ( $self, $ref ) = @_;
if ( !defined $ref ) {
$ref = $self->dimap;
croak "cannot use an unset map" if !defined $ref;
}
my $s = '';
my $cols = $ref->[0]->$#*;
for my $r ( 0 .. $ref->$#* ) {
my $d = "\t";
for my $c ( 0 .. $cols ) {
$s .= $ref->[$r][$c] . $d;
$d = '' if $c == $cols - 1;
}
$s .= $/;
}
return $s;
}
sub unconnected {
my ($self) = @_;
my $dimap = $self->dimap;
croak "dimap not set" if !defined $dimap;
my @points;
my $maxcost = $self->max_cost;
my $maxcol = $dimap->[0]->$#*;
for my $r ( 0 .. $dimap->$#* ) {
for my $c ( 0 .. $maxcol ) {
push @points, [ $r, $c ] if $dimap->[$r][$c] == $maxcost;
}
}
return \@points;
}
sub update {
my $self = shift;
my $dimap = $self->dimap;
croak "dimap not set" if !defined $dimap;
my $maxrow = $dimap->$#*;
my $maxcol = $dimap->[0]->$#*;
for my $ref (@_) {
my ( $r, $c ) = ( $ref->[0], $ref->[1] );
croak "row $r out of bounds" if $r > $maxrow or $r < 0;
croak "col $c out of bounds" if $c > $maxcol or $c < 0;
croak "value must be a number" unless looks_like_number $ref->[2];
$dimap->[$r][$c] = int $ref->[2];
}
$self->dimap($dimap);
return $self;
}
sub values {
my $self = shift;
my $dimap = $self->dimap;
croak "dimap not set" if !defined $dimap;
my @values;
my $maxrow = $dimap->$#*;
my $maxcol = $dimap->[0]->$#*;
for my $point (@_) {
my ( $r, $c ) = ( $point->[0], $point->[1] );
croak "row $r out of bounds" if $r > $maxrow or $r < 0;
croak "col $c out of bounds" if $c > $maxcol or $c < 0;
push @values, $dimap->[$r][$c];
}
return \@values;
}
1;
__END__
=head1 NAME
Game::DijkstraMap - a numeric grid of weights plus some related functions
=head1 SYNOPSIS
use Game::DijkstraMap;
my $dm = Game::DijkstraMap->new;
# x is where the player is (the goal) and the rest are
# considered as walls or floor tiles (see the costfn)
my $level = Game::DijkstraMap->str2map(<<'EOM');
#########
#.h.....#
#.#####'#
#.#.###x#
#########
EOM
# setup the dijkstra map
$dm->map($level);
# or, the above can be condensed down to
use Game::DijkstraMap;
my $dm = Game::DijkstraMap->new( str2map => <<'EOM' );
( run in 0.758 second using v1.01-cache-2.11-cpan-39bf76dae61 )