Miscellaneous Programming
QB: Maze Generation Tool

If you've never tried it before, generating a maze can seem easy enough in concept yet quite hard to grapple with, once you try to work out the details of it. It turns out that it really isn't all the difficult, once you've done it and made it work.

I'm not going to write this for novice programmers, though. I think you should be fairly comfortable with programming in QB, before tackling this project. But you don't have to be some expert, either. It's just a good idea that you understand most of the syntax and semantics of QB, because I'm going to focus on the maze application here and not on the language we're using. I'd recommend that you consider yourself a moderate programmer or, at least, a self-learner.

Building a Maze

How do you build a maze? Well, if you'll excuse the text-only sample, let's start out by taking a look at one:

+  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |     |           |           |                 |        |
+  +  +  +  +--+--+  +  +  +--+  +  +  +--+--+--+  +  +--+  +
|     |  |  |     |     |  |     |  |     |        |     |  |
+--+  +  +--+  +  +--+--+  +  +--+--+--+  +  +--+--+--+--+  +
|     |        |           |  |           |     |  |        |
+  +  +--+--+--+--+--+--+--+  +--+--+--+--+--+  +  +  +--+--+
|  |           |           |        |              |  |     |
+  +--+--+--+  +--+--+--+  +--+--+  +  +--+  +--+  +  +--+  +
|           |           |           |     |  |  |     |     |
+--+--+  +  +--+--+--+  +--+--+--+--+--+  +  +  +--+--+  +--+
|        |  |     |        |  |           |                 |
+  +--+--+  +  +  +  +--+--+  +  +--+--+--+  +--+--+--+--+  +
|     |     |  |     |     |  |     |     |        |        |
+--+--+  +--+  +--+--+--+  +  +--+  +  +  +--+--+  +  +--+  +
|        |     |           |           |  |        |     |  |
+  +--+--+  +--+  +--+--+  +--+--+--+--+  +--+--+--+--+--+  +
|  |     |     |        |     |        |     |     |        |
+  +  +  +--+  +--+--+  +  +--+  +--+  +--+  +  +--+  +--+  +
|     |     |           |        |           |        |     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +
In this case above, one of the things you might notice is that the maze actually looks like one. That's a good thing.

Next, you might notice that it's really kind of like a grid. If you count them, you'll see that this maze has 20 columns and 10 rows.

What about the solutions to the maze? Is there one? More than one? Of course, I'm sure we hope there is exactly one and no more. In this case, I think you'll agree that the maze meets this essential requirement.

where to start

How do we draw something like this with a computer? How do we guarantee only one solution, with one entrance and one exit to the maze?

Do we just grab a blank sheet of paper and start drawing lines? Should we start with the basic enclosed rectangle and then erase an entrance hole and an exit hole and go on from there? What method do we use?

Well, there are several ways and no one right one. But the one I like better starts out with a grid, like this one:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
There's the original maze shown as it was when it started out. All of the walls are in place and there is no path anywhere. Turning this into a maze is like kicking down walls, with a few special rules.

getting started

We start out by dropping into any grid location, at random if we want to. It doesn't really matter. Then we simply break down any one of the walls, except that we don't break down walls that lead to rooms we've already been to. When we start out, this means any wall can be broken.

Once we break down one of the walls, we simply walk into the newly opened room. Then choose any one of the remaining walls to break down, once again being aware not to break down a wall that leads to a room we've been in.

Here's an example of how the original maze may have started:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |x--> |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Here, we started at the x and broke down a wall. (There's no reason why I picked that particular wall, except that I know from the original maze that that wall was indeed broken down.)

getting there is part of the fun

This process continues until we cannot break down any more walls, because we are surrounded by rooms we've already visited and we are now trapped. Here's how it might have looked in the original maze, at the moment we first trapped ourselves:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+  +
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |    y|  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |        |  |x    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+  +  +--+  +
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |     |     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+--+--+  +--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |              |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
We started at x and ended up at y. At this point, we are surrounded by rooms we've already been to. So we are stuck.

a new lease on life

So now what? Well, we just pick any place along any path we've already been to and start from there, once again. Just pick anywhere we've been to, already. Here's the results of this strategy, after we get stuck again:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+  +
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |     |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +
|     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |        |
+  +  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+  +--+--+
|  |           |  |  |  |  |  |  |  |   <--a       |  |     |
+  +--+--+--+  +--+--+--+--+--+--+--+  +--+  +--+  +  +--+  +
|           |           |  |  |  |  |     |  |  |     |     |
+--+--+--+  +--+--+--+  +--+--+--+--+--+  +  +--+--+--+  +--+
|  |  |  |  |     |     |  |  |           |              |  |
+--+--+--+  +  +  +  +--+--+--+  +--+--+--+--+--+--+--+--+--+
|  |  |     |  |     |  |  |  |     |     |  |  |  |  |  |  |
+--+--+  +--+  +--+--+--+--+--+--+  +  +  +--+--+--+--+--+--+
|        |     |           |  |  |     |  |  |  |  |  |  |  |
+  +--+--+  +--+  +--+--+  +--+--+--+--+  +--+--+--+--+--+--+
|  |     |     |        |  |  |        |     |  |  |  |  |  |
+  +  +  +--+  +--+--+  +  +--+  +--+  +--+  +--+--+--+--+--+
|     | -->b|           |        |  |        |  |  |  |  |  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
We started at a, which is one of the rooms we'd already been to, and then continued on until arriving at b, where we were stuck again. As you can see, this time we got quite a ways before getting stuck.

Heck, it's already starting to look a bit like a maze!

finishing the job

Well, to make a long story short, this process continues until we've been in each and every room in the grid. Once we've achieved that, the maze is nearly done.

The only thing remaining to do is to open an entrance and an exit. It turns out, that's easy. Just pick any two exterior walls and break them down. It always works and you will always have exactly one path between them, if yoy've followed these rules carefully.

How's that for simple to do? It doesn't get much simpler.

guaranteed right

But how do you know there is one and only one solution? Well, you'll notice that we never break through a wall, into a room we've already been to. This keeps us from creating any loops or cycles that provide more than one way to get from place to place.

Also, all paths are connected because we always restart a new branch path from somewhere along the path we've already taken. So branches are never unconnected. And it is always possible to get from anywhere on one branch to anywhere on another branch.

Just imagine laying all those branches flat out on a sheet of paper, instead of all coiled up inside that grid. I think you'll see what I mean. Now, it's easy to see why picking any point along any one branch and picking any point along another branch (or the same one, but that's not as interesting) means that there can only be one way to go between them.

Programming a Maze

the basics

Take a close look at the original grid. If we set up four walls for each room, we'd have duplicate walls everywhere. That's because the north wall of the south room and the south wall of the north room would both be for the same intervening wall between them. That duplication is a pain.

The solution is to set up each room with, say, a west wall and a south wall (or a left wall and a bottom wall, if you prefer.) That's it. That way, the south wall of the north room is the only wall sitting between the north room and the room just south of it.

The only problem with that scheme is that we don't have walls for the north-most and the east-most walls of the maze, because there aren't any rooms out there to provide these walls. Of course, we could always make the grid one size larger in each direction to put rooms out there. We'll be returning to this last question in a bit. It turns out that there are some considerations, one way or another.

Either way we do it, we're going to need an array of west walls, an array of south walls, and if you haven't noticed, an array of markers indicating whether or not we've been to the room. (Kind of like leaving bread crumbs along out path, eh?)

We only need one bit per wall or marker, since we only need to know YES/NO information about each. It would be somewhat easier, if we just used an entire INTEGER for the purpose. But after some calculations, you'll see why we should go to the trouble.

how much is enough?

Let's take a crack at just how many rooms in our grid is enough.

Let's assume we are going to draw mazes on an HP LaserJet printer. These printers provide a printable area of about 8" by 10.5", leaving a quarter inch or so at all the margins of the 8.5" by 11" page. With 300 dots per inch of resolution, we should be able to make fairly nice, fine lines for our mazes.

But how detailed would we like to go? Would one millimeter spacing be small enough? Would it be too small?

Let's start out with the millimeter spacing specification and see where that takes us. Once we see where we land, we can make a somewhat better judgement about where next to go.

To compute the worst case number of rooms we have to handle, we'll assume that a single maze will cover the entire printed page and that it will use one millimeter wide paths, roughly. Given that, our calculation simply involves dividing the total printable area on the printer page by the area of one room. That will tell us the number of rooms we must handle.

(8" * 10.5") / (1 mm * 1 mm) = (8 * 25.4) * (10.5 * 25.4) = 54193.44

So we'd need to handle over 54,000 rooms. That's a lot, if we remember that we need to provide information on west and south walls and whether or not they've been visited.

Since BASIC doesn't support making INTEGER arrays anywhere near that size (and we'd need at least three arrays), we can either reduce our requirements to the about 32500 or so that we can count on and see where that leaves us or else we can think about what it means to just use a single bit, rather than an entire INTEGER for each array.

Frankly, I'm going to go for the gusto on this one. But let's look at reducing the requirements, first.

Assume we can only create an INTEGER array of say 32,500 elements. We'll plan on using an entire INTEGER for each of thing we need to keep track of, as well, such as the west and south walls and our visitation status -- for a total of three such arrays.

32500 = (8" * 10.5") / (X mm * X mm)

thus, X = SQRT(54193.44 / 32500) = (about) 1.29 mm

Well, that's not too bad at all! We can generate mazes with about 19 or so rooms per inch, which is fairly good resolution. So if this is fine for you, we could easily proceed along those lines and feel quite happy with the results. Those mazes would be very complex, being better than a grid of 150 by 200 per printed page.

But let's see where we could go, with a little more effort. If we can pack 16 bits per INTEGER value, that would provide 16 times as many rooms wouldn't it?

16 * 32500 = (8" * 10.5") / (X mm * X mm)

or, X = SQRT(54193.44 / (32500 * 16)) = (about) 1.29 mm / 4 = .323 mm

Now, we are talking about mazes that are better than 600 by 800, in size. That's serious stuff!

Is a third of a millimeter crazy? Perhaps. But that's (.323 / 25.4) * 300 = 3.8 dots wide: let's call it 4 dots. We can plot one dot for a wall and leave 3 more for an opening. A human should be able to see that -- we hope!

Maybe pressing the limits isn't your style. But it's where we are going. So sit back and enjoy it.

summary

We're going to support grids on the HP LaserJet printer, with room sizes such that they only span 4 printer dots in any direction. Let's calculate backwards, assuming we can pack 16 bits per INTEGER in BASIC, and see what the size of our arrays should be.

We take the total dot area of the printer and divide it by the dot area of our minimum sized room. Then divide again by the number of bits we can pack into an INTEGER array. That should get us the number of array elements, worst case, that we will need available to handle our west walls. A similar requirement, then, for the south walls and the visitation status.

29532 >= (300 * 8) * (300 * 10.5) / (4 * 4) / 16

So, a rounded 30,000 INTEGER elements would more than cover our needs for a bit array. Using three of these, one for west, one for south, and one for the visitation status, means a total of three 30,000 element arrays would cover the entire printer page with almost a half-million rooms!

That's one killer maze, eh?

Maze Algorithm

I hope I've conviced you this is a no-holds-barred maze generation program. Now, it's time to work out the details of an algorithm for the maze.

Something I neglected to tell you about, thus far, is that we'll need some way to restart the maze generation, after reaching a dead end. One way of handling this is to simply pick anywhere in the maze, at random, and check to see if we've been there before. If so, we pick up at that point.

But what if not? If not, we have to pick another place, at random.

Early in the maze generation, our odds of picking a location we've already been to isn't good. But if we do find one, the odds that we can forge a new path from there is pretty good.

Later in the maze generation, our odds of picking a location we've been to is pretty good. But the odds of being able to forge a new path from there gets to be really bad.

Either way you look at it, there's a problem. A solution is to keep a list of places we've been to in a 'path list.' We just add our visited locations into this list as we visit them, so long as there is more than one exit (there's no point adding them if there is only one, because we are going to take that direction and the next time there won't be any exits.)

So, here's the algorithm, in my form of pidgeon BASIC:

    Empty the path list.
    Set up the west walls.
    Set up the south walls.
    Set up the visitation status.
    Set up a count of rooms that remain to be visited.
    Pick a starting location in the maze, at random.
    DO WHILE (more rooms to visit),
      Decrement the count of rooms to visit.
      Mark the current room as visited.
      Count the number of valid exits from this room.
      DO WHILE (no exits from this room),
        Pick an entry from the path list, at random.
        Remove that entry from the path list.
        Count the number of valid exits from this new room.
      LOOP
      IF (count of exits > 1) THEN
        Add this room to the path list.
      END IF
      Select one of the available exits, at random.
      Break the intervening wall in that selected direction.
      Move into the new room in that direction.
    LOOP

Doesn't look that bad, does it? Once this is done, all we need to do is print out the maze.

You can take your own crack at writing this kind of program, if you want. Or you can download my versions and look at them, instead.

But they conform to this general approach.

Some General Issues

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.

Select one of the following programs. The links are to the .BAS files, directly. There are no ZIPped versions, below, nor HTMLized versions:
 
  • Text-mode Mazes, no bit flags, limited
    This text-output version is fairly simple and follows the logic outlined before. It is a straight-forward rendition.

  • Text-mode Mazes, bit flgs, limited
    This text-output version provides the same features as the first, except that it uses bit flags instead of wasting an entire INTEGER to represent walls and room visitation status.

  • Text-mode Mazes, bit flgs, big mazes
    This text-output version uses the denser packing of bit flags to extend the max size for a maze. The path list is eliminated, due to it's excessive use of memory, by using a bit field and a fast search algorithm.

 

Quick links:

 
  • HP LaserJet Mazes, bit flgs, big mazes
    This HP-output version uses the same idea above and provides the ability to place several mazes on a single page.

  • HP LaserJet Mazes, bit flgs, big, fast
    This HP-output version reorganizes the output routine to take advantage of fast vector drawing on the HP LaserJet. The program should print much more quickly onto the printer.

  • Screen Maze, bit flgs, big, fast
    This screen-output version modifies the HP vectorized version of the maze program and uses that same method to draw to the screen in mode 12.

  • Screen Maze + path finding
    This screen-output version adds an animated path-finding algorithm, once the maze is drawn. The path-finding algorithm searches the maze drawn on the screen by examining pixel values.

 
    Creation Date:  Tue 11-Jul-2000 11:40:24
    Last Modified:  Sat 15-Jul-2000 13:51:34
    Copyright (C) 2000 Jonathan Dale Kirwan