File Coverage

blib/lib/Games/RolePlay/MapGen/Generator/SparseAndLoops.pm
Criterion Covered Total %
statement 64 64 100.0
branch 21 24 87.5
condition 5 6 83.3
subroutine 9 9 100.0
pod 0 3 0.0
total 99 106 93.4


line stmt bran cond sub pod time code
1             # vi:tw=0 syntax=perl:
2              
3             package Games::RolePlay::MapGen::Generator::SparseAndLoops;
4              
5 7     7   5351 use common::sense;
  7         14  
  7         47  
6 7     7   317 use Carp;
  7         12  
  7         551  
7 7     7   35 use parent 'Games::RolePlay::MapGen::Generator::Perfect';
  7         18  
  7         43  
8 7     7   432 use Games::RolePlay::MapGen::Tools qw( choice roll );
  7         16  
  7         9155  
9              
10             1;
11              
12 34925 100   34925   42758 sub _dirsum { my $c = 0; for (qw(n s e w)) { $c ++ if $_[0]->{od}{$_} } $c };
  34925         60775  
  139700         493700  
  34925         134060  
13 77     77   166 sub _endian_tiles { return grep { &_dirsum($_) == 1 } map(@$_, @{ $_[0] }) }
  34925         63380  
  77         428  
14              
15             # remove_deadends {{{
16             sub remove_deadends {
17 7     7 0 22 my $this = shift;
18 7         19 my $opts = shift;
19 7         22 my $map = shift;
20              
21 7         115 my @dirs = (qw(n s e w));
22              
23 7         33 for my $tile ( &_endian_tiles( $map ) ) {
24 56 100       198 if( &roll(1, 100) <= $opts->{remove_deadend_percent} ) {
25              
26 808         2529 DO_THIS_TILE_ALSO:
27 202         383 my @togo = grep { !$tile->{od}{$_} } @dirs;
28 202         595 my $dir = &choice(@togo);
29              
30             TRY_THIS_DIR_INSTEAD:
31 218 100       3764 if( my $nex = $tile->{nb}{$dir} ) {
32              
33 202         671 $tile->{od}{$dir} = $nex->{od}{$Games::RolePlay::MapGen::opp{$dir}} = 1;
34              
35 202 100       1230 if( $nex->{type} ) {
36             # Excellent, we're done with this tile.
37              
38             } else {
39             # Alrightsir, mark nex as a corridor and we'll have to keep going.
40              
41 169         226 $tile = $nex;
42 169         542 $tile->{type} = 'corridor';
43              
44 169 100       426 if( &roll(1, 100) > $opts->{same_way_percent} ) {
45 16   66     26 @togo = grep { !$tile->{od}{$_} and !$tile->{_bud}{$dir} } @dirs;
  64         506  
46 16         59 $dir = &choice(@togo);
47             }
48              
49 169         2673 goto DO_THIS_TILE_ALSO;
50             }
51              
52             } else {
53 16         63 $tile->{_bud}{$dir} = 1;
54 16   100     285 @togo = grep { !$tile->{od}{$_} and !$tile->{_bud}{$_} } @dirs;
  64         424  
55 16         60 $dir = &choice(@togo);
56              
57 16 50       54 die "FATAL: couldn't figure out how to un-dead this end..." unless $dir;
58              
59 16         165 goto TRY_THIS_DIR_INSTEAD;
60             }
61             }
62             }
63             }
64             # }}}
65             # sparsify {{{
66             sub sparsify {
67 7     7 0 22 my $this = shift;
68 7         18 my $opts = shift;
69 7         16 my $map = shift;
70              
71 7         27 my $sparseness = $opts->{sparseness};
72              
73             SPARSIFY:
74 70         252 for my $tile ( &_endian_tiles( $map ) ) {
75 2322         5817 my($dir)= grep { $tile->{od}{$_} } (qw(n s e w)); # grep returns the resulting list size unless you evaluate in list context
  9288         20018  
76 2322 100       28178 my $nex = ($tile->{od}{n} ? $map->[$tile->{y}-1][$tile->{x}] :
    100          
    100          
77             $tile->{od}{s} ? $map->[$tile->{y}+1][$tile->{x}] :
78             $tile->{od}{e} ? $map->[$tile->{y}][$tile->{x}+1] :
79             $map->[$tile->{y}][$tile->{x}-1] );
80              
81 2322 50       15712 $opts->{t_cb}->() if exists $opts->{t_cb};
82              
83 2322         12009 $tile->{od} = {n=>0, s=>0, e=>0, w=>0};
84 2322         6739 delete $tile->{type};
85              
86 2322 50       5789 die "incomplete open direction found during sparseness calculation" unless defined $nex;
87              
88 2322         9966 $nex->{od}{$Games::RolePlay::MapGen::opp{$dir}} = 0;
89             }
90              
91 70 100       3639 goto SPARSIFY if --$sparseness > 0;
92             }
93             # }}}
94             # genmap {{{
95             sub genmap {
96 7     7 0 15 my $this = shift;
97 7         40 my $opts = $this->gen_opts;
98 7         80 my ($map, $groups) = $this->SUPER::genmap(@_);
99              
100 7         154 $this->sparsify( $opts, $map );
101 7         156 $this->remove_deadends( $opts, $map );
102              
103 7         2720 return ($map, $groups);
104             }
105             # }}}
106              
107             __END__