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 Y 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.           // Move to the correct position
  103.           planeTransform.postTranslate(
  104.             mazeOrigin + spaceBetweenPlanes * startX + wallWidth,
  105.             mazeHeight, mazeOrigin + spaceBetweenPlanes * i);
  106.           // give the actual size
  107.           planeTransform.postScale(wallWidth, mazeHeight, 1f);
  108.           allPlanes.addElement(new Plane(planeTransform, 1f));
  109.           startX = -1;
  110.         }
  111.       }
  112.     }
  113.     for (int i = 0; i < maze.length; i++)
  114.     {
  115.       int startY = -1;
  116.       long shift = (0x1L << i);
  117.       for (int j = 0; j < maze.length; j++)
  118.       {
  119.         if ((maze[j] & shift) == shift && startY == -1)
  120.         {
  121.           startY = j;
  122.           continue;
  123.         }
  124.         if ((((maze[j] & shift) == 0) || (j == (maze.length - 1)))
  125.            && (startY >= 0))
  126.         {
  127.           int steps = j - startY;
  128.           if (steps == 1)
  129.           {
  130.             startY = -1;
  131.             continue;
  132.           }
  133.           if (j == (maze.length - 1))
  134.           {
  135.             steps++;
  136.           }
  137.           Transform planeTransform = new Transform();
  138.           // Divided by 2 since the original square is of side 2;
  139.           float wallWidth = (spaceBetweenPlanes * (steps - 1) / 2);
  140.           // translate to the correct position
  141.           planeTransform.postTranslate(
  142.             mazeOrigin + spaceBetweenPlanes * i, mazeHeight,
  143.             mazeOrigin + spaceBetweenPlanes * startY + wallWidth);
  144.           // rotate 90 degrees since this is a vertical wall
  145.           planeTransform.postRotate(90f, 0f, 1f, 0f);
  146.           // give the correct size
  147.           planeTransform.postScale(wallWidth, mazeHeight, 1f);
  148.           allPlanes.addElement(new Plane(planeTransform, 1f));
  149.           startY = -1;
  150.         }
  151.       }
  152.     }
  153.     return allPlanes.elements();
  154.   }
  155.   // Create new random maze
  156.   private void createNew(int mazeSize)
  157.   {
  158.     Random random = new Random();
  159.     int totalSize = mazeSize * 2 + 1;
  160.     maze = new long[totalSize];
  161.     int backtrack[] = new int[mazeSize * mazeSize];
  162.     int backtrackIndex = 0;
  163.     for (int i = 0; i < maze.length; i++)
  164.     {
  165.       maze[i] = -1;//ȫ1
  166.     }
  167.     int x = 1;
  168.     int y = 1;
  169.     int UP = 0;
  170.     int DOWN = 1;
  171.     int LEFT = 2;
  172.     int RIGHT = 3;
  173.     // traverse the maze finding unconnected spots
  174.     while (true)
  175.     {
  176.       maze[x] &= ~(0x1 << y);
  177.       int currentBacktrackIndex = backtrackIndex;
  178.       int directions[] = new int[4];
  179.       int availableSpaces = 0;
  180.       if (y - 2 > 0 && (maze[x] & (0x1 << (y - 2))) != 0)
  181.       {
  182.         directions[availableSpaces++] = UP;
  183.       }
  184.       if (y + 2 < totalSize && (maze[x] & (0x1 << (y + 2))) != 0)
  185.       {
  186.         directions[availableSpaces++] = DOWN;
  187.       }
  188.       if (x + 2 < totalSize && (maze[x + 2] & (0x1 << y)) != 0)
  189.       {
  190.         directions[availableSpaces++] = LEFT;
  191.       }
  192.       if (x - 2 > 0 && (maze[x - 2] & (0x1 << y)) != 0)
  193.       {
  194.         directions[availableSpaces++] = RIGHT;
  195.       }
  196.       if (availableSpaces > 0)
  197.       {
  198.         int chosenDirection =
  199.           directions[(random.nextInt() >>> 1) % availableSpaces];
  200.         backtrack[backtrackIndex++] = chosenDirection;
  201.         if (chosenDirection == UP)
  202.         {
  203.           maze[x] &= ~(0x1 << (y - 1));
  204.           y -= 2;
  205.         }
  206.         if (chosenDirection == DOWN)
  207.         {
  208.           maze[x] &= ~(0x1 << (y + 1));
  209.           y += 2;
  210.         }
  211.         if (chosenDirection == LEFT)
  212.         {
  213.           maze[x + 1] &= ~(0x1 << y);
  214.           x += 2;
  215.         }
  216.         if (chosenDirection == RIGHT)
  217.         {
  218.           maze[x - 1] &= ~(0x1 << y);
  219.           x -= 2;
  220.         }
  221.       }
  222.       // if nothing is not visitied in the neigbourhood backtrack
  223.       else
  224.       {
  225.         if (backtrackIndex == 0)
  226.         {
  227.           // end of algorithm
  228.           break;
  229.         }
  230.         backtrackIndex--;
  231.         if (backtrack[backtrackIndex] == UP)
  232.         {
  233.           y += 2;
  234.         }
  235.         else if (backtrack[backtrackIndex] == DOWN)
  236.         {
  237.           y -= 2;
  238.         }
  239.         else if (backtrack[backtrackIndex] == LEFT)
  240.         {
  241.           x -= 2;
  242.         }
  243.         else if (backtrack[backtrackIndex] == RIGHT)
  244.         {
  245.           x += 2;
  246.         }
  247.       }
  248.     }
  249.     for(int i=0;i<maze.length;i++){
  250.     System.out.println(maze[i]);
  251.     
  252.     }
  253.     System.out.println("XXXXXXXXXXXXXX");
  254.     // find start and end points
  255.     while (true)
  256.     {
  257.       int pos = (random.nextInt() >>> 1) % totalSize;
  258.       if (startX < 0 && (maze[1] & (0x1 << pos)) == 0)
  259.       {
  260.         startX = pos;
  261.         maze[0] &= ~(0x1 << pos);
  262.       }
  263.       if (endX < 0 && (maze[maze.length - 2] & (0x1 << pos)) == 0)
  264.       {
  265.         endX = pos;
  266.         maze[maze.length - 1] &= ~(0x1 << pos);
  267.       }
  268.       if (endX >= 0 && startX >= 0)
  269.       {
  270.         break;
  271.       }
  272.     }
  273.     for(int i=0;i<maze.length;i++){
  274.     System.out.println(maze[i]);
  275.     
  276.     }
  277.     System.out.println(startX);
  278.     System.out.println(endX);
  279.   }
  280. }