/* MazeTile.java 3.1 Written by Kevin N. Haw and JoAnn K. Haw, www.thehaws.org. Please mail comments via the link at our website. Implements maze drawing in Java, 1.1 (to support older versions of Netscape and IE). All contents copyright 2000-2005 by Kevin N. Haw and JoAnn K. Haw. The authors grant permission to freely distribute and modify this program as long as this copyright notice and all copyright notices embedded in the program remain intact. MazeTile This class serves as a building block for mazes. Each tile is a polygon that is fitted together with other tiles. Sides from each tile are removed to form paths in the maze. Sides left intact for the maze's walls. Tiles (currently) have the following restrictions: 1) All tiles must be homogeneous. That is, each tile must have same shape and orientation as all others. 1a) As a result, only 4 and 6 sided polygons can be used. 2) Edges between tiles are single, straight line segments. 2a) Each tile is defined by a polygon. To use: First, the caller invokes the static method MazeTile.AllocateMaze() with a boundary rectangle and a polygon to use as a template for the tiles. A MazeTile is returned. The user then invokes constructmaze() on that MazeTile every time that a new maze is to be created. Additional methods solve the maze, paint it, determine what tile contains a given point, or find the corner tiles of the maze. */ import java.awt.*; import java.awt.event.*; import java.awt.Graphics; import java.util.Vector; import java.awt.Point; import java.awt.Rectangle; import java.io.PrintStream; import java.awt.Color; import java.awt.Polygon; import java.applet.AppletContext; import java.net.URL; import java.lang.Thread; class MazeTile { // Copyright and version data public static String copyMsg = "MazeTile: Copyright Kevin N. Haw and JoAnn K. Haw, 2000-2005."; public static String verMsg = "MazeTile v 3.1"; public static int verno = 0x300100; // Byte0=revision, byte1= minor version, byte2= major version // Define variables to manage an entire maze Vector theMaze; // List of all MazeTiles in this maze // Define data for each instance of the class Point Center; Polygon TilePoly; // This tile's polygon MazeTile Neighbor[]; // Array of references to neighboring tiles. // NULL indicates maze boundary boolean pathToNeighbor[]; // TRUE if neighbor has path, FALSE // if blocked by a wall boolean tileMapped; // Working variable for maze creation and solving // This constructor creates a maze tile, not connected to any neighbors. MazeTile(Polygon poly, // Shape of tile Vector maze) // Maze this tile is part of { int i; int sumX=0, sumY=0; // Used to calculate tile center // Record the tile's shape TilePoly = poly; // Allocate arrays to express tile's relationship with neighbors Neighbor = new MazeTile[TilePoly.npoints]; pathToNeighbor = new boolean[TilePoly.npoints]; // Sum and average the points in the polygon to find the center for(i=0; i 0) { // Pick a tile at random i = (int) (possiblePathList.size() * Math.random()); // Get a reference to the tile theTile = (MazeTile)possiblePathList.elementAt(i); theDirection = ((Integer)pathDirectionList.elementAt(i)).intValue(); // If the tile is still not part of the maze, create a path to it if(Neighbor[theDirection].tileMapped == false) { // Mark the path pathToNeighbor[theDirection] = true; // For the next step, we need to be able to tell the neighbor who // its parent is (this tile) and in what direction it lies. To do // this, loop through the neighbor's references to its neighbors // until we see a reference back to this tile. for(j=0; j= theTile.Center.x) ) || (rightMost && (cornerTile.Center.x <= theTile.Center.x) ) || (leftMost==false && rightMost==false) ) { // We are at the horizontal extreme - check the vertical if( (topMost && (cornerTile.Center.y >= theTile.Center.y) ) || (bottomMost && (cornerTile.Center.y <= theTile.Center.y) ) || (topMost==false && bottomMost==false) ) { // Corner found cornerTile = theTile; } } } // Return corner tile. return(cornerTile); } // Recursive routine calculates the path to a given tile Vector solve(MazeTile end) { int i; Vector theSolution; // Mark this tile as being visited for finding the solution tileMapped = true; // Determine if this tile is the endpoint for the solution search if (this == end) { // Solution is found - return the solution, adding this tile to it theSolution = new Vector(); theSolution.addElement(this); return (theSolution); } // This tile is not the solution. Keep looking, searching // each of the neighboring tiles. for(i=0; i