Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pathfinder #3

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@

<groupId>io.github.ace-lectures.2aa4</groupId>
<!-- Replace this with your MacId. E.g., mine would be a1-mossers -->
<artifactId>a1-STUDENT_MAC_ID_GOES_HERE</artifactId>
<artifactId>a1-qadirq</artifactId>
<version>1.0</version>
<name>McMaster :: SFWRENG :: 2AA4 :: Maze Runner</name>

@@ -25,7 +25,7 @@
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.6.0</version>
<version>1.5.0</version>
</dependency>
<!-- To support Logging through Log4J-->
<dependency>
25 changes: 25 additions & 0 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/Direction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ca.mcmaster.se2aa4.mazerunner;

public enum Direction {
North, South, East, West;

public Direction turnRight(){
switch(this) {
case North: return Direction.East;
case East: return Direction.South;
case South: return Direction.West;
case West: return Direction.North;
default: return null;
}
}

public Direction turnLeft(){
switch(this) {
case North: return Direction.West;
case East: return Direction.North;
case South: return Direction.East;
case West: return Direction.South;
default: return null;
}
}
}
69 changes: 53 additions & 16 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/Main.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

package ca.mcmaster.se2aa4.mazerunner;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import org.apache.commons.cli.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@@ -11,26 +13,61 @@ public class Main {
private static final Logger logger = LogManager.getLogger();

public static void main(String[] args) {
System.out.println("** Starting Maze Runner");
logger.info("** Starting Maze Runner");

Options options = new Options();
options.addOption("i", "input",true, "Path to maze.txt file ");
options.addOption("p", "input", true, "User potential solution for maze ");

CommandLineParser parser = new DefaultParser();
CommandLine cmd;

try {
System.out.println("**** Reading the maze from file " + args[0]);
BufferedReader reader = new BufferedReader(new FileReader(args[0]));
String line;
while ((line = reader.readLine()) != null) {
for (int idx = 0; idx < line.length(); idx++) {
if (line.charAt(idx) == '#') {
System.out.print("WALL ");
} else if (line.charAt(idx) == ' ') {
System.out.print("PASS ");
}

cmd = parser.parse(options, args);

if (!cmd.hasOption("i")) {
logger.error("No maze file path, use -i to select specific maze");
return;
}

String mazefilepath = cmd.getOptionValue("i");

Maze maze = new Maze(mazefilepath); //------<<<<<< >>>>>>>>>> used to creat the ADS

if (cmd.getOptionValue("p")!= null){

PathFinder path = new PathFinder(maze);
String userSolution = cmd.getOptionValue("p");
Boolean validPath = path.validate(userSolution);
//user solution will be condensced ?

if(validPath) {
System.out.println("This is a correct path solution to this maze");
}
System.out.print(System.lineSeparator());
else {
System.out.println("This is an incorrect path solution to this maze");
}

}
else {
// solve the maze ?
logger.info("Finding valid solution for the maze path");
PathFinder path = new PathFinder(maze);
// pass in the maze object that can be used to find the path
String solution = path.findSolution();
System.out.println("This is the solution to the maze: ");
// will need to implement this solution

}

} catch(ParseException e) {
logger.error("Failed to find file path");
} catch(Exception e) {
System.err.println("/!\\ An error has occured /!\\");
logger.error("/!\\ An error has occured /!\\");
}
System.out.println("**** Computing path");
System.out.println("PATH NOT COMPUTED");
System.out.println("** End of MazeRunner");
logger.info("**** Computing path");
logger.info("PATH NOT COMPUTED");
logger.info("** End of MazeRunner");
}
}
117 changes: 117 additions & 0 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/Maze.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

package ca.mcmaster.se2aa4.mazerunner;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import java.io.IOException;
import org.apache.commons.cli.*;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;
import java.util.ArrayList;



public class Maze {

private static final Logger logger = LogManager.getLogger(Maze.class);

private List<List<Boolean>> maze = new ArrayList<>();

public Maze(String filepath) {

try (BufferedReader reader = new BufferedReader(new FileReader (filepath))){
String line;

while((line = reader.readLine()) != null ) {

List<Boolean> newRow = new ArrayList<>();

for (int idx = 0; idx < line.length(); idx++) {

if (line.charAt(idx) == '#') {

newRow.add(false);

}else if (line.charAt(idx) == ' '){

newRow.add(true);
}
else {
newRow.add(false);
}
}

maze.add(newRow);
}
} catch(IOException e) {
logger.error("Error reading file", e);
}

}

public int getRows(){
return maze.size();
}

public int getCols() {
if (maze.isEmpty()) {
return 0;
}
return maze.get(0).size();
}

public int[] mazeStartPosition() {
int[] startPosition = new int[2];
if (this.getRows() == 0 ) {
logger.error("Maze is empty");
}

startPosition[1] = 0;

for ( int row = 0; row < this.getRows(); row++) {
List<Boolean> currentRow = maze.get(row);
if (currentRow.get(0)) {
startPosition[0] = row;
return startPosition;
}
else{
continue;
}
}

logger.info("No entry point on the west side of the maze");
logger.info("Invalid Maze path");
return null;
}

public int[] mazeExitPosition() {
int [] exitPosition = new int[2];

exitPosition[1] = this.getCols() - 1;

for ( int row = 0; row < this.getRows(); row++) {
List<Boolean> currentRow = this.maze.get(row);
if (currentRow.get(this.getCols()-1)){
exitPosition[0] = row;
return exitPosition;
}
else {
continue;
}
}
logger.info("No exit point on th east side of the maze ");
logger.info("Invalid Maze path");
return null;
}

public List<List<Boolean>> getMaze() {

return this.maze;

}

}
90 changes: 90 additions & 0 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/PathFinder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package ca.mcmaster.se2aa4.mazerunner;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
import org.apache.commons.cli.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;
import java.util.ArrayList;

public class PathFinder {

private static final Logger logger = LogManager.getLogger(PathFinder.class);

private Maze maze;
private Player player;
private String userSolution;
private Tile currTile;


private StringBuilder solution = new StringBuilder();


public PathFinder(Maze maze) {
this.maze = maze.getMaze();
player = new Player(maze.mazeStartPosition());
currTile = new Tile(maze.mazeStartPosition(), this.maze);
}

public String findSolution() {
logger.info("Finding Valid solution");
// have a way to parse through the maze and append to solutionPath list.
// need to implement the logic to find the solution

while (!hasReachedEnd()) {
if(this.canMoveForward()){
player.moveForward();
this.solution.append("F");
}
}

return this.solution;
}

public boolean validate(String userSolution) {
// user soliution will be condensed, need to expand it, how ?

this.userSolution = userSolution;
this.solution = this.findSolution();

if (this.userSolution.equals(this.solution)) {
return true;
}
else {
return false;
}
}

public boolean hasReachedEnd() {
// check if the player has reached the end of the maze
if(player.getPosition() == maze.mazeExitPosition()) {
return true;
}
return false;
}

/*
only need to check if it can move forward, if it can't
then rotate,
and then check again can it move forward
*/


public boolean canMoveForward(){
// checks if the next step is a wall need to know the diretion is facing
if(tile.isWall(player.getPosition()), player.getDirection()) {
return false;
}
else{
return true;
}

}




}
65 changes: 65 additions & 0 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ca.mcmaster.se2aa4.assignment1;

public class Player {

private int row;
private int col;
private Direction currDir = Direction.East; // always start off facing east


public Player(int[] startPos) {
this.row = startPos[0];
this.col = startPos[1];
}

public void moveFoward(){
switch(this.currDir) {

case North:
this.row--;
break;
case South:
this.row++;
break;
case East:
this.col++;
break;
case West:
this.col--;
break;
}

}

public void turnRight() {
switch(this.currDir){
case North:
this.currDir = Directoin.East;
break;
case South:
this.currDir = Direction.West;
break;
case East:
this.currDir = Direction.South;
break;
case West:
this.currDir = Direction.North;
break;

}

}

public void turnLeft(){

}

public int[] getPosition() {
return new int[] {this.row, this.col};
}

//returns the direction the player is facing
public Direction getDirection() {
return this.currDir;
}
}
55 changes: 55 additions & 0 deletions src/main/java/ca/mcmaster/se2aa4/mazerunner/Tile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package ca.mcmaster.se2aa4.mazerunner;



public class Tile {

private boolean isWall;
private Maze maze;
private row;
private col;

public Tile(int[] currPos, Maze maze) {
this.isWall = false; //because the very first tile will be the start Pos

this.row = currPos[0];
this.col = currPos[1];

this.maze = maze;

}

public boolean isWall(int[] currPos, Direction currDir ) {

switch(currDir){
case North:
if (this.getTile(currPos[0] - 1, currPos[1]) == false) {
this.isWall = true;
}
break;
case South:
if (this.getTile(currPos[0] + 1, currPos[1]) == false) {
this.isWall = true;
}
break;
case East:
if (this.getTile(currPos[0], currPos[1] + 1) == false) {
this.isWall = true;
}
break;
case West:
if (this.getTile(currPos[0], currPos[1] - 1) == false) {
this.isWall = true;
}
break;
}


return this.isWall;
}

public boolean getTile(int row, int col){
return this.maze.get(row).get(col);
}

}