Maze.java
上传用户:gyyuli
上传日期:2013-07-09
资源大小:3050k
文件大小:8k
源码类别:

J2ME

开发平台:

Java

  1. import java.util.*;
  2. import javax.microedition.m3g.*;
  3. // This class creates the maze
  4. class Maze
  5. {
  6.   private final static int MAX_SIZE = 31;
  7.   // dimension of the maze
  8.   private final float mazeSideLength, mazeHeight;
  9.   // store the location on X of the start and end
  10.   private int startX = -1, endX = -1;
  11.   // maze rows are encoded as bits in a long field
  12.   private long[] maze;
  13.   // utility variables
  14.   private float mazeOrigin, spaceBetweenPlanes;
  15.   Maze(int corridorCount, float mazeSideLength, float mazeHeight)
  16.   {
  17.     if (corridorCount > MAX_SIZE)
  18.     {
  19.       throw new IllegalArgumentException("Maze too big");
  20.     }
  21.     this.mazeSideLength = mazeSideLength;
  22.     this.mazeHeight = mazeHeight;
  23.     createNew(corridorCount);
  24.   }
  25.   // creates a plane located at the start of the maze
  26.   Plane createStartMark()
  27.   {
  28.     Transform markTransform = new Transform();
  29.     markTransform.postTranslate(mazeOrigin
  30.       + startX * spaceBetweenPlanes,
  31.       mazeHeight / 2, mazeOrigin);
  32.     markTransform.postScale(3 * spaceBetweenPlanes / 4, 1f, 1f);
  33.     return new Plane(markTransform, 1f);
  34.   }
  35.   // creates a plane located at the end of the maze
  36.   Plane createEndMark()
  37.   {
  38.     Transform markTransform = new Transform();
  39.     markTransform.postTranslate(mazeOrigin
  40.     + endX * spaceBetweenPlanes,
  41.       mazeHeight / 2, -mazeOrigin);
  42.     markTransform.postScale(3 * spaceBetweenPlanes / 4, 1f, 1f);
  43.     markTransform.postRotate(180f, 0f, 1f, 0f);
  44.     return new Plane(markTransform, 1f);
  45.   }
  46.   // Calculate the start X coordinate
  47.   float findStartLocationX()
  48.   {
  49.     return mazeOrigin + (startX + 0.5f) * spaceBetweenPlanes;
  50.   }
  51.   // Calculate the start Z coordinate
  52.   float findStartLocationZ()
  53.   {
  54.     return mazeOrigin + spaceBetweenPlanes;
  55.   }
  56.   // checks if the location (x, z) is at the end given certain tolerance
  57.   boolean isAtTheEnd(float x, float z, float tolerance)
  58.   {
  59.     // just use linear distances
  60.     return Math.abs(x - (mazeOrigin + endX * spaceBetweenPlanes))
  61.       < tolerance
  62.       && Math.abs(z + mazeOrigin) < tolerance;
  63.   }
  64.   // creates the horizontal and vertical planes and puts
  65.   // them in an enumeration
  66.   Enumeration createPlanes()
  67.   {
  68.     // Space between walls
  69.     spaceBetweenPlanes = mazeSideLength / (maze.length - 1);
  70.     mazeOrigin = -mazeSideLength / 2;
  71.     Vector allPlanes = new Vector();
  72.     for (int i = 0; i < maze.length; i++)
  73.     {
  74.       int startX = -1;
  75.       for (int j = 0; j < maze.length; j++)
  76.       {
  77.         long shift = (0x1L << j);
  78.         if ((maze[i] & shift) == shift && startX == -1)
  79.         {
  80.           startX = j;
  81.           continue;
  82.         }
  83.         if ((((maze[i] & shift) == 0) || (j == (maze.length - 1)))
  84.            && (startX >= 0))
  85.         {
  86.           int steps = j - startX;
  87.           // Don't create walls of side 1 since they
  88.           // will be created on the other direction
  89.           if (steps == 1)
  90.           {
  91.             startX = -1;
  92.             continue;
  93.           }
  94.           // compensate that the last item is always 1
  95.           if (j == (maze.length - 1))
  96.           {
  97.             steps++;
  98.           }
  99.           Transform planeTransform = new Transform();
  100.           // Divided by 2 since the original square is of side 2;
  101.           float wallWidth = (spaceBetweenPlanes * (steps - 1) / 2);
  102.     //      System.out.println((int)wallWidth);
  103.           // Move to the correct position
  104.           planeTransform.postTranslate(
  105.             mazeOrigin + spaceBetweenPlanes * startX + wallWidth,
  106.             mazeHeight, mazeOrigin + spaceBetweenPlanes * i);
  107.           // give the actual size
  108.           planeTransform.postScale(wallWidth, mazeHeight, 1f);
  109.           allPlanes.addElement(new Plane(planeTransform, 1f));
  110.           startX = -1;
  111.         }
  112.       }
  113.     }
  114.    // System.out.println("begin");
  115.     for (int i = 0; i < maze.length; i++)
  116.     {
  117.       int startY = -1;
  118.       long shift = (0x1L << i);
  119.       for (int j = 0; j < maze.length; j++)
  120.       {
  121.         if ((maze[j] & shift) == shift && startY == -1)
  122.         {
  123.           startY = j;
  124.           continue;
  125.         }
  126.         if ((((maze[j] & shift) == 0) || (j == (maze.length - 1)))
  127.            && (startY >= 0))
  128.         {
  129.           int steps = j - startY;
  130.           if (steps == 1)
  131.           {
  132.             startY = -1;
  133.             continue;
  134.           }
  135.           if (j == (maze.length - 1))
  136.           {
  137.             steps++;
  138.           }
  139.           Transform planeTransform = new Transform();
  140.           // Divided by 2 since the original square is of side 2;
  141.           float wallWidth = (spaceBetweenPlanes * (steps - 1) / 2);
  142.           // translate to the correct position
  143.           planeTransform.postTranslate(
  144.             mazeOrigin + spaceBetweenPlanes * i, mazeHeight,
  145.             mazeOrigin + spaceBetweenPlanes * startY + wallWidth);
  146.           // rotate 90 degrees since this is a vertical wall
  147.           planeTransform.postRotate(90f, 0f, 1f, 0f);
  148.           //  缩放
  149.           planeTransform.postScale(wallWidth, mazeHeight, 1f);
  150.           allPlanes.addElement(new Plane(planeTransform, 1f));
  151.           startY = -1;
  152.         }
  153.       }
  154.     }
  155.     //System.out.println(allPlanes.size());
  156.     return allPlanes.elements();
  157.   }
  158.   // Create new random maze
  159.   private void createNew(int mazeSize)
  160.   {
  161.     Random random = new Random();
  162.     int totalSize = mazeSize * 2 + 1;
  163.     maze = new long[totalSize];
  164.     int backtrack[] = new int[mazeSize * mazeSize];
  165.     int backtrackIndex = 0;
  166.     for (int i = 0; i < maze.length; i++)
  167.     {
  168.       maze[i] = -1;
  169.     }
  170.     int x = 1;
  171.     int y = 1;
  172.     int UP = 0;
  173.     int DOWN = 1;
  174.     int LEFT = 2;
  175.     int RIGHT = 3;
  176.     // traverse the maze finding unconnected spots
  177.     while (true)
  178.     {
  179.     // System.out.println("("+x+","+y+")");
  180.       maze[x] &= ~(0x1 << y);
  181.       int currentBacktrackIndex = backtrackIndex;
  182.       int directions[] = new int[4];
  183.       int availableSpaces = 0;
  184.       if (y - 2 > 0 && (maze[x] & (0x1 << (y - 2))) != 0)
  185.       {
  186.         directions[availableSpaces++] = UP;
  187.       }
  188.       if (y + 2 < totalSize && (maze[x] & (0x1 << (y + 2))) != 0)
  189.       {
  190.         directions[availableSpaces++] = DOWN;
  191.       }
  192.       if (x + 2 < totalSize && (maze[x + 2] & (0x1 << y)) != 0)
  193.       {
  194.         directions[availableSpaces++] = LEFT;
  195.       }
  196.       if (x - 2 > 0 && (maze[x - 2] & (0x1 << y)) != 0)
  197.       {
  198.         directions[availableSpaces++] = RIGHT;
  199.       }
  200.       if (availableSpaces > 0)
  201.       {
  202.         int chosenDirection =
  203.           directions[(random.nextInt() >>> 1) % availableSpaces];
  204.         backtrack[backtrackIndex++] = chosenDirection;
  205.         if (chosenDirection == UP)
  206.         {
  207.           maze[x] &= ~(0x1 << (y - 1));
  208.           y -= 2;
  209.         }
  210.         if (chosenDirection == DOWN)
  211.         {
  212.           maze[x] &= ~(0x1 << (y + 1));
  213.           y += 2;
  214.         }
  215.         if (chosenDirection == LEFT)
  216.         {
  217.           maze[x + 1] &= ~(0x1 << y);
  218.           x += 2;
  219.         }
  220.         if (chosenDirection == RIGHT)
  221.         {
  222.           maze[x - 1] &= ~(0x1 << y);
  223.           x -= 2;
  224.         }
  225.       }
  226.       // if nothing is not visitied in the neigbourhood backtrack
  227.       else
  228.       {
  229.         if (backtrackIndex == 0)
  230.         {
  231.           // end of algorithm
  232.           break;
  233.         }
  234.         backtrackIndex--;
  235.         if (backtrack[backtrackIndex] == UP)
  236.         {
  237.           y += 2;
  238.         }
  239.         else if (backtrack[backtrackIndex] == DOWN)
  240.         {
  241.           y -= 2;
  242.         }
  243.         else if (backtrack[backtrackIndex] == LEFT)
  244.         {
  245.           x -= 2;
  246.         }
  247.         else if (backtrack[backtrackIndex] == RIGHT)
  248.         {
  249.           x += 2;
  250.         }
  251.       }
  252.     }
  253.     // find start and end points
  254.     while (true)
  255.     {
  256.       int pos = (random.nextInt() >>> 1) % totalSize;
  257.       if (startX < 0 && (maze[1] & (0x1 << pos)) == 0)
  258.       {
  259.         startX = pos;
  260.         maze[0] &= ~(0x1 << pos);
  261.       }
  262.       if (endX < 0 && (maze[maze.length - 2] & (0x1 << pos)) == 0)
  263.       {
  264.         endX = pos;
  265.         maze[maze.length - 1] &= ~(0x1 << pos);
  266.       }
  267.       if (endX >= 0 && startX >= 0)
  268.       {
  269.         break;
  270.       }
  271.     }
  272.        /* for(int i=0;i<maze.length;i++){
  273.     System.out.println(maze[i]);
  274.     
  275.     }
  276.     System.out.println(startX);
  277.     System.out.println(endX);*/
  278.   }
  279. }