Cube Maze is the continuation of what may well become a Christmas tradition. Last Christmas, as devoted readers may recall, I became captivated with a plastic puzzle called "Rubik's Clock" which was given to my brother-in-law. As he was leaving the next day, I quickly decided to create a fully-functioning HyperCard copy of the puzzle; the result was the Rubik's Clock stack.
This Christmas it happened again. My brother-in-law acquired a curious plastic marble maze cube from Japan. Once again I decided to make a HyperCard copy before Betsy and I had to return home. And so we have this month's installment of Mr. Wizard: the Cube Maze.
WHAT IT DOES
The cube maze is simply a maze drawn on the surface of a cube. The object is to move a marble from a special starting position through the maze and back to the start. This necessarily involves traversing most if not all of the six faces.
This puzzle was somewhat harder to replicate than Rubik's Clock. My first task was to laboriously reproduce every twist and turn of every passage on each of the six faces of the cube. I did this by painting a standard grid on each of six cards and then erasing the unwanted line segments (much as Michelangelo might chip away at a block of marble to find the statue within).
My next task was to provide an animated marble that would roll through the passages and over the edges without ever going through a wall. I also had to devise some system of pointing the marble in a valid direction.
My solution is something of a compromise, but it works. Whenever the marble is at an intersection, arrow buttons on a separate navigation panel illuminate, one for each valid direction. When you push an arrow button the marble automatically rolls to the next intersection. If it comes to a dead end, it reverses directions and returns to the intersection.
I also provided buttons that allow the player to view each of the six faces, so that she can turn the cube over in her hand, so to speak. A detailed series of help cards explains the game and the various control panels and even offers an analysis of the maze's substructure and a general solution.
Moving across the faces of a cube can be a bit confusing, both for the player and for the programmer as well. On a cube there is no consistent compass. It is impossible to assign north, south, east, and west in a consistent way. Inevitably, if you travel north off the edge of one face you will find yourself traveling east on the next face. I could have created the illusion of a consistent compass by providing 4 rotations of each face, but that might have been even more confusing (and would mean creating 24 cube cards instead of just 6). The challenge, then, was to capture the essential properties of a three dimensional object on a two dimensional screen.
HOW IT WORKS
From a programming standpoint, the trickiest part of this problem was how to let the player move the marble in any valid direction without ever allowing the marble to penetrate a wall. The marble itself is just an ordinary hypercard button; I move it by simply changing its location. The walls are just a collection of black dots painted on the surface of the card. The marble has no automatic way of "knowing" when it has hit a wall.
I could have created a huge chart of all possible legal moves and all possible illegal moves in any given position, but this would have been tedious. Besides, I would like to develop other maze stacks in the future and it would be nice not to have to go through such a process every time I create a new maze.
My solution was to take advantage of the fact that the walls are drawn in a very precise fashion, so that the vertical and horizontal width of every passage is precisely the same. I used an XFCN that returns whether any given pixel on the screen is black or white. If I look in a very precise manner I need only test a single dot; if it's black I can be sure there's a wall in that direction, if not, there is not a wall.
Most of the key subroutines are in the background layer. My "choice" function returns a list of all valid directions at any given point. My "march" routine simply moves the marble until there is more than one choice. The other handlers simply perform the animation necessary to move the marble north, south, east, or west. Four more handlers handle the special case of moving over an edge (this is where the essence of three dimensional space is captured).
As always, please feel free to examine the scripts. Those of you with slower Macs (that is, most of us) may find the movement of the marble a bit sluggish, especially at first. When I get more time I intend to develope an XCMD that can move the marble much faster. I'd also like to play with other ways of moving the marble, like dragging it or clicking near it.
A belated Merry Christmas, everyone! And now, if you please, push the "Push Me" button and get lost!