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

This assignment: Solve for a path through a Two-Dimensional maze by use of exhau

ID: 3839242 • Letter: T

Question

This assignment:
Solve for a path through a Two-Dimensional maze by use of exhaustive search andbacktracking.
Given a two-dimensional array like the one shown below, create a recursive Javaprogram that will traverse the array looking for a path from the upper left corner tothe lower right.


private int[][] grid = { {1,1,1,0,1,1,0,0,0,1,1,1,1},{1,0,1,1,1,0,1,1,1,1,0,0,1},      {0,0,0,0,1,0,1,0,1,0,1,0,0},      {1,1,1,0,1,1,1,0,1,0,1,1,1},      {1,0,1,0,0,0,0,1,1,1,0,0,1},      {1,0,1,1,1,1,1,1,0,1,1,1,1},      {1,0,0,0,0,0,0,0,0,0,0,0,0},      {1,1,1,1,1,1,1,1,1,1,1,1,1}};


Program specifications:
In the maze, values represented are:

- 1 – An available space for a path (an open ‘room’)- 0 – A ‘wall’- 3 – A visited room- 7 – A room on a successful path

Your program should:
Start in the upper left corner Attempt to move in a direction

- Check that the ‘room’ you want to move into is inside the maze- Check that the room you want to move to is available (not a wall)- Check that the room you want to move to has not been visitedpreviously

If the move is not valid try to move in another direction If the is valid, ‘move’ into the ‘room’ and mark it as ‘visited’ (3) If no valid move is available, unwind in your recursive call stack to the
previous call and try the next direction from there
Repeat until either you’ve reached the goal or you’ve determined that there

is no path through the maze.

Some suggestions:
Determine what the base cases will be Your recursive method should return a variable of type boolean. Your recursive method’s signature should accept two parameters only.

Do it in Java

Explanation / Answer


public class JavaMaze
{
public JavaMaze(int aDimension)
{

public JavaMaze(int aDimension, int bDimension)
{
dimensionA = aDimension;
dimensionB = bDimension;
gridDimensionX = xDimension * 4 + 1;
gridDimensionY = yDimension * 2 + 1;
grid = new char[gridDimensionA][gridDimensionB];
init();
generateMaze();
}

private void init()
{

cells = new Cell[dimensionA][dimensionB];
for (int a = 0; a < dimensionA; a++)
{
for (int y = 0; y < dimensionB; y++)
{
cells[a][b] = new Cell(a, b, false);
}
}
}
private class Cell
{
int x, y; // coordinates
  
ArrayList<Cell> neighbors = new ArrayList<>();

boolean visited = false;
  
Cell parent = null;

boolean inPath = false;
  
double travelled;
  
double projectedDist;

boolean wall = true;

boolean open = true;

Cell(int x, int y)
{
this(x, y, true);
}

Cell(int x, int y, boolean isWall)
{
{
// skip if outside, is a wall or is not opened
if (other==null || other.wall || !other.open) continue;
neighbors.add(other);
}
if (neighbors.isEmpty()) continue;
// get random cell
Cell selected = neighbors.get(random.nextInt(neighbors.size()));
// add as neighbor
selected.open = false; // indicate cell closed for generation
cell.addNeighbor(selected);
cells.add(cell);
cells.add(selected);
}
}
// used to get a Cell at x, y; returns null out of bounds
public Cell getCell(int x, int y) {
try {
return cells[x][y];
} catch (ArrayIndexOutOfBoundsException e) { // catch out of bounds
return null;
}
}

public void solve() {
// default solve top left to bottom right
this.solve(0, 0, dimensionX - 1, dimensionY -1);
}
// solve the maze starting from the start state (A-star algorithm)
public void solve(int startX, int startY, int endX, int endY) {
// re initialize cells for path finding
for (Cell[] cellrow : this.cells) {
for (Cell cell : cellrow) {
cell.parent = null;
cell.visited = false;
cell.inPath = false;
cell.travelled = 0;
cell.projectedDist = -1;
}
}
// cells still being considered
ArrayList<Cell> openCells = new ArrayList<>();
// cell being considered
Cell endCell = getCell(endX, endY);
if (endCell == null) return; // quit if end out of bounds
{ // anonymous block to delete start, because not used later
Cell start = getCell(startX, startY);
if (start == null) return; // quit if start out of bounds
start.projectedDist = getProjectedDistance(start, 0, endCell);
start.visited = true;
openCells.add(start);
}
boolean solving = true;
while (solving) {
if (openCells.isEmpty()) return; // quit, no path
// sort openCells according to least projected distance
Collections.sort(openCells, new Comparator<Cell>(){
@Override
public int compare(Cell cell1, Cell cell2) {
double diff = cell1.projectedDist - cell2.projectedDist;
if (diff > 0) return 1;
else if (diff < 0) return -1;
else return 0;
}
});
Cell current = openCells.remove(0); // pop cell least projectedDist
if (current == endCell) break; // at end
for (Cell neighbor : current.neighbors) {
double projDist = getProjectedDistance(neighbor,
current.travelled + 1, endCell);
if (!neighbor.visited || // not visited yet
projDist < neighbor.projectedDist) { // better path
neighbor.parent = current;
neighbor.visited = true;
neighbor.projectedDist = projDist;
neighbor.travelled = current.travelled + 1;
if (!openCells.contains(neighbor))
openCells.add(neighbor);
}
}
}
// create path from end to beginning
Cell backtracking = endCell;
backtracking.inPath = true;
while (backtracking.parent != null) {
backtracking = backtracking.parent;
backtracking.inPath = true;
}
}
// get the projected distance
// (A star algorithm consistent)
public double getProjectedDistance(Cell current, double travelled, Cell end) {
return travelled + Math.abs(current.x - end.x) +
Math.abs(current.y - current.x);
}

// draw the maze
public void updateGrid() {
char backChar = ' ', wallChar = 'X', cellChar = ' ', pathChar = '*';
// fill background
for (int x = 0; x < gridDimensionX; x ++) {
for (int y = 0; y < gridDimensionY; y ++) {
grid[x][y] = backChar;
}
}
// build walls
for (int x = 0; x < gridDimensionX; x ++) {
for (int y = 0; y < gridDimensionY; y ++) {
if (x % 4 == 0 || y % 2 == 0)
grid[x][y] = wallChar;
}
}
// make meaningful representation
for (int x = 0; x < dimensionX; x++) {
for (int y = 0; y < dimensionY; y++) {
Cell current = getCell(x, y);
int gridX = x * 4 + 2, gridY = y * 2 + 1;
if (current.inPath) {
grid[gridX][gridY] = pathChar;
if (current.isCellBelowNeighbor())
if (getCell(x, y + 1).inPath) {
grid[gridX][gridY + 1] = pathChar;
grid[gridX + 1][gridY + 1] = backChar;
grid[gridX - 1][gridY + 1] = backChar;
} else {
grid[gridX][gridY + 1] = cellChar;
grid[gridX + 1][gridY + 1] = backChar;
grid[gridX - 1][gridY + 1] = backChar;
}
if (current.isCellRightNeighbor())
if (getCell(x + 1, y).inPath) {
grid[gridX + 2][gridY] = pathChar;
grid[gridX + 1][gridY] = pathChar;
grid[gridX + 3][gridY] = pathChar;
} else {
grid[gridX + 2][gridY] = cellChar;
grid[gridX + 1][gridY] = cellChar;
grid[gridX + 3][gridY] = cellChar;
}
} else {
grid[gridX][gridY] = cellChar;
if (current.isCellBelowNeighbor()) {
grid[gridX][gridY + 1] = cellChar;
grid[gridX + 1][gridY + 1] = backChar;
grid[gridX - 1][gridY + 1] = backChar;
}
if (current.isCellRightNeighbor()) {
grid[gridX + 2][gridY] = cellChar;
grid[gridX + 1][gridY] = cellChar;
grid[gridX + 3][gridY] = cellChar;
}
}
}
}
}

// simply prints the map
public void draw() {
System.out.print(this);
}
// forms a meaningful representation
@Override
public String toString() {
updateGrid();
String output = "";
for (int y = 0; y < gridDimensionY; y++) {
for (int x = 0; x < gridDimensionX; x++) {
output += grid[x][y];
}
output += " ";
}
return output;
}

// run it
public static void main(String[] args) {
MyMaze maze = new MyMaze(20);
maze.solve();
maze.draw();
}
}