@ -7,6 +7,7 @@
using std : : string ;
using matrix : : Matrix ;
namespace maze {
inline size_t rand ( size_t i , size_t j ) {
if ( i < j ) {
return Random : : uniform ( i , j ) ;
@ -93,74 +94,73 @@ inline std::pair<Point, Point> find_coord(Matrix& maze) {
dbc : : sentinel ( " failed to find coord? " ) ;
}
void maze : : randomize_rooms ( std : : vector < Room > & rooms_out , std : : vector < Point > & maybe_here ) {
dbc : : check ( maybe_here . size ( ) > = 2 , " must have at least two possible points to place rooms " ) ;
void Builder : : randomize_rooms ( ) {
dbc : : check ( $ dead_ends . size ( ) > = 2 , " must have at least two possible points to place rooms " ) ;
while ( rooms_out . size ( ) < 2 ) {
while ( $ rooms . size ( ) < 2 ) {
// use those dead ends to randomly place rooms
for ( auto at : maybe_here ) {
for ( auto at : $ dead_ends ) {
if ( Random : : uniform ( 0 , 1 ) ) {
size_t offset = Random : : uniform ( 0 , 1 ) ;
Room cur { at . x + offset , at . y + offset , 1 , 1 } ;
rooms_out . push_back ( cur ) ;
$ rooms . push_back ( cur ) ;
}
}
}
}
void maze : : init ( Matrix & maze ) {
matrix : : assign ( maze , WALL_VALUE ) ;
void Builder : : init ( ) {
matrix : : assign ( $ walls , WALL_VALUE ) ;
}
void maze : : divide ( Matrix & maze , Point start , Point end ) {
void Builder : : divide ( Point start , Point end ) {
for ( matrix : : line it { start , end } ; it . next ( ) ; ) {
maze [ it . y ] [ it . x ] = 0 ;
maze [ it . y + 1 ] [ it . x ] = 0 ;
$ walls [ it . y ] [ it . x ] = 0 ;
$ walls [ it . y + 1 ] [ it . x ] = 0 ;
}
}
void maze : : hunt_and_kill ( Matrix & maze , std : : vector < Room > & rooms , std : : vector < Point > & dead_ends ) {
for ( auto & room : rooms ) {
for ( matrix : : box it { maze , room . x , room . y , room . width } ; it . next ( ) ; ) {
maze [ it . y ] [ it . x ] = 0 ;
void Builder : : hunt_and_kill ( ) {
for ( auto & room : $ rooms ) {
for ( matrix : : box it { $ walls , room . x , room . y , room . width } ; it . next ( ) ; ) {
$ walls [ it . y ] [ it . x ] = 0 ;
}
}
Point on { 1 , 1 } ;
while ( ! complete ( maze ) ) {
auto n = neighbors ( maze , on ) ;
while ( ! complete ( $ walls ) ) {
auto n = neighbors ( $ walls , on ) ;
if ( n . size ( ) = = 0 ) {
dead_ends . push_back ( on ) ;
auto t = find_coord ( maze ) ;
$ dead_ends . push_back ( on ) ;
auto t = find_coord ( $ walls ) ;
on = t . first ;
maze [ on . y ] [ on . x ] = 0 ;
$ walls [ on . y ] [ on . x ] = 0 ;
size_t row = ( on . y + t . second . y ) / 2 ;
size_t col = ( on . x + t . second . x ) / 2 ;
maze [ row ] [ col ] = 0 ;
$ walls [ row ] [ col ] = 0 ;
} else {
auto nb = n [ rand ( size_t ( 0 ) , n . size ( ) - 1 ) ] ;
maze [ nb . y ] [ nb . x ] = 0 ;
$ walls [ nb . y ] [ nb . x ] = 0 ;
size_t row = ( nb . y + on . y ) / 2 ;
size_t col = ( nb . x + on . x ) / 2 ;
maze [ row ] [ col ] = 0 ;
$ walls [ row ] [ col ] = 0 ;
on = nb ;
}
}
for ( auto at : dead_ends ) {
for ( auto & room : rooms ) {
for ( auto at : $ dead_ends ) {
for ( auto & room : $ rooms ) {
Point room_ul { room . x - room . width - 1 , room . y - room . height - 1 } ;
Point room_lr { room . x + room . width - 1 , room . y + room . height - 1 } ;
if ( at . x > = room_ul . x & & at . y > = room_ul . y & &
at . x < = room_lr . x & & at . y < = room_lr . y )
{
for ( matrix : : compass it { maze , at . x , at . y } ; it . next ( ) ; ) {
if ( maze [ it . y ] [ it . x ] = = 1 ) {
maze [ it . y ] [ it . x ] = 0 ;
for ( matrix : : compass it { $ walls , at . x , at . y } ; it . next ( ) ; ) {
if ( $ walls [ it . y ] [ it . x ] = = 1 ) {
$ walls [ it . y ] [ it . x ] = 0 ;
break ;
}
}
@ -169,54 +169,59 @@ void maze::hunt_and_kill(Matrix& maze, std::vector<Room>& rooms, std::vector<Poi
}
}
void maze : : inner_donut ( Matrix & maze , float outer_rad , float inner_rad ) {
size_t x = matrix : : width ( maze ) / 2 ;
size_t y = matrix : : height ( maze ) / 2 ;
void Builder : : inner_donut ( float outer_rad , float inner_rad ) {
size_t x = matrix : : width ( $ walls ) / 2 ;
size_t y = matrix : : height ( $ walls ) / 2 ;
for ( matrix : : circle it { maze , { x , y } , outer_rad } ;
for ( matrix : : circle it { $ walls , { x , y } , outer_rad } ;
it . next ( ) ; )
{
for ( int x = it . left ; x < it . right ; x + + ) {
maze [ it . y ] [ x ] = 0 ;
$ walls [ it . y ] [ x ] = 0 ;
}
}
for ( matrix : : circle it { maze , { x , y } , inner_rad } ;
for ( matrix : : circle it { $ walls , { x , y } , inner_rad } ;
it . next ( ) ; )
{
for ( int x = it . left ; x < it . right ; x + + ) {
maze [ it . y ] [ x ] = 1 ;
$ walls [ it . y ] [ x ] = 1 ;
}
}
}
void maze : : inner_box ( Matrix & maze , size_t outer_size , size_t inner_size ) {
size_t x = matrix : : width ( maze ) / 2 ;
size_t y = matrix : : height ( maze ) / 2 ;
void Builder : : inner_box ( size_t outer_size , size_t inner_size ) {
size_t x = matrix : : width ( $ walls ) / 2 ;
size_t y = matrix : : height ( $ walls ) / 2 ;
for ( matrix : : box it { maze , x , y , outer_size } ;
for ( matrix : : box it { $ walls , x , y , outer_size } ;
it . next ( ) ; )
{
maze [ it . y ] [ it . x ] = 0 ;
$ walls [ it . y ] [ it . x ] = 0 ;
}
for ( matrix : : box it { maze , x , y , inner_size } ;
for ( matrix : : box it { $ walls , x , y , inner_size } ;
it . next ( ) ; )
{
maze [ it . y ] [ it . x ] = 1 ;
$ walls [ it . y ] [ it . x ] = 1 ;
}
}
void maze : : remove_dead_ends ( Matrix & maze , std : : vector < Point > & dead_ends ) {
for ( auto at : dead_ends ) {
for ( matrix : : compass it { maze , at . x , at . y } ; it . next ( ) ; ) {
if ( maze [ it . y ] [ it . x ] = = 0 ) {
void Builder : : remove_dead_ends ( ) {
dbc : : check ( $ dead_ends . size ( ) > 0 , " you have to run an algo first, no dead_ends to remove " ) ;
for ( auto at : $ dead_ends ) {
for ( matrix : : compass it { $ walls , at . x , at . y } ; it . next ( ) ; ) {
if ( $ walls [ it . y ] [ it . x ] = = 0 ) {
int diff_x = at . x - it . x ;
int diff_y = at . y - it . y ;
maze [ at . y + diff_y ] [ at . x + diff_x ] = 0 ;
$ walls [ at . y + diff_y ] [ at . x + diff_x ] = 0 ;
}
}
}
}
void Builder : : dump ( const std : : string & msg ) {
matrix : : dump ( msg , $ walls ) ;
}
}