Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Note: program might malfunction if any of heading/direction valeus will be equal to -1
- import uk.ac.warwick.dcs.maze.logic.IRobot;
- import java.util.*;
- public class GrandFinale
- {
- //Variables
- private int pollRun = 0; // how many steps are made
- private List<Integer> allHeadings;
- public void controlRobot(IRobot robot)
- {
- List<Integer> pExits = new ArrayList<Integer>(); // passage exits
- List<Integer> nwExits = new ArrayList<Integer>(); // non-wall exits
- // If robot's first time in the maze
- if (robot.getRuns() == 0)
- {
- // If it's the first step of the current run
- if (pollRun == 0)
- {
- allHeadings = new ArrayList<Integer>();
- }
- findExits(robot, pExits, nwExits); // find all current exits (passage and nonwall exits)
- if (pExits.size() == 0)
- {
- backtrackControl(robot, pExits, nwExits);
- }
- else
- {
- exploreControl(robot, pExits, nwExits);
- }
- }
- else
- robot.setHeading(allHeadings.get(pollRun));
- pollRun++;
- }
- public void reset()
- {
- pollRun = 0;
- }
- //---------------------
- // Controller methods
- //---------------------
- /* Method controls the robot under exploring rules:
- * 1. Never go back in corridor.
- * 2. If in not-visited junction select random passage, if not present - random nonwall exit.
- * 3. If in visited junction or deadend switch to backtrack controller
- * Methods gets IRobot object
- * Method faces the robot to the direction, does not return anything
- */
- private void exploreControl(IRobot robot, List<Integer> pExits, List<Integer> nwExits)
- {
- // If deadend
- if (nwExits.size() == 1)
- {
- // If it's not the first step
- if (pollRun != 0)
- {
- robot.face(universalDeadend(robot));
- }
- else
- {
- robot.face(exploreJunction(robot, pExits, nwExits));
- }
- }
- else
- // If corridor
- if (nwExits.size() == 2)
- {
- robot.face(universalCorridor(robot));
- }
- // If junction/crossroad
- else
- {
- robot.face(exploreJunction(robot, pExits, nwExits));
- }
- allHeadings.add(robot.getHeading());
- }
- /* Method controls robot under backtracking rules:
- * 1. If it's a deadend - turn around.
- * 2. Never go back in a corridor
- * 3. If it's a junction: pick random passage exit, if not present, go back to the direction, from which robot first came to that junction
- * Method gets IRobot object
- * Method faces the robot to the direction, does not return anything
- */
- private void backtrackControl(IRobot robot, List<Integer> pExits, List<Integer> nwExits)
- {
- robot.setHeading(reverseHeading(robot, allHeadings.get(allHeadings.size() - 1)));
- allH
- }
- //---------------------
- // Other methods
- //---------------------
- /* Method checks if given direction is a wall
- * Method gets a IRobot object and a direction (int value)
- * Method returns true if it's wall, false otherwise
- */
- private boolean isWall(IRobot robot, int direction)
- {
- return robot.look(direction) == IRobot.WALL;
- }
- /* Method checks if given direction is a passage
- * Method gets a IRobot object and a direction (int value)
- * Method returns true if it's passage, false otherwise
- */
- private boolean isPassage(IRobot robot, int direction)
- {
- return robot.look(direction) == IRobot.PASSAGE;
- }
- /* Method reverses heading
- * Method gets IRobot object and heading to be reversed
- * Method returns reversed heading (int value)
- */
- private int reverseHeading(IRobot robot, int h)
- {
- boolean isIncrease = false; // do you need to +2 to reverse the heading or -2
- for (int i = IRobot.NORTH; i <= IRobot.WEST; i++)
- {
- if (h + 2 == i)
- isIncrease = true;
- }
- if (isIncrease)
- return h + 2;
- else
- return h - 2;
- }
- /* Method finds all the nonwall and passage exits (and their directions)
- * Methods gets an IRobot object
- * Methods does not return, however it changes value of pExits and nwExits (passage exits and nonwall exits))
- */
- private void findExits(IRobot robot, List<Integer> pExits, List<Integer> nwExits)
- {
- for(int i = IRobot.AHEAD; i <= IRobot.LEFT; i++)
- {
- if (!isWall(robot, i))
- {
- nwExits.add(i);
- if (isPassage(robot, i))
- {
- pExits.add(i);
- }
- }
- }
- }
- /* Picks random direction value from exits list
- * Method gets List<int> object
- * Method returns random value from the List
- */
- private int pickRandom(List<Integer> A)
- {
- Random rand = new Random();
- return A.get(rand.nextInt(A.size()));
- }
- // Actually deadend can be run by exploreJunction method, that way there would not be need to include special case for robot's first step
- /* Method finds a direction when ANY robot is at deadend
- * Methods gets a IRobot object
- * Methods returns direction for robot to go (int value)
- */
- private int universalDeadend(IRobot robot)
- {
- return IRobot.BEHIND;
- }
- /* Method finds a direction when ANY robot is at corridor (either straight path or corner)
- * Methods gets a IRobot object
- * Methods returns direction for robot to go (int value)
- */
- private int universalCorridor(IRobot robot)
- {
- for (int i = IRobot.AHEAD; i <= IRobot.LEFT; i++)
- {
- if ((!isWall(robot, i)) && (i != IRobot.BEHIND))
- return i;
- }
- // If something goes wrong
- return -1;
- }
- /* Method finds direction that suits the Explorer conditions the best:
- * 1. Pick random passage if present.
- * 2. Pick random non wall exit.
- * Method gets IRobot objeect
- * Method returns direction for robot to go (int value)
- */
- private int exploreJunction(IRobot robot, List<Integer> pExits, List<Integer> nwExits)
- {
- if(pExits.size() != 0)
- {
- return pickRandom(pExits);
- }
- else
- {
- return pickRandom(nwExits);
- }
- }
- }
Add Comment
Please, Sign In to add comment