Moved maze generation into its own class, outside of the minecraft
Moved maze generation into its own class, outside of the minecraft
world. Also removed the open starting area.

--- a/net/minecraft/mazemod/ItemMazePaper.java
+++ b/net/minecraft/mazemod/ItemMazePaper.java
@@ -46,7 +46,11 @@
 	int iPosX=(int)entityplayer.posX;
 	int iPosY=(int)entityplayer.posY;
 	int iPosZ=(int)entityplayer.posZ;
-	generateMaze(world,iPosX,iPosY-2,iPosZ);
+
+	Maze maze=new Maze(5,5);
+	maze.draw(world,iPosX,iPosY-2,iPosZ);
+
+	//generateMaze(world,iPosX,iPosY-2,iPosZ);
 
 	return itemstack;
     }
@@ -123,10 +127,10 @@
 			break;
 		    }
 		
-		if(world.getBlockId(needSpaceAt.iPosX,needSpaceAt.iPosY,needSpaceAt.iPosZ)!=wallBlockID)
+		if(world.getBlockId(needSpaceAt.x,needSpaceAt.y,needSpaceAt.z)!=wallBlockID)
 		    {
 			foundExit=true;
-			world.setBlock(exitPos.iPosX,exitPos.iPosY,exitPos.iPosZ,0);
+			world.setBlock(exitPos.x,exitPos.y,exitPos.z,0);
 		    }
 	    }
 
@@ -153,7 +157,7 @@
 	// Create a list of available neighbors
 	if(isUnvisited(world, pos))
 	    {
-		world.setBlock(pos.iPosX,pos.iPosY,pos.iPosZ,0);
+		world.setBlock(pos.x,pos.y,pos.z,0);
 
 		List<iVec3D> neighbors=new LinkedList<iVec3D>();
 		neighbors.add(new iVec3D(1,0,0));
@@ -167,10 +171,10 @@
 			iVec3D nextDir=neighbors.remove(nextIdx);
 			iVec3D nextWall=pos.plus(nextDir);
 			iVec3D nextPos=nextWall.plus(nextDir);
-			if(world.getBlockId(nextPos.iPosX,nextPos.iPosY,nextPos.iPosZ)==wallBlockID)
+			if(world.getBlockId(nextPos.x,nextPos.y,nextPos.z)==wallBlockID)
 			    {
 				mazeGen(world,nextPos,stack);
-				world.setBlock(nextWall.iPosX,nextWall.iPosY,nextWall.iPosZ,0);
+				world.setBlock(nextWall.x,nextWall.y,nextWall.z,0);
 			    }
 		    }
 	    }
@@ -182,27 +186,27 @@
     {
 	int problems=0;
 	// Definitely visited if is already set
-	if(world.getBlockId(pos.iPosX,pos.iPosY,pos.iPosZ)!=wallBlockID)
+	if(world.getBlockId(pos.x,pos.y,pos.z)!=wallBlockID)
 	    problems++;
 
 	// There will always be at most entrance, so one visited neighbor
-	if(world.getBlockId(pos.iPosX+1,pos.iPosY,pos.iPosZ)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX-1,pos.iPosY,pos.iPosZ)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX,pos.iPosY,pos.iPosZ+1)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX,pos.iPosY,pos.iPosZ-1)!=wallBlockID)
+	if(world.getBlockId(pos.x+1,pos.y,pos.z)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x-1,pos.y,pos.z)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x,pos.y,pos.z+1)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x,pos.y,pos.z-1)!=wallBlockID)
 	    problems++;
 
 	// Make sure that there is nothing on the diagonals
-	if(world.getBlockId(pos.iPosX+1,pos.iPosY,pos.iPosZ+1)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX+1,pos.iPosY,pos.iPosZ-1)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX-1,pos.iPosY,pos.iPosZ+1)!=wallBlockID)
-	    problems++;
-	if(world.getBlockId(pos.iPosX-1,pos.iPosY,pos.iPosZ-1)!=wallBlockID)
+	if(world.getBlockId(pos.x+1,pos.y,pos.z+1)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x+1,pos.y,pos.z-1)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x-1,pos.y,pos.z+1)!=wallBlockID)
+	    problems++;
+	if(world.getBlockId(pos.x-1,pos.y,pos.z-1)!=wallBlockID)
 	    problems++;
 
 	if(problems>0)

--- /dev/null
+++ b/net/minecraft/mazemod/Maze.java
@@ -1,1 +1,79 @@
+/* This file is part of the Maze Mod
+ *
+ *
+ * Maze Mod is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maze Mod is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
+package net.minecraft.src;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Random;
+
+public class Maze 
+{
+    private MazeNode start;
+
+    public Maze(int halfWidth,int halfHeight)
+    {
+	MazeNode[][] nodes=new MazeNode[halfWidth*2+1][halfHeight*2+1];
+	// Prepare the base
+	for(int dx=0;dx<halfWidth*2+1;dx++)
+	    for(int dy=0;dy<halfHeight*2+1;dy++)
+		nodes[dx][dy]=new MazeNode();
+
+	// Connect neighbors
+	for(int dx=0;dx<halfWidth*2+1;dx++)
+	    for(int dy=0;dy<halfHeight*2+1;dy++)
+		{
+		    if(dx>0)
+			nodes[dx][dy].setNeighbor(MazeNode.West,nodes[dx-1][dy]);
+		    if(dx<nodes.length-1)
+			nodes[dx][dy].setNeighbor(MazeNode.East,nodes[dx+1][dy]);
+		    if(dy>0)
+			nodes[dx][dy].setNeighbor(MazeNode.South,nodes[dx][dy-1]);
+		    if(dy<nodes[dx].length-1)
+			nodes[dx][dy].setNeighbor(MazeNode.North,nodes[dx][dy+1]);
+		}
+
+	// Pick the exit
+	List<MazeNode> edges=new LinkedList<MazeNode>();
+	for(int dx=0;dx<halfWidth*2+1;dx++)
+	    for(int dy=0;dy<halfHeight*2+1;dy++)
+		if(nodes[dx][dy].isEdgeNode())
+		    edges.add(nodes[dx][dy]);
+
+	Random r=new Random();
+	int exitIdx=r.nextInt(edges.size());
+	edges.get(exitIdx).setExit(true);
+	
+
+	// Set the start base
+	start=nodes[halfWidth][halfHeight];
+	
+	// Make the maze... recursively using depth-first algorithm
+	generate();
+    }
+
+    private void generate()
+    {
+	start.generate();
+    }
+
+    public void draw(World world,int iPosX, int iPosY, int iPosZ)
+    {
+	start.draw(world,new iVec3D(iPosX,iPosY,iPosZ));
+	world.setBlockWithNotify(iPosX,iPosY+1,iPosZ,0);
+    }
+}

--- /dev/null
+++ b/net/minecraft/mazemod/MazeNode.java
@@ -1,1 +1,173 @@
+/* This file is part of the Maze Mod
+ *
+ *
+ * Maze Mod is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maze Mod is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
+package net.minecraft.src;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Random;
+
+public class MazeNode
+{
+    public static int North=0;
+    public static int East=1;
+    public static int South=2;
+    public static int West=3;
+
+    private MazeNode[] neighbors=new MazeNode[4];
+    private boolean[] connections=new boolean[4];
+    private iVec3D[] directions=new iVec3D[4];
+    private boolean drawn=false;
+    private boolean visited=false;
+
+    private boolean exit=false;
+
+    public MazeNode()
+    { 
+	for(int i=0;i<connections.length;i++)
+	    connections[i]=false;
+
+	directions[North]=new iVec3D(0,0,1);
+	directions[East]=new iVec3D(1,0,0);
+	directions[South]=new iVec3D(0,0,-1);
+	directions[West]=new iVec3D(-1,0,0);
+    }
+
+    public void setNeighbor(int i,MazeNode node)
+    {
+	neighbors[i]=node;
+    }
+
+    public boolean isVisited()
+    {
+	return visited;
+    }
+
+    public void setConnection(MazeNode neighbor,boolean connection)
+    {
+	for(int i=0;i<neighbors.length;i++)
+	    if(neighbor==neighbors[i])
+		{
+		    connections[i]=connection;
+		    return;
+		}
+    }	
+
+    public boolean isEdgeNode()
+    { // An edge node is a node with at least one edge without a neighbor
+	for(int i=0;i<neighbors.length;i++)
+	    if(neighbors[i]==null) return true;
+	return false;
+    }
+
+    public void setExit(boolean exit)
+    {
+	this.exit=exit;
+    }
+
+    public void generate()
+    {
+	visited=true;
+
+	// Create a list of avalable neighbors
+	List<MazeNode> availableNeighbors=new LinkedList<MazeNode>();
+	
+	for(int i=0;i<neighbors.length;i++)
+	    if(neighbors[i]!=null && !neighbors[i].isVisited())
+		availableNeighbors.add(neighbors[i]);
+
+	// Pick neighbors until all gone
+	Random r=new Random();
+	while(!availableNeighbors.isEmpty())
+	    {
+		int nextIdx=r.nextInt(availableNeighbors.size());
+		MazeNode nextNeighbor=availableNeighbors.remove(nextIdx);
+		if(!nextNeighbor.isVisited())
+		    { // Good choice
+			// Mark the connection
+			nextNeighbor.setConnection(this,true);
+			setConnection(nextNeighbor,true);
+
+			// Continue with recursive generation
+			nextNeighbor.generate();
+		    }
+	    }
+    }
+
+    public void draw(World world,iVec3D pos)
+    {
+	if(drawn) return;
+
+	drawn=true;
+	
+	// Draw the corners
+	drawWall(world,pos.plus(new iVec3D(1,0,1)));
+	drawWall(world,pos.plus(new iVec3D(1,0,-1)));
+	drawWall(world,pos.plus(new iVec3D(-1,0,1)));
+	drawWall(world,pos.plus(new iVec3D(-1,0,-1)));
+
+	// Draw other sides
+	for(int i=0;i<directions.length;i++)
+	    {
+		if(neighbors[i]==null)
+		    if(exit)
+			drawGround(world,pos.plus(directions[i]));
+		    else
+			drawWall(world,pos.plus(directions[i]));
+		else if(connections[i]==false)
+		    drawWall(world,pos.plus(directions[i]));
+		else
+		    {
+			neighbors[i].draw(world,pos.plus(directions[i].times(2)));
+			drawGround(world,pos.plus(directions[i]));
+		    }
+	    }
+
+	// Draw the ground
+	drawGround(world,pos);
+    }
+
+    public void drawGround(World world,iVec3D pos)
+    { 
+	world.setBlock(pos.x,pos.y,pos.z,Block.grass.blockID);
+	world.setBlock(pos.x,pos.y+1,pos.z,0);
+	world.setBlock(pos.x,pos.y+2,pos.z,0);
+	world.setBlock(pos.x,pos.y+3,pos.z,0);
+	drawFillDown(world,pos);
+    }
+
+    public void drawWall(World world,iVec3D pos)
+    { 
+	world.setBlock(pos.x,pos.y,pos.z,Block.wood.blockID);
+	world.setBlock(pos.x,pos.y+1,pos.z,Block.leaves.blockID);
+	world.setBlock(pos.x,pos.y+2,pos.z,Block.leaves.blockID);
+	world.setBlock(pos.x,pos.y+3,pos.z,Block.leaves.blockID);
+	drawFillDown(world,pos);
+    }
+
+    public void drawFillDown(World world,iVec3D pos)
+    {
+	// Make sure that the maze does not end up floating on air by addting
+	// stones until a stone layer is reached..
+	for(int y=pos.y-1;y>=0;y--)
+	    if(world.getBlockId(pos.x,y,pos.z)==Block.stone.blockID)
+		break;
+	    else
+		world.setBlock(pos.x,y,pos.z,Block.stone.blockID);
+
+    }
+}

--- a/net/minecraft/mazemod/iVec3D.java
+++ b/net/minecraft/mazemod/iVec3D.java
@@ -19,25 +19,31 @@
 
 class iVec3D
 {
-    public int iPosX;
-    public int iPosY;
-    public int iPosZ;
+    public int x;
+    public int y;
+    public int z;
 
-    public iVec3D(int iPosX,int iPosY, int iPosZ)
+    public iVec3D(int x,int y, int z)
     {
-	this.iPosX=iPosX;
-	this.iPosY=iPosY;
-	this.iPosZ=iPosZ;
+	this.x=x;
+	this.y=y;
+	this.z=z;
     }
 
     public iVec3D plus(iVec3D other)
     {
-	iVec3D result=new iVec3D(iPosX+other.iPosX,iPosY+other.iPosY,iPosZ+other.iPosZ);
+	iVec3D result=new iVec3D(x+other.x,y+other.y,z+other.z);
+	return result;
+    }
+
+    public iVec3D times(int a)
+    {
+	iVec3D result=new iVec3D(a*x,a*y,a*z);
 	return result;
     }
 
     public String toString()
     {
-	return iPosX+" "+iPosY+" "+iPosZ;
+	return x+" "+y+" "+z;
     }
 }