Maze Maker

I remember when I was in school, I used to play the game where you help the mouse go through the maze and reach the target as quickly as possible. Even

when I finished my college, I would still wonder how one can create a maze. Those who create maze must be super ingenious.

It was only recently I decided to decode the mystery of maze creation. I asked my friend Google and guess what, I was presented with plenty of solutions in various languages. Some very difficult to follow and some not so difficult. Having got my head around the algorithm, I decided to do it in my first language i.e. Perl. It didn’t took me long to convert the algorithm into Perl script.

As you all know, I am still a new player in Raku. Thankfully I have plenty of support when it comes to Raku queries. For the first time, I decided to be part of Raku Advent Calendar. Thanks to JJ Merelo, I was given a slot. At that point, I didn’t have a clue what I am going to do. But I knew I have plenty of ideas that can be converted into Raku.

As you guessed it correctly, I picked my favourite maze maker script for the Raku Advent Calendar. With the help of many people on Twitter, I got my first draft ready in Raku. But it wasn’t creating the tunnel as expected. I went to my friend, Scimon Proctor, for guidance. He helped me with the Raku magic and all working smoothly now.

It was time to do some housekeeping before I hand it over to JJ Merelo. Having spent around 30 minutes, I got my final draft ready as below:

use v6; my %opposite-of = ( 'north' => 'south', 'south' => 'north', 'west' => 'east', 'east' => 'west' ); my @directions = %opposite-of.keys; sub MAIN(Int :$height = 10, Int :$width = 10) { my $maze; make-maze( 0, 0, $maze, $height, $width ); say render-maze( $maze, $height, $width ); } # # # METHODS sub make-maze( $x, $y, $maze is rw, $height, $width ) { for ( @directions.pick(@directions) ) -> $direction { my ( $new_x, $new_y ) = ( $x, $y ); if ( 'east' eq $direction ) { $new_x += 1; } elsif ( 'west' eq $direction ) { $new_x -= 1; } elsif ( 'south' eq $direction ) { $new_y += 1; } else { $new_y -= 1; } if not-visited( $new_x, $new_y, $maze, $height, $width ) { $maze[$y][$x]{$direction} = 1; $maze[$new_y][$new_x]{ %opposite-of{$direction} } = 1; make-maze( $new_x, $new_y, $maze, $height, $width ); } } } sub not-visited( $x, $y, $maze, $height, $width ) { # check the boundary return if $x < 0 or $y < 0; return if $x > $width - 1 or $y > $height - 1; # return false if already visited return if $maze[$y][$x]; # return true return 1; } sub render-maze($maze, $height, $width) { my $as_string = " " ~ ( "_ " x $width ); $as_string ~= "

"; for ( 0 .. $height - 1 ) -> $y { $as_string ~= "|"; for ( 0 .. $width - 1 ) -> $x { my $cell = $maze[$y][$x]; $as_string ~= $cell<south> ?? " " !! "_"; $as_string ~= $cell<east> ?? " " !! "|"; } $as_string ~= "

"; } return $as_string; }

What next?

I am thinking of converting this into a Raku Library, something like Games::Maze. I am working on it, hopefully I should have it ready before Christmas.

If you think it can be improved in any way then please do share with me. I would love to hear from you and learn from your experience. Till then have fun with it from a Perl Fan, who equally loves Raku.