12. Last Thoughts

Back Home Up

Your exact design is your business, of course.  But it's nice to think ahead a little before settling down to write some code.

Some considerations

displaying the maze

I haven't covered the methods for drawing the maze, here. And I'm not going to. If you want to see how that's done and cannot work it out for yourself, feel free to download the sample code and see how I did it.

output device

We might want to output the maze to an HP Laserjet printer, the PC screen in text mode, the PC screen in graphics mode, a BMP file, etc. In the worked examples, I generate two different outputs: one in the text-mode format because it's a quick and easy way to verify that the rest of the program is working, and one for the HP Laserjet to show how to deal with slightly more complex requirements.

output statements

To display the maze, we need to know if should be displayed on the screen, printed, or written to a file. In QB, except for displaying the maze in graphics mode on the screen, this is easily handled by just using the file I/O style of PRINT. The user can specify the filename of SCRN: for the screen, LPT1: for the first printer, or a regular file name, too. That much flexibility should be plenty.

displaying the maze on a laserjet

HP Laserjets are really pretty nice to use, but they do add a slight complexity to our program if we really want to make the application nice to use.

You've got two general approaches to use here. The first is to simply stretch a maze to always fit the entire page of paper. Doing this means exactly one maze per page. They will look very nice and professional, but for relatively simply mazes your pathways in the maze will be oversized. The second is to allow several mazes to be generated and placed onto the page before ejecting it. This complicates the user interface somewhat. But it has its advantages.

the path list

For really large mazes, the path list can get pretty darned big before it gets small again. This is because the maze algorithm just spins away for a while, blasting through walls and adding these rooms to the path list. It's not uncommon for the number of entries in that list to get close to the total number of rooms in the maze, itself. And for a really big maze, this means a really big list.

For the versions of this program that actually support very big mazes (up to say a half-million rooms), this path list is almost impossibly big. We just can't get BASIC to give us that much room in a single array. So we need to figure out another strategy.

The idea I've tried is to use yet another one of those bit-packed arrays, just like the wall and visitation status arrays, to hold a bit which indicates whether or not a particular room is worth checking. In this case, I randomly select a place to start searching, and then search this array 16 rooms at a time until I find a block of 16 that contains at least one room to try. Then I try it. If it fails, it gets removed from this array and I pick another starting point at random. The time it takes isn't predictable, but it works and saves a lot of space.

dividing and conquering

It's not uncommon that you find you can divide up a larger problem into smaller ones to solve, solve those and then to aggregate those solutions to solve the larger one. Generating a large maze can be solved this way, as well. Can you think of how?

We already know that there is one guaranteed path between any two exterior openings in any maze we complete. What if we took a large maze grid and simply solved only one corner of it? We could then pick any two exits from that corner area, internal to the larger maze area, and we'd know there was only one path to connect them.

So, what we could do is first imagine that the larger maze is sub-divided into a coarser grid of much fewer rooms, solve that maze first, then treat each room of that coarser grid as a sub-section of the larger maze to solve. Solve each of those individually and follow the guiding influence of the coarser maze to tell us how to connect up the sections.

A disadvantage of this technique is that the resulting maze will have obvious, hard regions in it that a player will recognize and take advantage of, in solving it. But how might one fix this problem? Think about it.

does it have to be a rectangle?

What about different basic shapes?

Consider making the original grid in the form of concentric circles, instead of rectilinear, and using radii to divide it all up into rooms. Perhaps, you'd need to leave an inner chamber to keep the rooms from getting too small as you neared the middle. But wouldn't the same logic at generating a maze apply here?

What kinds of other shapes do you think might work, too?

some further considerations

Do we want to make this a kind of batch program, accepting specifications from a file for example? Do we want to require user interaction, one maze at a time?

In QB, we have access to the COMMAND$ value. This allows us to examine what was typed on the command line and change the way we do things, depending on what we see there. Perhaps we could look at COMMAND$ and see if a filename was given. If so, we'd read the file and perform the operations that were saved there during a different session with the program. If not, we'd let the user operate the program from the keyboard and screen and create a new session log of what was done.

 

Last updated: Wednesday, July 06, 2005 21:05