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 )