Difference between revisions of "Dynamically Sized Maze"

From RogueBasin
Jump to navigation Jump to search
Line 4: Line 4:


<pre>
<pre>
./dynamic.pl 500 1419687417
./dynamic.pl 250 1419688140
############################################################################################## ! ! !##################
############################################################################## ! ! ! !##########
############################################################################################_  _  _!################
############################################################################_  _ _  _!########
############################################################################################_  ! ! ! !################
############ ! !############################################################_ _  _!  _!########
######################################################################################## !_  _! !_  ! !##############
######## !_    _!########################################################## ! _ _!_  _!######
######################################################################################_   ! !_ _ !_ ! ! !##########
######_  _ _! ! !#################################################### ! ! !  _ _!_  _ _! ! !##
#################################################################################### !_ !_ _!   _ _! !   _!########
####_  _!  _!_  _!################################################_  _ _ _ _!##_      _  _!
##################################################################################_  _ __  !_!  _ _! !  _!########
##_  _!_ _  _ _ _!########## ! ! !################################_  !    _!######_!_!_!    _!
##################################################################################_    ! !_  !_ _ _!  _ __!########
##_ _ _ _  !  _  ! !## ! !##_  _  ! ! !############################_   _!  _!##########_  !_!##
#################### ! ! ! ! !## ! ! ! !############################################_! !_ _ _  ! !_ _ ! _ _!########
##_    !  !_!_ _  !_    ! !_    ! !  ! !############################_!_  _!##########_  _!##
##################_      _  !_     _   _!##########################################_       ! !      !_  _!########
##_  !  !_!####_      !  _  !_! !  !_  _!################ ! ! !######_  ! ! ! ! ! ! !  _ _!##
##################_ !_!_!_  !   !_!_ ! ! !##########################################_!_!_! !   !_!_!_! !  _!########
##_  !_!_!########_!_!_!_!_     !_!_!_!########## ! !_  _  _!####_ _ _ _ _  !  !_  _!##
##################_  _!##_    !_!##_  _  _!########################################_   _ !_!_!####_  _ _!########
_  _ _! !##################_!_!_!####_  ! ! ! ! ! !_    !  !_  ! ! ! ! !_ _ _  !_ _!  _!  _!##
############## ! !_  _!####_!_!######_!_  ! ! ! !####################################_    !_! !######_  _!##########
_  !  _  _!##########################_ _ _ _ _  !    !   !_!_             _  !   _!  _!  _!##
############_    !    _!################_ _  !  ! !############ ! !####################_!  _  _!####_  ! ! !########
_ _ _ _!_  _!########################_    _!  _! !_!_!_!_!####_!_!_!_!_!_!_  ! !_ _ _!    _!##
##########_  _!_ _!_!####################_    !_  ! !########_    ! ! !#### ! !#### ! ! !_!    _!####_  _  ! ! ! !##
_    _ _ _ _!########################_  !  _! !_  _!######################_  !_ _ _ _! !_!####
##########_    !    _!######################_!_!_ _  ! !######_  ! !  ! !_    ! !_          !_!########_!_  _ _  _!
_  !_!  _ _   _!#################### ! ! ! !  _!    _!######################_  !  _ _    _!####
############_!_ _!  _!############################_ _  _!####_  ! ! !_ _ _ _!_  !_  !_!_!_!_!##############_!_  _ _!
_  !  _!  !  _!##################_   _ _!_ _!   !_!########################_  !_ _  !_!_!######
##########_  _  !    _!#################### ! ! ! !  _ _!##_  _! !_    !_ _  ! !_  _!#################### ! !_  _!
_  !_ _ _! !  _!##################_  !_ _      !_!##########################_         _!########
############_!_  !_!    _!################_  _ _  !_  _!_    !_ _  !_!  _  ! !_ _ _ _!##################_  _    _!
_  !  !  _!  _!##################_   _  ! !_!_!##############################_!_!_!_!##########
##############_  ! !_!  _!################_ _ _  !_ _ _ _!_  !_!##_  ! !_!  _! !  _  _!######## ! ! ! ! ! !  _!_!_!##
_   !   !_  _!####################_!_    _!##################################################
##############_ _  !_  _!################ ! ! ! !_    ! !_ _  _!_  !  _ _!  ! ! !  _! !#### !  !  _      _!######
##_!_!_!_!##_!##########################_!_!####################################################
################_      _!##############_  _ _ _!_  !          _! !_ _! !  _! ! ! ! !    _! !  _! !  _!_!_!_!########
##################_!_!_!################_      _  ! !_!_!_!_!_!_  _ _    _! ! ! !_  !        _!    _!##############
##########################################_!_!_!_    _!######## !_  _!_!_!_  !_  _!_!_!_!_!_!##_!_!################
##################################################_!_!########_    !  _!####_      _!################################
############################################################ ! ! !_  _!######_!_!_!##################################
##########################################################_  _  _!_!################################################
########################################################## !  _!_!####################################################
########################################################_  _ _!######################################################
########################################################_  _!########################################################
########################################################_  _!########################################################
########################################################_  ! !########################################################
########################################################_ _  _!######################################################
##########################################################_  _!######################################################
################################################## ! !#### !  _!######################################################
################################################_    _! !  _ _!######################################################
################################################ ! !_      _!########################################################
##############################################_  _ _!_!_!_!##########################################################
##############################################_  ! !##################################################################
##############################################_ _  ! !################################################################
################################## ! ! ! ! ! ! !_ _  _!##############################################################
################################_  _ _ _ _ _  _! !  _!##############################################################
################################_    _  !_  !_  !  _! !##############################################################
##################################_!_!_ _ _  !  _!_ _  _!############################################################
#################################### ! ! ! ! !_  !  _  _!############################################################
##################################_  _ _    !  ! ! !_!##############################################################
################################## !_  _!_!_! !_!_  _!##############################################################
############################ ! !_  _  _!##_  _!_  _!##############################################################
##########################_    _!  _!_!####_  _! ! ! !##############################################################
#################### ! ! ! ! !  _!  _!####_  _!  !_  _!############################################################
##################_  _ _  ! !  _!  _!####_      !      _!############################################################
##################_ _ _  ! ! !  _!  _!######_!_!_!_!_!_!##############################################################
################## ! !  _!  !      _!################################################################################
################_  _  _!_!_!_!_!_!##################################################################################
############## ! !  _!_!##############################################################################################
############_  _ _ _!################################################################################################
############ !_ _  ! !################################################################################################
########## !    _!_  _!##############################################################################################
########_  _!_ _ _  _!##############################################################################################
########_  !  _  _!_!################################################################################################
########_  _!  _ _!##################################################################################################
##########_!_ _  _!##################################################################################################
############_  _ _!##################################################################################################
############ !  _!####################################################################################################
##########_  _ _!####################################################################################################
## ! ! ! ! !  _!######################################################################################################
_  _ _ _  !  _!######################################################################################################
_  _  !  _!  _!######################################################################################################
##_!_  ! !  _ _!######################################################################################################
####_  !_ _ _!########################################################################################################
####_ _  _!##########################################################################################################
######_  _!##########################################################################################################
########_!############################################################################################################
</pre>
</pre>



Revision as of 13:49, 27 December 2014

This article will describe a technique to build mazes that can grow in all directions, creating a very organic appearance.

Example

./dynamic.pl 250 1419688140
############################################################################## ! ! ! !##########
############################################################################_   _ _   _!########
############ ! !############################################################_ _   _!  _!########
######## !_     _!########################################################## !  _ _!_   _!######
######_   _ _! ! !#################################################### ! ! !  _ _!_   _ _! ! !##
####_   _!  _!_   _!################################################_   _ _ _ _!##_       _   _!
##_   _!_ _   _ _ _!########## ! ! !################################_  !    _!######_!_!_!    _!
##_ _ _ _  !  _  ! !## ! !##_   _  ! ! !############################_   _!  _!##########_  !_!##
##_    !   !_!_ _  !_    ! !_    ! !   ! !############################_!_   _!##########_   _!##
##_  !   !_!####_      !  _  !_! !   !_   _!################ ! ! !######_  ! ! ! ! ! ! !  _ _!##
##_  !_!_!########_!_!_!_!_      !_!_!_   _!########## ! !_   _   _!####_ _ _ _ _  !   !_   _!##
_   _ _! !##################_!_!_!####_  ! ! ! ! ! !_    !   !_  ! ! ! ! !_ _ _  !_ _!  _!  _!##
_  !  _   _!##########################_ _ _ _ _  !     !   !_!_             _  !    _!  _!  _!##
_ _ _ _!_   _!########################_     _!  _! !_!_!_!_!####_!_!_!_!_!_!_  ! !_ _ _!    _!##
_     _ _ _ _!########################_  !  _! !_   _!######################_  !_ _ _ _! !_!####
_  !_!  _ _   _!#################### ! ! ! !  _!    _!######################_  !  _ _     _!####
_  !  _!   !  _!##################_   _ _!_ _!   !_!########################_  !_ _  !_!_!######
_  !_ _ _! !  _!##################_  !_ _      !_!##########################_         _!########
_  !   !  _!  _!##################_   _  ! !_!_!##############################_!_!_!_!##########
_    !   !_   _!####################_!_     _!##################################################
##_!_!_!_!##_!##########################_!_!####################################################

Source code

#!/usr/bin/env perl

use strict;
use warnings;

no warnings 'uninitialized';
no warnings 'recursion';

use List::Util qw/min max shuffle/;

# Command-line options

my $CELLS = $ARGV[0] || 250;
my $SEED  = $ARGV[1] || time();

srand($SEED);

# Constants

my %DIRECTIONS = (
    N => { dy => -1, opposite => 'S' },
    S => { dy => 1,  opposite => 'N' },
    E => { dx => 1,  opposite => 'W' },
    W => { dx => -1, opposite => 'E' },
);

# Variables

my $map = {};
my ( $min_x, $min_y, $max_x, $max_y ) = ( 0, 0, 0, 0 );
my $count = 0;

# Code

carve( 0, 0, 'E' );
print output();

print "$0 $CELLS $SEED # => ( $min_x, $min_y, $max_x, $max_y )\n";

sub carve {
    my ( $x0, $y0, $direction ) = @_;

    my $x1 = $x0 + $DIRECTIONS{$direction}{dx};
    my $y1 = $y0 + $DIRECTIONS{$direction}{dy};

    return if defined $map->{$y1}{$x1};    # already visited

    $min_x = min( $min_x, $x1 );
    $max_x = max( $max_x, $x1 );

    $min_y = min( $min_y, $y1 );
    $max_y = max( $max_y, $y1 );

    $map->{$y0}{$x0}{$direction} = 1;
    $map->{$y1}{$x1}{ $DIRECTIONS{$direction}{opposite} } = 1;

    return if $count++ > $CELLS;

    for my $new_direction ( shuffle keys %DIRECTIONS ) {
        carve( $x1, $y1, $new_direction );
    }
}

sub output {
    my $output = '';
    for my $y ( $min_y .. $max_y ) {
        for my $x ( $min_x .. $max_x ) {
            if ( ref $map->{$y}{$x} ) {
                $output .= $map->{$y}{$x}{S} ? ' ' : '_';
                $output .= $map->{$y}{$x}{E} ? ' ' : '!';
            }
            else {
                $output .= '##';
            }
        }
        $output .= "\n";
    }
    return $output;
}

Description

This is a simple recursive backtracker that starts at position {0,0} and can grow into all directions.

  1. Start carving from (x0,y0) into a specific direction.
  2. Calculate the new coordinates (x1,y1).
  3. Return if the new position was already visited.
  4. Repeat the process from the new position, trying all possible directions.

In most mazes, the process terminates when all coordinates were visited; but in our case there is no limit for growth, so we must terminate after an arbitrary limit.

Another important point is that, since the maze can become very sparse, we use a hash table instead of an array to store the cells.

Usage

$ ./dynamic.pl [length] [random seed]

More examples

$ ./dynamic.pl 250 1419687187
################################## ! !########################################
################################_    ! ! ! !##################################
################################_  !_ _ _   _!################################
################################_  !  _!  _ _!################################
################################_  !  _   _!##################################
##############################_   _!  _!_!#################### ! ! !##########
##############################_  ! ! ! !####################_       _! !######
##############################_  !_ _  ! !####################_!_!      _!####
##############################_      !_   _!################_    !_!_!  _! !##
############################## !_!_! !  _ _!###### ! ! !##_   _!_  !_ _ _   _!
############################_   _ _ _!  _!######_   _   _!_    !_  !_   _   _!
##########################_   _!  _ _! ! ! !## !_  !  _ _!##_!_  ! !_ _  !_!##
##########################_  !  _  !  _ _  !_   _ _!  _! !_   _ _! !_     _!##
##########################_  !_ _!_ _!   !_    !_   _!_   _ _!  _ _!   !_!####
########################_   _!  _      !   !_!_!_  !    _!  _ _!_   _!_!######
########################_       _!_!_!_!_!    _!_    !_!_ _  !   !_ _   _!####
##########################_!_!_!######## !_!  _!##_!_!####_    !        _!####
################################ ! ! !_       _!############_!_!_!_!_!_!######
##############################_   _  !   !_!_!################################
################## ! !########_  ! ! ! !_!####################################
################_    ! ! !##_   _!_ _ _ _! ! !################################
################_  !  _   _!_   _ _   _ _ _   _!##############################
################_  !_! !  _!##_!   !_ _ _ _!  _!##############################
################_  !_   _! ! !_  !      _  !_   _!############################
############ ! !_ _  !    _  !_  !_!_!_!_       _!############################
##########_    !_    !_!_!_       _!######_!_!_!##############################
##########_  !     !_!######_!_!_!############################################
#### ! !##_  !_!_!_!##########################################################
##_    !_     _!##############################################################
_   _!_    !_!################################################################
_ _ _  !_!_!##################################################################
_    !  _!####################################################################
_  !_   _!####################################################################
_ _  !_!######################################################################
_     _!######################################################################
##_!_!########################################################################
$ ./dynamic.pl 250 1419687341
######## ! !############################################################
#### !_     _!##########################################################
##_   _ _! ! ! ! !######################################################
_   _!_ _     _  ! ! ! ! !##############################################
_        !_!_!_     _ _  ! ! ! !########################################
##_!_!_!  _! !##_!_!_   _!  _   _!######################################
######_       _!####_  !  _!  _! ! !####################################
########_!_!    _!##_   _!  _!  _   _!#################### ! !##########
############_!    _!##_!_  !_  !  _ _!########## ! !####_    ! ! ! ! !##
############ !_!  _!####_   _ _!  _!##########_    ! ! !_  !          _!
######## !_       _!######_!_   _ _!#### ! ! !_  !  _ _  ! !_!_!_!_!_!##
######_      !_!_!########## !_   _!##_   _  !   !_!_   _!  _!##########
####_    !_!_!######## ! ! !   !  _!##_    !   !_!##_       _!##########
####_  !_! !########_   _ _ _!_ _ _!####_! !_!_!######_!_!_!############
####_       _!######_   _  ! ! ! ! ! ! !_   _!##########################
######_!_!  _!########_!_           _  !    _!##########################
########_   _!############_!_!_!_!_!_    !_!############################
######_   _ _!#### ! ! ! ! !##########_!_!##############################
######_ _   _!##_   _       _!##########################################
####_   _ _ _! ! !  _!_!_!  _!##########################################
####_ _ _  !  _   _ _! !_   _!##########################################
####_     _!  _!_!  _       _!##########################################
####_  !_!  _ _!_    !_!_!_!############################################
####_       _!####_!  _!################################################
######_!_!_!####_   _ _!################################################
################_ _   _!################################################
###### ! ! ! !##_     _!################################################
## !_     _  !_   _!_!##################################################
_   _  !_!_  !_ _ _   _!################################################
_    !_! !_  !  _  !  _!################################################
##_!    _  ! ! ! ! !  _! !##############################################
####_!_!  _!_ _!  _!  _   _!############################################
######_ _!   !  _!_ _!    _!############################################
####_   _ _!_ _!_    ! !_!##############################################
####_   _  !   !_  !    _!##############################################
######_!_  ! ! !   !_!_!################################################
########_  ! !   !_!####################################################
########_    !_!_!######################################################
##########_!_!##########################################################
$ ./dynamic.pl 250 1419687903
############## ! !######################################################################################################
########## ! !    _!####################################################################################################
########_   _ _!  _!####################################################################################################
########_ _ _  !_   _! !######################################################## ! !####################################
########_   _ _ _! !    _!############################################## ! ! ! !    _!##################################
########_  ! !  _ _! !  _! ! ! !###### ! ! ! !######## ! ! ! !######## !   !  _  !    _! ! ! ! !########################
########_ _  !_  !  _! !   !    _! ! !  _     _! !##_   _ _   _!####_   _!    _!_!_!            _!######################
######## ! ! !  _!  _! ! !_  !     !  _ _!_!      _! !  _!  _ _!####_   _!_!_!######_!_!_!_!_!    _!########## ! ! ! !##
###### !  _ _!_ _ _ _!    _!_!_!_!    _!####_!_!        _! !    _!##_  ! ! !##################_!    _! !####_   _ _   _!
####_   _! ! ! ! ! !##_!_!########_!_!##########_!_!_!_!_    !    _! ! !    _!##################_!      _! !_   _!    _!
####_ _ _  !  _ _   _!####################################_!_!_!     !_ _!  _!####################_!_!      _! !  _!_!##
######_   _!_  ! !  _!##########################################_!_!        _!########################_!_! !  _!_   _!##
###### !_ _ _ _!  _ _!##############################################_!_!_!_!############################_    !      _!##
## ! !    _!   !_   _!################################################################################## !_!_! !_!_!####
_      !     ! !  _ _!################################################################################_    !    _!######
##_!_!_!_!_!_!    _!################################################################################_   _! ! !_!########
##############_!_!##################################################################################_  !_     _!########
####################################################################################################_    !_!_! ! !######
######################################################################################################_! !   !    _!####
######################################################################################################_    ! ! !  _!####
################################################################################################ ! ! !##_!_!_  !_   _!##
##############################################################################################_   _  !_   _  ! ! !  _!##
################################################################################################_!_      !_  ! ! !  _!##
####################################################################################################_!_!_! ! ! ! !  _!##
########################################################################################################_   _! ! !  _!##
########################################################################################################_ _  !_  !  _!##
##########################################################################################################_ _  !_!  _!##
############################################################################################################_       _!##
##############################################################################################################_!_!_!####