Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

java programming.OOP F. (Extra Credit) Write a program to simulate varying behav

ID: 3730896 • Letter: J

Question

java programming.OOP

F. (Extra Credit) Write a program to simulate varying behaviors for robots. The robots are trying to escape a maze, such as the following: k 2ak A robot has a position and a method void(Maze m) that modifies the position. Provide a common superclass Robot whose move method does nothing. Provide subclasses RandomRobot, RightHandRuleRobot, and MemoryRobot. Each of these robots has a different strategy for escaping. The RandomRobot simply makes random moves. The RightHandRobot moves around the maze so that it's right hand always touches a wall. The MemoryRobot remembers all positions that it has previously ocupied and never goes back to a position that it know to be dead end.

Explanation / Answer

import java.io.File;
import java.io.FileReader;

public class RobotRace {

    public static void main(String[] args) {
        if (args.length == 1) {
            try {
                int stepCounterRightHandRobot = 0;
                int stepCounterMemoryRobot = 0;
                boolean didRobbieFindTheGoal = true;
                File file = new File(args[0]);
                FileReader stream = new FileReader(file);
                Maze maze=new Maze(stream);

                RightHandRuleRobot robbie = new RightHandRuleRobot(maze);
                MemoryRobot bobbie = new MemoryRobot(maze);


                //The robots conducts the race one at a time!
                while (!robbie.hasReachedGoal() && didRobbieFindTheGoal) {

                    try {
                        robbie.move();
                    } catch (Exception e) {
                        System.err.println(e);
                        didRobbieFindTheGoal = false;
                    }
                    stepCounterRightHandRobot++;
                }

                while(!bobbie.hasReachedGoal()){
                    try {
                        bobbie.move();
                    }
                    catch(Exception e){
                        System.err.println(e);
                    }
                    stepCounterMemoryRobot++;

                }

                System.out.println("Steps for MemoryRobot robot: " +
                        stepCounterMemoryRobot);
                System.out.println("Steps for RightHandRuleRobot: " +
                        stepCounterRightHandRobot);

                if (stepCounterMemoryRobot < stepCounterRightHandRobot ||
                        !didRobbieFindTheGoal){
                    System.out.println(" MemoryRobot WON!!");
                }
                else if (stepCounterMemoryRobot > stepCounterRightHandRobot){
                    System.out.println(" RightHandRuleRobot WON!!");
                }
                else {
                    System.out.println("It is a TIE!");
                }


            } catch (Exception e) {
                System.err.println(e);
            }

        }
        else{
            System.err.println("Invalid program parameters.");
        }

    }
}
--------------------------------------------------------------------------------------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

public class Maze {

    private char[][] maze;
    private Position start;


    public Maze(java.io.Reader file) throws IOException{

        BufferedReader buffer = new BufferedReader(file);
        Queue<String> queue = new LinkedList<String>();
        String line;
        int lineNr = 0;
        int lineSize = 0;
        int i;

        int lineIndex = 0;
        int startExist = 0;
        boolean goalExist = false;

        // Read the file and stores each line in an queue.
        while((line = buffer.readLine()) != null){
            if (lineSize < line.length()){
                lineSize = line.length();
            }
            queue.add(line);
            lineNr++;
        }

        maze = new char[lineNr][lineSize];

        // Merging the lines from the file to the maze array.
        while ((line = queue.poll()) != null){
            i = 0;

            while (i < lineSize){
                if (i < line.length()) {
                    maze[lineIndex][i] = line.charAt(i);
                }
                else{
                    maze[lineIndex][i] = '*';
                }
                i++;

            }
            lineIndex++;
        }

        // Controls and checks that start and goal position exist in the maze.
        for (int y = 0; y <lineNr; y++){
            for (int x = 0; x < lineSize; x++){
                if (maze[y][x] == 'G'){
                    goalExist = true;
                }
                if (maze[y][x] == 'S'){

                    this.start = new Position(x,y);
                    startExist++;
                }
            }
        }


        //Control that maze only contained one start and at least one goal.
        if( startExist == 0 || startExist > 1 || !goalExist){
            throw new IOException("Invalid Maze on file");
        }
    }

    public boolean isMovable(Position p){

        try {
            if (maze[p.getY()][p.getX()] == ' ' ||
                    maze[p.getY()][p.getX()] == 'G'
                    || maze[p.getY()][p.getX()] == 'S') {
                return true;
            }

        } catch (ArrayIndexOutOfBoundsException e){
            return false;
        }
        return false;

    }

    public boolean isGoal(Position p){
        try {
            if (maze[p.getY()][p.getX()] == 'G') {
                return true;
            }
        } catch(ArrayIndexOutOfBoundsException e){
            return false;
        }
        return false;

    }

    public Position getStartPosition(){
        return this.start;
    }
}
-------------------------------------------------------------------------------------------------------------
import java.util.EmptyStackException;
import java.util.Hashtable;
import java.util.Stack;


public class MemoryRobot extends Robot {

    private Stack<Position> positionStack;
    private Hashtable<String, Integer> wayTracker;


    // Constructor for MemoryRobot.

    public MemoryRobot(Maze maze) throws IllegalStateException {
        super(maze);
        positionStack = new Stack<Position>();
        wayTracker = new Hashtable<>();
        super.setCurrentPosition(maze.getStartPosition());
        if (checkIfTrapped()){
            throw new IllegalStateException("Error: Robot is boxed in!");
        }
    }

    @Override
    public void move() throws IllegalStateException{

        Position p = getCurrentPosition();

        //Checks what possible ways the robot can go.
        boolean movableEast = maze.isMovable(p.getPosToEast());
        boolean movableSouth = maze.isMovable(p.getPosToSouth());
        boolean movableNorth = maze.isMovable(p.getPosToNorth());
        boolean movableWest = maze.isMovable(p.getPosToWest());

        //If way movable and not visited push position to stack
        // and move robot depending on direction.
        if (movableEast && !isVisited(p.getPosToEast())) {
            positionStack.push(p);
            setCurrentPosition(p.getPosToEast());
        }
        else if (movableSouth && !isVisited(p.getPosToSouth())) {
            positionStack.push(p);
            setCurrentPosition(p.getPosToSouth());
        }
        else if (movableNorth && !isVisited(p.getPosToNorth())) {
            positionStack.push(p);
            setCurrentPosition(p.getPosToNorth());
        }
        else if (movableWest && !isVisited(p.getPosToWest())) {
            positionStack.push(p);
            setCurrentPosition(p.getPosToWest());

        }
        else {
            try {
                setCurrentPosition(positionStack.pop());
            } catch (EmptyStackException e) {
                throw new IllegalStateException("Error: Robot could not find the goal");
            }

        }
        //Mark the recent position as visited by adding it to the hash table.
        addPositiontoHashTable(p);

    }

    private boolean isVisited(Position p) {
        if (wayTracker.containsKey(p.getX() + " " + p.getY())) {
            return true;
        }
        return false;
    }


    private void addPositiontoHashTable(Position p) {

        if (!wayTracker.containsKey(p.getX() + " " + p.getY())) {
            wayTracker.put(p.getX() + " " + p.getY(), 1);
        }
    }

}
------------------------------------------------------------------------------------------------
public class Position {

    private int y;
    private int x;


    public Position(int x, int y){

        this.y = y;
        this.x = x;
    }

    // Getter that returns X position

    public int getX(){
        return this.x;
    }

    // Getter that returns Y position

    public int getY(){
        return this.y;
    }

    //Method that returns the position to the south of current position.

    public Position getPosToSouth(){
        return new Position(this.x, this.y+1);
    }

    // Method that returns the position to the north of current position.

    public Position getPosToNorth(){
        return new Position(this.x, this.y-1);
    }

    //Method that returns the position to the west of current position.

    public Position getPosToWest(){
        return new Position(this.x-1, this.y);
    }
    // Method that returns the position to the east of current position.

    public Position getPosToEast(){
        return new Position(this.x+1, this.y);
    }


    //Method that can be used to compare two objects

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Position position = (Position) o;

        if (y != position.y) return false;
        return x == position.x;

    }

    //Creates a hashcode for the object

    @Override
    public int hashCode() {
        int result = y;
        result = 31 * result + x;
        return result;
    }
}
------------------------------------------------------------------------------------------------------------------

public class RightHandRuleRobot extends Robot {
    private int facingP;


    public RightHandRuleRobot(Maze maze) throws IllegalStateException{
        super(maze);

        super.setCurrentPosition(maze.getStartPosition());

        getFacingPosition(getCurrentPosition());

        if (checkIfTrapped()){
            throw new IllegalStateException("Error: Robot is boxed in!");
        }
    }


    @Override
    public void move() throws IllegalStateException{

        switch (facingP){

            case 1: facingEast();
                break;

            case 2: facingSouth();
                break;

            case 3: facingWest();
                break;

            case 4: facingNorth();
                break;

            default:
                throw new IllegalStateException("Invalid maze: " +
                        "No walls around the robot!");

        }
        // If Robot came back to start position, it is unable to find the goal.
        if (maze.getStartPosition().equals(getCurrentPosition())){
            throw new IllegalStateException("Robot could not find a goal!");
        }


    }


    /**
     * Make the robot move if it is facing east
     */
    private void facingEast(){
        Position p = getCurrentPosition();
        boolean movableEast = maze.isMovable(p.getPosToEast());
        boolean movableSouth = maze.isMovable(p.getPosToSouth());
        boolean movableNorth = maze.isMovable(p.getPosToNorth());

        if (!movableSouth && !movableEast && movableNorth){
            setCurrentPosition(p.getPosToNorth());
            facingP = 4;
        }
        else if (movableEast && !movableSouth) {
            setCurrentPosition(p.getPosToEast());
        }
        else if (movableSouth){
            setCurrentPosition(p.getPosToSouth());
            facingP = 2;
        }
        else {
            setCurrentPosition(p.getPosToWest());
            facingP = 3;
        }
    }

    /**
     * Make the robot move if it is facing north
     */
    private void facingNorth(){
        Position p = getCurrentPosition();
        boolean movableEast = maze.isMovable(p.getPosToEast());
        boolean movableWest = maze.isMovable(p.getPosToWest());
        boolean movableNorth = maze.isMovable(p.getPosToNorth());

        if (!movableNorth && !movableEast && movableWest){
            setCurrentPosition(p.getPosToWest());
            facingP = 3;
        }
        else if (movableNorth && !movableEast) {
            setCurrentPosition(p.getPosToNorth());
        }
        else if (movableEast){
            setCurrentPosition(p.getPosToEast());
            facingP = 1;
        }
        else {
            setCurrentPosition(p.getPosToSouth());
            facingP = 2;
        }
    }

    /**
     * Make the robot move if it is facing west
     */
    private void facingWest(){
        Position p = getCurrentPosition();
        boolean movableSouth = maze.isMovable(p.getPosToSouth());
        boolean movableWest = maze.isMovable(p.getPosToWest());
        boolean movableNorth = maze.isMovable(p.getPosToNorth());

        if (!movableNorth && !movableWest && movableSouth){
            setCurrentPosition(p.getPosToSouth());
            facingP = 2;
        }
        else if (movableWest && !movableNorth) {
            setCurrentPosition(p.getPosToWest());
        }
        else if (movableNorth){
            setCurrentPosition(p.getPosToNorth());
            facingP = 4;
        }
        else {
            setCurrentPosition(p.getPosToEast());
            facingP = 1;
        }


    }

    /**
     * Make the robot move if it is facing south
     */
    private void facingSouth(){
        Position p = getCurrentPosition();
        boolean movableEast = maze.isMovable(p.getPosToEast());
        boolean movableSouth = maze.isMovable(p.getPosToSouth());
        boolean movableWest = maze.isMovable(p.getPosToWest());

        if (!movableWest && !movableSouth && movableEast){
            setCurrentPosition(p.getPosToEast());
            facingP = 1;
        }
        else if (movableSouth && !movableWest) {
            setCurrentPosition(p.getPosToSouth());
        }
        else if (movableWest){
            setCurrentPosition(p.getPosToWest());
            facingP = 3;
        }
        else {
            setCurrentPosition(p.getPosToNorth());
            facingP = 4;
        }


    }

    /**
     * Method that which position the robot face in the start
     */
    private void getFacingPosition(Position start){

        if (!maze.isMovable(start.getPosToWest())) {
            facingP = 2;
        }
        else if (!maze.isMovable(start.getPosToNorth())) {
            facingP = 3;
        }
        else if (!maze.isMovable(start.getPosToEast())) {
            facingP = 4;
        }
        else if (!maze.isMovable(start.getPosToSouth())) {
            facingP = 1;
        }
        else {
            facingP = 0;
        }
    }

}
-------------------------------------------------------------------------------------------------------
public abstract class Robot {

    private Position currentP;
    protected Maze maze;

    public Robot(Maze maze)throws IllegalStateException{
        this.maze = maze;

    }

    // Abstract method for moving the robot.


    public abstract void move() throws IllegalStateException;

    //Returns the current position of the robot.

    public Position getCurrentPosition(){
        return this.currentP;
    }

    // Allows the user to set the position of the robot.

    protected void setCurrentPosition(Position p){
        this.currentP = p;

    }

    // Checks if robot has reached the goal.

    public boolean hasReachedGoal(){
        return maze.isGoal(currentP);
    }

    // Function is used to check if Robot is trapped/boxed in.

    protected boolean checkIfTrapped(){
        if( !maze.isMovable(currentP.getPosToSouth()) &&
                !maze.isMovable(currentP.getPosToNorth()) &&
                !maze.isMovable(currentP.getPosToWest()) &&
                !maze.isMovable(currentP.getPosToEast())){
            return true;
        }
        return false;
    }

}