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;
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.