Package maze.ai

Source Code of maze.ai.ModifiedFloodfill

package maze.ai;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Vector;

import maze.model.Direction;
import maze.model.MazeCell;
import maze.model.MazeModel;
import maze.model.RobotModel;

public class ModifiedFloodfill extends RobotBase
{
   private int[][] distance;
   private boolean[][] explored;
   private int[][] directions;
   private ArrayList<RobotStep> moveQueue = new ArrayList<RobotStep>();
   private boolean turbo = false;
   private static final int USELESS = 1024;
   private MazeModel maze = new MazeModel();
   private boolean goal;
   private static final boolean TO_CENTER = true;
   private static final boolean TO_START = false;
   private boolean speedRunCapable;

   /**
    * Returns a string describing this class
    */
   @Override
   public String toString()
   {
      return "Modified Flood Fill";
   }

   /**
    * Initializes the algorithm for use. This should be called before any run is
    * started.
    */
   @Override
   public void initialize()
   {
      super.initialize();
      moveQueue.clear();
      maze.setSize(robotLocation.getMazeSize());
      maze.clearMaze();
      Dimension size = maze.getSize();
      if (distance == null)
      {
         distance = new int[size.width][size.height];
         explored = new boolean[size.width][size.height];
         directions = new int[size.width][size.height];
      }
      for (int i = 0; i < size.width; i++)
      {
         for (int j = 0; j < size.height; j++)
         {
            distance[i][j] = USELESS;
            explored[i][j] = false;
            directions[i][j] = 0;
         }
      }
      goal = TO_CENTER;
      speedRunCapable = false;
   }

   /**
    * Returns the next step that the robot should take. This is called by the
    * controller.
    */
   @Override
   public RobotStep nextStep()
   {
      RobotStep next;
      Direction nextDirection;
      Direction currentDirection = robotLocation.getDirection();
      if (moveQueue.isEmpty())
      {
         if (getExplored() == false)
         {
            checkWalls();
            setExplored();
         }
         if (atGoal() == true)
         {
            if ( (goal == TO_CENTER) && (speedRunCapable == false))
            {
               speedRunCapable = true;
               blockOutCenter();
            }
            goal = !goal;
            floodfill();
         }
         nextDirection = getBestDirection();
         turbo = getNeighborExplored(nextDirection);
         if (nextDirection == currentDirection)
         {
            next = RobotStep.MoveForward;
         }
         else if (nextDirection == currentDirection.getLeft())
         {
            next = RobotStep.RotateLeft;
            moveQueue.add(RobotStep.MoveForward);
         }
         else if (nextDirection == currentDirection.getRight())
         {
            next = RobotStep.RotateRight;
            moveQueue.add(RobotStep.MoveForward);
         }
         else
         // if(nextDirection == currentDirection.getOpposite())
         {
            next = RobotStep.MoveBackward;
         }
      }
      else
      {
         next = moveQueue.get(0);
         moveQueue.remove(0);
      }
      return next;
   }

   /**
    * Returns the explored flag of the current location's neighbor in the given
    * direction.
    */
   private boolean getNeighborExplored(Direction direction)
   {
      MazeCell neighbor;
      MazeCell here = robotLocation.getCurrentLocation();
      Dimension size = maze.getSize();
      if ( (direction == Direction.North) && (here.getY() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() - 1);
      }
      else if ( (direction == Direction.South) && (here.getY() != size.getHeight()))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() + 1);
      }
      else if ( (direction == Direction.East) && (here.getX() != size.getWidth()))
      {
         neighbor = MazeCell.valueOf(here.getX() + 1, here.getY());
      }
      else if ( (direction == Direction.West) && (here.getX() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX() - 1, here.getY());
      }
      else
      {
         return false;
      }

      return getExplored(neighbor);
   }

   /**
    * Returns the explored flag of the given location's neighbor.
    */
   private boolean getNeighborExplored(MazeCell here, Direction direction)
   {
      MazeCell neighbor;
      Dimension size = maze.getSize();
      if ( (direction == Direction.North) && (here.getY() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() - 1);
      }
      else if ( (direction == Direction.South) && (here.getY() != size.getHeight()))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() + 1);
      }
      else if ( (direction == Direction.East) && (here.getX() != size.getWidth()))
      {
         neighbor = MazeCell.valueOf(here.getX() + 1, here.getY());
      }
      else if ( (direction == Direction.West) && (here.getX() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX() - 1, here.getY());
      }
      else
      {
         return false;
      }

      return getExplored(neighbor);
   }

   /**
    * Returns the explored flag of the given location.
    */
   private boolean getExplored(MazeCell cell)
   {
      return explored[cell.getX() - 1][cell.getY() - 1];
   }

   /**
    * Returns the explored flag of the current location.
    */
   private boolean getExplored()
   {
      return getExplored(robotLocation.getCurrentLocation());
   }

   /**
    * Sets the explored flag of the current location to true.
    */
   private void setExplored()
   {
      explored[robotLocation.getCurrentLocation().getX() - 1][robotLocation.getCurrentLocation().getY() - 1] = true;
   }

   /**
    * Returns the best direction to go, according to Floodfill, from the current
    * MazeCell. This algorithm biases in the following order: Straight, North,
    * East, West, South
    */
   private Direction getBestDirection()
   {
      MazeCell here = robotLocation.getCurrentLocation();
      Direction current = robotLocation.getDirection();
      //int bestDistance = getDistance(here);
      Direction bestDirection = null;

      if (hasSameDirection(here, Direction2.getDirection(current)))
      //&& (robotLocation.isWallFront() == false))
      {
         bestDirection = current;
      }
      else if (hasSameDirection(here, Direction2.getDirection(Direction.North)))
      //&& (maze.getWall(here, Direction.North).isSet() == false))
      {
         bestDirection = Direction.North;
      }
      else if (hasSameDirection(here, Direction2.getDirection(Direction.East)))
      //&& (maze.getWall(here, Direction.East).isSet() == false))
      {
         bestDirection = Direction.East;
      }
      else if (hasSameDirection(here, Direction2.getDirection(Direction.South)))
      //&& (maze.getWall(here, Direction.South).isSet() == false))
      {
         bestDirection = Direction.South;
      }
      else if (hasSameDirection(here, Direction2.getDirection(Direction.West)))
      //&& (maze.getWall(here, Direction.West).isSet() == false))
      {
         bestDirection = Direction.West;
      }
      /*
            if ( (bestDistance >
                getNeighborDistance(here, robotLocation.getDirection())) &&
                (robotLocation.isWallFront() == false))
            {
               bestDirection = robotLocation.getDirection();
               bestDistance = getNeighborDistance(here, bestDirection);
            }

            if ( (bestDistance > getNeighborDistance(here, Direction.North)) &&
                (maze.getWall(here, Direction.North).isSet() == false))
            {
               bestDirection = Direction.North;
               bestDistance = getNeighborDistance(here, bestDirection);
            }
            if ( (bestDistance > getNeighborDistance(here, Direction.East)) &&
                (maze.getWall(here, Direction.East).isSet() == false))
            {
               bestDirection = Direction.East;
               bestDistance = getNeighborDistance(here, bestDirection);
            }
            if ( (bestDistance > getNeighborDistance(here, Direction.West)) &&
                (maze.getWall(here, Direction.West).isSet() == false))
            {
               bestDirection = Direction.West;
               bestDistance = getNeighborDistance(here, bestDirection);
            }
            if ( (bestDistance > getNeighborDistance(here, Direction.South)) &&
                (maze.getWall(here, Direction.South).isSet() == false))
            {
               bestDirection = Direction.South;
               bestDistance = getNeighborDistance(here, bestDirection);
            }
            */

      if (bestDirection == null)
      {
         modifiedFloodfill();
         return getBestDirection();
      }
      else
      {
         return bestDirection;
      }
   }

   /**
    * Returns the distance of the MazeCell adjacent to the passed MazeCell and
    * is adjacent in the specified direction.
    */
   private int getNeighborDistance(MazeCell here, Direction direction)
   {
      MazeCell neighbor;
      Dimension size = maze.getSize();
      if ( (direction == Direction.North) && (here.getY() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() - 1);
      }
      else if ( (direction == Direction.South) && (here.getY() != size.getHeight()))
      {
         neighbor = MazeCell.valueOf(here.getX(), here.getY() + 1);
      }
      else if ( (direction == Direction.East) && (here.getX() != size.getWidth()))
      {
         neighbor = MazeCell.valueOf(here.getX() + 1, here.getY());
      }
      else if ( (direction == Direction.West) && (here.getX() != 1))
      {
         neighbor = MazeCell.valueOf(here.getX() - 1, here.getY());
      }
      else
      {
         return USELESS;
      }

      return getDistance(neighbor);
   }

   /**
    * Returns the distance of the desired MazeCell
    */
   private int getDistance(MazeCell here)
   {
      return distance[here.getX() - 1][here.getY() - 1];
   }

   /**
    * Sets the distance of the desired MazeCell to the value provided
    */
   private void setDistance(MazeCell here, int value)
   {
      distance[here.getX() - 1][here.getY() - 1] = value;
   }

   private void floodfill()
   {
      Dimension size = maze.getSize();
      Vector<MazeCell> queue = new Vector<MazeCell>();
      MazeCell cell;
      int currentDistance;
      boolean speedy;

      for (int i = 1; i <= size.width; i++)
      {
         for (int j = 1; j <= size.height; j++)
         {
            MazeCell here = MazeCell.valueOf(i, j);
            setDistance(here, USELESS);
            setDirection(here, 0);
         }
      }

      if (goal == TO_START)
      {
         cell = MazeCell.valueOf(1, size.height);
         setDistance(cell, 0);
         queue.add(cell);
         speedy = false;
      }
      else
      {
         int targetX = size.width / 2;
         int targetY = size.height / 2;
         cell = MazeCell.valueOf(targetX, targetY);
         setDistance(cell, 0);
         queue.add(cell);
         cell = MazeCell.valueOf(targetX + 1, targetY);
         setDistance(cell, 0);
         queue.add(cell);
         cell = MazeCell.valueOf(targetX, targetY + 1);
         setDistance(cell, 0);
         queue.add(cell);
         cell = MazeCell.valueOf(targetX + 1, targetY + 1);
         setDistance(cell, 0);
         queue.add(cell);
         if ( (speedRun == true) && (speedRunCapable == true))
         {
            speedy = true;
         }
         else
         {
            speedy = false;
         }
      }

      while (queue.isEmpty() == false)
      {
         cell = queue.get(0);
         queue.remove(0);
         currentDistance = getDistance(cell);

         //Check to see if accessible
         if (maze.getWall(cell, Direction.North).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.North)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.North) == true)))
            {
               queue.add(cell.plusY(-1));
               setDistance(cell.plusY(-1), currentDistance + 1);
               setDirection(cell.plusY(-1), Direction2.South.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.North)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.North) == true)))
            {
               setDirection(cell.plusY(-1), Direction2.South.getIndex() +
                                            getDirection(cell.plusY(-1)));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.South).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.South)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.South))))
            {
               queue.add(cell.plusY(1));
               setDistance(cell.plusY(1), currentDistance + 1);
               setDirection(cell.plusY(1), Direction2.North.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.South)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.South) == true)))
            {
               setDirection(cell.plusY(1), Direction2.North.getIndex() +
                                           getDirection(cell.plusY(1)));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.West).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.West)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.West))))
            {
               queue.add(cell.plusX(-1));
               setDistance(cell.plusX(-1), currentDistance + 1);
               setDirection(cell.plusX(-1), Direction2.East.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.West)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.West) == true)))
            {
               setDirection(cell.plusX(-1), Direction2.East.getIndex() +
                                            getDirection(cell.plusX(-1)));
            }

         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.East).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.East)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.East))))
            {
               queue.add(cell.plusX(1));
               setDistance(cell.plusX(1), currentDistance + 1);
               setDirection(cell.plusX(1), Direction2.West.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.East)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.East) == true)))
            {
               setDirection(cell.plusX(1), Direction2.West.getIndex() + getDirection(cell.plusX(1)));
            }
         }
      }

      MazeCell here = robotLocation.getCurrentLocation();
      if (getDistance(here) == USELESS)
      {
         System.out.println("Purging Knowledge");
         maze.clearMaze();
         speedRunCapable = false;
         for (int i = 0; i < size.width; i++)
         {
            for (int j = 0; j < size.height; j++)
            {
               explored[i][j] = false;
            }
         }
         explored[here.getX() - 1][here.getY() - 1] = true;
         checkWalls();
         floodfill();
      }
   }

   /**
    * This function loads a value into the directions array based upon the cell
    * passed and the value in i
    */
   private void setDirection(MazeCell here, int i)
   {
      directions[here.getX() - 1][here.getX() - 1] = i;
   }

   /**
    * This function loads a value into the directions array based upon the cell
    * passed and the value in i
    */
   private int getDirection(MazeCell here)
   {
      return directions[here.getX() - 1][here.getX() - 1];
   }

   /**
    * This function loads a value into the directions array based upon the cell
    * passed and the value in i
    */
   private boolean isSameDirection(MazeCell here, Direction2 dir)
   {
      if (directions[here.getX() - 1][here.getX() - 1] == dir.getIndex())
      {
         return true;
      }
      else
      {
         return false;
      }
   }

   /**
    * This function loads a value into the directions array based upon the cell
    * passed and the value in i
    */
   private boolean hasSameDirection(MazeCell here, Direction2 dir)
   {
      return Direction2.containsDirection(directions[here.getX() - 1][here.getX() - 1], dir);
   }

   /**
    * This helper function should only be called when first entering the center
    * goal. Sets the maze knowledge of the algorithm to think that there are no
    * other ways out of the center because according the American rules there is
    * only one entrance/exit associated with the goal.
    */
   private void blockOutCenter()
   {
      Dimension size = maze.getSize();
      MazeCell cell1 = MazeCell.valueOf(size.width / 2, size.height / 2);
      MazeCell cell2 = MazeCell.valueOf(size.width / 2 + 1, size.height / 2);
      MazeCell cell3 = MazeCell.valueOf(size.width / 2, size.height / 2 + 1);
      MazeCell cell4 = MazeCell.valueOf(size.width / 2 + 1, size.height / 2 + 1);
      MazeCell current = robotLocation.getCurrentLocation();

      if (cell1.equals(current) == false)
      {
         maze.setWall(cell1.getX(), cell1.getY(), Direction.North.getIndex());
         maze.setWall(cell1.getX(), cell1.getY(), Direction.West.getIndex());
      }
      if (cell2.equals(current) == false)
      {
         maze.setWall(cell2.getX(), cell2.getY(), Direction.North.getIndex());
         maze.setWall(cell2.getX(), cell2.getY(), Direction.East.getIndex());
      }
      if (cell3.equals(current) == false)
      {
         maze.setWall(cell3.getX(), cell3.getY(), Direction.South.getIndex());
         maze.setWall(cell3.getX(), cell3.getY(), Direction.West.getIndex());
      }
      if (cell4.equals(current) == false)
      {
         maze.setWall(cell4.getX(), cell4.getY(), Direction.South.getIndex());
         maze.setWall(cell4.getX(), cell4.getY(), Direction.East.getIndex());
      }
   }

   /**
    * Returns true if the current location of the robot is its current
    * destination.
    */
   private boolean atGoal()
   {
      MazeCell cell = robotLocation.getCurrentLocation();
      Dimension size = maze.getSize();
      if ( (goal == TO_START) && (cell.getX() == 1) && (cell.getY() == size.height))
      {
         return true;
      }
      if ( (goal == TO_CENTER) &&
          ( (cell.getY() == size.height / 2) || (cell.getY() == (size.height / 2 + 1))) &&
          ( (cell.getX() == size.width / 2) || (cell.getX() == (size.width / 2 + 1))))
      {
         return true;
      }
      return false;
   }

   /**
    * Updates the algorithm's memory of the maze based upon the walls in the
    * current cell.
    */
   private void checkWalls()
   {
      MazeCell cell = robotLocation.getCurrentLocation();
      Direction direction = robotLocation.getDirection();
      if (robotLocation.isWallFront())
      {
         maze.setWall(cell.getX(), cell.getY(), direction.getIndex());
         if (hasSameDirection(cell, Direction2.getDirection(direction)))
         {
            setDirection(cell, getDirection(cell) ^ Direction2.getDirection(direction).getIndex());
         }
      }
      if (robotLocation.isWallLeft())
      {
         maze.setWall(cell.getX(), cell.getY(), direction.getLeft().getIndex());
         setDirection(cell,
                      getDirection(cell) &
                            (Direction2.Mask.getIndex() ^ Direction2.getDirection(direction.getLeft()).getIndex()));
      }
      if (robotLocation.isWallRight())
      {
         maze.setWall(cell.getX(), cell.getY(), direction.getRight().getIndex());
         setDirection(cell,
                      getDirection(cell) &
                            (Direction2.Mask.getIndex() ^ Direction2.getDirection(direction.getRight()).getIndex()));
      }
      if (robotLocation.isWallBack())
      {
         maze.setWall(cell.getX(), cell.getY(), direction.getOpposite().getIndex());
         setDirection(cell,
                      getDirection(cell) &
                            (Direction2.Mask.getIndex() ^ Direction2.getDirection(direction.getOpposite()).getIndex()));
      }
   }

   /**
    * Returns the "turbo" state of the algorithm. Will be true when areas are
    * being traversed after they have been explored before.
    */
   public boolean isInTurboMode()
   {
      return turbo;
   }

   /**
    * Returns the instance of how the algorithm understands the maze. For
    * Floodfill this is an integer for each cell representing the expected
    * distance from the center.
    */
   public int[][] getUnderstandingInt()
   {
      return distance;
   }

   @Override
   /**
    * Sets the instance of the robot model to use.
    */
   public void setRobotLocation(RobotModel model)
   {
      this.robotLocation = model;
      distance = null; //insures that initialize() works right
   }

   private void modifiedFloodfill()
   {
      //Dimension size = maze.getSize();
      Vector<MazeCell> queue = new Vector<MazeCell>();
      Vector<MazeCell> badQueue = new Vector<MazeCell>();
      MazeCell cell;
      MazeCell here = robotLocation.getCurrentLocation();
      int currentDistance;
      boolean speedy;

      if ( (goal == TO_CENTER) && (speedRun == true) && (speedRunCapable == true))
      {
         speedy = true;
      }
      else
      {
         speedy = false;
      }

      //Load up a queue until you find good info
      badQueue.add(here);
      while ( (badQueue.isEmpty() == false)/* && (queue.isEmpty() == true)*/)
      {
         cell = badQueue.get(0);
         badQueue.remove(0);
         this.setDistance(cell, USELESS);
         currentDistance = USELESS;

         //Check to see if accessible
         if (maze.getWall(cell, Direction.North).isSet() == false)
         { //Check to see if it should be added to queue
            if (neighborIsPoisoned(cell, Direction.North))
            {
               //if( queue.isEmpty()){
               badQueue.add(cell.plusY(-1));
               //}
               setDirection(cell.plusY(-1), Direction2.Directionless.getIndex());
            }
            else
            {
               queue.add(cell.plusY(-1));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.South).isSet() == false)
         { //Check to see if it should be added to queue
            if (neighborIsPoisoned(cell, Direction.South))
            {
               //if( queue.isEmpty()){
               badQueue.add(cell.plusY(1));
               //}
               setDirection(cell.plusY(1), Direction2.Directionless.getIndex());
            }
            else
            {
               queue.add(cell.plusY(1));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.West).isSet() == false)
         { //Check to see if it should be added to queue
            if (neighborIsPoisoned(cell, Direction.West))
            {
               //if( queue.isEmpty()){
               badQueue.add(cell.plusX(-1));
               //}
               setDirection(cell.plusX(-1), Direction2.Directionless.getIndex());
            }
            else
            {
               queue.add(cell.plusX(-1));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.East).isSet() == false)
         { //Check to see if it should be added to queue
            if (neighborIsPoisoned(cell, Direction.East))
            {
               //if( queue.isEmpty()){
               badQueue.add(cell.plusX(1));
               //}
               setDirection(cell.plusX(1), Direction2.Directionless.getIndex());
            }
            else
            {
               queue.add(cell.plusX(1));
            }
         }
         this.setDistance(cell, USELESS);
      }

      //Work back from the good knowledge to the current location
      while (queue.isEmpty() == false)
      {
         if (queue.contains(here))
         {
            return;
         }
         cell = queue.get(0);
         queue.remove(0);
         currentDistance = getDistance(cell);

         //Check to see if accessible
         if (maze.getWall(cell, Direction.North).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.North)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.North) == true)))
            {
               queue.add(cell.plusY(-1));
               setDistance(cell.plusY(-1), currentDistance + 1);
               setDirection(cell.plusY(-1), Direction2.South.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.North)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.North) == true)))
            {
               setDirection(cell.plusY(-1), Direction2.South.getIndex() +
                                            getDirection(cell.plusY(-1)));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.South).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.South)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.South))))
            {
               queue.add(cell.plusY(1));
               setDistance(cell.plusY(1), currentDistance + 1);
               setDirection(cell.plusY(1), Direction2.North.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.South)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.South) == true)))
            {
               setDirection(cell.plusY(1), Direction2.North.getIndex() +
                                           getDirection(cell.plusY(1)));
            }
         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.West).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.West)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.West))))
            {
               queue.add(cell.plusX(-1));
               setDistance(cell.plusX(-1), currentDistance + 1);
               setDirection(cell.plusX(-1), Direction2.East.getIndex());
            }
            else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.West)) &&
                     ( (speedy == false) || (getNeighborExplored(cell, Direction.West) == true)))
            {
               setDirection(cell.plusX(-1), Direction2.East.getIndex() +
                                            getDirection(cell.plusX(-1)));
            }

         }

         //Check to see if accessible
         if (maze.getWall(cell, Direction.East).isSet() == false)
         { //Check to see if it should be added to queue
            if ( ( (currentDistance + 1) < getNeighborDistance(cell, Direction.East)) &&
                ( (speedy == false) || (getNeighborExplored(cell, Direction.East))))
            {
               queue.add(cell.plusX(1));
               setDistance(cell.plusX(1), currentDistance + 1);
               setDirection(cell.plusX(1), Direction2.West.getIndex());
            }
         }
         else if ( ( (currentDistance + 1) == getNeighborDistance(cell, Direction.East)) &&
                  ( (speedy == false) || (getNeighborExplored(cell, Direction.East) == true)))
         {
            setDirection(cell.plusY(-1), Direction2.West.getIndex() + getDirection(cell.plusX(1)));
         }
      }

      System.out.println("Failed Modified");
      floodfill();
   }

   private boolean neighborIsPoisoned(MazeCell cell, Direction dir)
   {
      //This function determines if a cell is tainted by bad information
      //This can be tested by finding if the cell has a neighbor that is
      //better other than the one querying it
      if (getNeighborDistance(cell, dir) == 0)
      {
         //Goals are not poisoned
         return false;
      }

      MazeCell here;
      Direction whereFrom = dir.getOpposite();

      if (dir.equals(Direction.North))
      {
         here = cell.plusY(-1);
      }
      else if (dir.equals(Direction.South))
      {
         here = cell.plusY(1);
      }
      else if (dir.equals(Direction.East))
      {
         here = cell.plusX(1);
      }
      else if (dir.equals(Direction.West))
      {
         here = cell.plusX(-1);
      }
      else
      {
         //If directionless was passed then we just act like it's not poisoned
         return false;
      }

      /*
      if(!whereFrom.equals(Direction.North))
      {
         if(getDistance(here)> getNeighborDistance(here,Direction.North)){
           return false;
         }
      }
      if(!whereFrom.equals(Direction.South))
      {
         if(getDistance(here)> getNeighborDistance(here,Direction.South)){
           return false;
         }
      }
      if(!whereFrom.equals(Direction.West))
      {
         if(getDistance(here)> getNeighborDistance(here,Direction.West)){
           return false;
         }
      }
      if(!whereFrom.equals(Direction.East))
      {
         if(getDistance(here)> getNeighborDistance(here,Direction.East)){
           return false;
         }
      }
      */

      if ( (hasSameDirection(here, Direction2.getDirection(whereFrom)) == true) &&
          isSameDirection(here, Direction2.getDirection(whereFrom)) == false)
      {
         setDirection(here, getDirection(here) ^ Direction2.getDirection(whereFrom).getIndex());
         return false;
      }

      return isSameDirection(here, Direction2.getDirection(whereFrom));
   }

   public static enum Direction2
   {
      //These should match those values set in Maze.java

      North(1),
      South(2),
      East(4),
      West(8),
      Directionless(0),
      Mask(15);
      private final int index;

      private Direction2(int index)
      {
         this.index = index;
      }

      public int getIndex()
      {
         return this.index;
      }

      public static Direction2 getDirection(Direction dir)
      {
         if (dir.equals(Direction.North))
         {
            return North;
         }
         if (dir.equals(Direction.South))
         {
            return South;
         }
         if (dir.equals(Direction.West))
         {
            return West;
         }
         if (dir.equals(Direction.East))
         {
            return East;
         }
         return Directionless;
      }

      public static Direction getDirection(Direction2 dir)
      {
         if (dir.equals(North))
         {
            return Direction.North;
         }
         if (dir.equals(South))
         {
            return Direction.South;
         }
         if (dir.equals(West))
         {
            return Direction.West;
         }
         if (dir.equals(East))
         {
            return Direction.East;
         }
         return null;
      }

      public static boolean containsDirection(int data, Direction2 dir)
      {
         if ( (data & dir.getIndex()) != 0)
         {
            return true;
         }
         else
         {
            return false;
         }
      }
   }

}
TOP

Related Classes of maze.ai.ModifiedFloodfill

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.