The program is using backtracking to find out a way out of the maze(which it does fine). The problem occurs when I try to print out the correct path I took.
This is my solveMaze() method.
boolean result = false;
while(result==false){
if((row > 29) || (row < 0) || (col > 19) || (col < 0)) //check if position is within the array
return false;
if(maze[row][col].getVar().equals("E")) // check if youre at the exit
return true;
if(maze[row][col].getVar().equals("1")) // check if youre hitting a wall
return false;
if(maze[row][col].position.size() > 2){ // check if youre at an intersection
intersection[numIntersection] = maze[row][col]; // add intersection to intersection array
numIntersection++;
}
//this section does not need to be checked if youve never visited the position before
if(maze[row][col].getVisted() == true && numIntersection > 0){
if(intersection[numIntersection-1] == null)
return false;
else if(intersection[numIntersection-1] != null){ //as you backtrack to the last intersection pick up your "markers"
maze[row][col].setVar("0");
if(maze[row][col].position == intersection[numIntersection-1].position && intersection[numIntersection-1].getVisted()==true){ //remove intersection from the array as you pass back thru
maze[row][col].setVar("+");
intersection[numIntersection-1] = null;
numIntersection--;
}
}
}
if(maze[row][col].position.empty()==true) //check if the stack is empty
return false;
maze[row][col].position.pop();
if(maze[row][col].getVisted() == false)
maze[row][col].setVar("+"); //mark path as you land on unvisted positions
maze[row][col].setVisted(true);
//look north
if(solveMaze(row-1,col)== true)
return true;
//look east
if(solveMaze(row,col+1)== true){
return true;
}
//look west
if(solveMaze(row,col-1)== true){
return true;
}
//look south
if(solveMaze(row+1,col)== true){
return true;
}
}
return false;
}
As I backtrack I am picking back up my markers but it seems to be picking up markers on the correct path also and prints a maze with a broken up path.
Related
I have this method that solves the first possible path in a 2D maze matrix (works fine)
public boolean findFirstPath() {
boolean found = false;
path = new ArrayList<Coordinate>(); // restarts the path in case the algorithm has been solved previously
Coordinate coor = new Coordinate();
coor.i = startI; coor.j = startJ; coor.direction = 0; // instance of the first Coordinate object
path.add(coor); // the first coordinate is added to the path
while (!found && path.size() > 0) {
path.get(path.size()-1).direction++; // accesses the last element and increments the direction by 1
if (path.get(path.size()-1).direction <= 4) {
Coordinate coor_next = setNextCell(path.get(path.size()-1)); // we assign the last element of the path
if (isValidSpot(coor_next)) {
path.add(coor_next); // add to the path the valid cell
if (coor_next.i == endI && coor_next.j == endJ) { // if it reaches the end
found = true;
}
}
} else { // if it has checked all 4 directions go back
path.remove(path.size()-1); // deletes the last position in backtracking
}
}
return found;
}
I need to make modifications to find the shortest possible path and I can't find an optimal solution, I've tried something like this:
public boolean findShortestPath() {
boolean found = false;
int steps = 0;
path = new ArrayList<Coordinate>();
ArrayList<Coordinate> shortest = new ArrayList<Coordinate>(); // arrayList where the shortest path will be stored
Coordinate coor = new Coordinate();
coor.i = startI; coor.j = startJ; coor.direction = 0;
path.add(coor);
while (!found && path.size() > 0) {
path.get(path.size()-1).direction++;
if (path.get(path.size()-1).direction <= 4) {
Coordinate coor_next = setNextCell(path.get(path.size()-1));
if (isValidSpot(coor_next)) {
steps++;
if (steps < path.size()) {
shortest.add(path.get(path.size()-1));
} else {
path.add(coor_next);
}
if (coor_next.i == endI && coor_next.j == endJ) {
found = true;
}
}
} else {
path.remove(path.size()-1);
}
}
return found;
}
but it does not even enter the if (steps < path.size()) comprobation, any suggestions? Thanks.
In my method under the if statement:
if (currentLocationX == 0 && currentLocationY == 4)
I have a break statement that should make the program exit out of the while loop and return true for 'answer' and for the method. Yet after some testing it seems that after returning true for 'answer', it goes back into the while loop giving the wrong results int the end. Why is my break statement not doing what it's supposed to? Thank you!
P.S. (this method calls on some other method that were not relevant to mention here)
public boolean solveMaze()
{
boolean answer = false;
int currentLocationX;
int currentLocationY;
//push starting location
pushX(2);
pushY(1);
while((isEmptyX() == false) && (isEmptyY() == false))
{
printMaze();
System.out.println();
currentLocationX = popX();
currentLocationY = popY();
//mark current location as visited
visited(currentLocationX, currentLocationY, maze);
System.out.println("Current Location: " + currentLocationX + ", " + currentLocationY);
if (currentLocationX == 0 && currentLocationY == 4)
{
answer = true;
break;
}
else
{
//push all unvisited OPEN neighbor locations into stack
if (checkEast(currentLocationX, currentLocationY) == 0)
{
pushX(eastX(currentLocationX));
pushY(eastY(currentLocationY));
}
else;
if (checkSouth(currentLocationX, currentLocationY)== 0)
{
pushX(southX(currentLocationX));
pushY(southY(currentLocationY));
}
else;
if (checkWest(currentLocationX, currentLocationY)== 0)
{
pushX(westX(currentLocationX));
pushY(westY(currentLocationY));
}
else;
if (checkNorth(currentLocationX, currentLocationY)== 0)
{
pushX (northX(currentLocationX));
pushY(northY(currentLocationY));
}
else;
}
}
return answer;
}
I wrote out the basic logic of your method as
public static boolean solveMaze() {
boolean answer = false;
int currentLocationX = 0;
int currentLocationY = 4;
while (true) {
if (currentLocationX == 0 && currentLocationY == 4) {
System.out.println("Hit the break");
break;
} else {
System.out.println("Missed the break");
}
}
return answer;
}
and if you execute it you get Hit the break. So your solveMaze() method is fine in terms of breaking out of the loop once it satisfies your if-statement. I would say that if you see your code subsequently going back into the while loop, it must be that solveMaze() was called a second time.
New to the site and have not been coding long. I am trying to find a way to check to see if the entered value is withing the array range as well as checking to see if the position is already occupied. I am running into trouble if the problems are not in order. I would like for it to catch the problem in any order and request them to enter another value, then recheck again. Thanks for any advice!
This is what I ended up doing. Any thoughts? Thanks again.
//in play game method
while(checkNotInBounds(move)){
System.out.println("Out of Bounds! Please try again...");
move = getMove(player);
}
while(!checkSpaceFree(move, boardValues)){
System.out.println("Space Taken! Please try again...");
move = getMove(player);
while(checkNotInBounds(move)){
System.out.println("Out of Bounds! Please try again...");
move = getMove(player);
}
//Method: checkInBounds
//Purpose: find out if move is in bounds
public static boolean checkNotInBounds(int[] move){
if(move[0] > 2 || move[0] < 0 || move[1] > 2 || move[1] < 0){
return true;}
return false;
}
//Method: checkFreeSpace
//Purpose: find if space is free
public static boolean checkSpaceFree(int[] move, char[][]boardValues){
if(boardValues[move[0]][move[1]] == ' '){
return true;}
return false;
}
Why not split it up into two methods instead of one as your trying to do two things there and switching isn't neccary then
do something like
public static boolean checkLegalMove(int[] move, char[][] boardValues){
if(move[0] > 2 || move[0] < 0 || move[1] > 2 || move[1] < 0){
return false;
}
if(boardValues[move[0]][move[1]] != ' '){
return false;
}
return true;
}
public void doSomething(boolean checkLegalMove(move,boardValues), char player){
boolean check = checkLegalMove(move,boardValues);
char temp = player;
if(check ==true ){
//do something to player
}else{
getMove(player);
}
}
Hi I'm writing a checkers engine and defining a canEat(Point1,Point2) method for player class which returns true or false based on if player can eat eat the piece at the specified points by checking if the pieces and landing path is on board, if the two pieces belong to the same player or not and also considering the king/super status of piece.
Anyways it works pretty pleasantly without recursion, but without recursion method must get points of the pieces instead of the landing piece which is okay if I manage the recursion. But I want the method to also consider if it gets the landing point instead of piece location. When I run the code it fixes the location and calls itself again there is no problem with that but. I get NullPointerException on
caneat = Checker2.isAlive() ? true : false; because Checker2 is null. My pointToChecker method returns null on this guy so Checker2 is null. What is causing this I'm new to recursion, even OOP to be honest and
Here is my code and console error log
public boolean canEat(Point Piece, Point target)
{
//INITIALIZING
//POINT1 & CHECKER1-> piece which eats
//POINT2 & CHECKER2-> piece to eat
//POINT3 & CHECKER3-> landing path
if (samePoint(Piece, target))
return false;
boolean caneat = true;
boolean king1 = false;
Point Point1,Point2,Point3;
Checker Checker1,Checker2,Checker3;
int ownerID, victimID,axis;
axis = getDirection(Piece, target);
//CHECK IF PLAYER POINTED THE SQUARE AHEAD TARGET PIECE OR THE PIECE TO EAT
int distance = getStep(Piece, target);
if(distance == 2)
{
boolean resolution;
System.err.println("Recoordinated target");
Point fixed = getBackwards(target, axis);
System.err.println("Fixed is: " + Piece + " " + fixed);
resolution = canEat(Piece, fixed);
return resolution;
}
Point1 = Piece;
Point2 = target;
Point3 = findMovePosition(target, axis);
if(!inBoard(Point1) || !inBoard(Point2) || !inBoard(Point3))
{
System.err.println("Error: Invalid Move --> Thinking outside the box");
return false;
}
Checker1 = PointToPiece(Point1);
Checker2 = PointToPiece(Point2);
Checker3 = PointToPiece(Point3);
//CHECK IF PIECES ARE ALIVE
caneat = Checker1.isAlive() ? true : false;
caneat = Checker2.isAlive() ? true : false;
if(!Checker2.isAlive())
{
return false;
}
//THERE SHOULD BE TARGET AND VICTIM PIECES AND AN EMPTY LANDING POINT
if(!isOccupied(Piece))
{
System.err.println("#OccupyChecker invalid piece to move");
return false;
}
if(!isOccupiedbyEnemy(target))
{
System.err.println("#OccupyChecker invalid piece to eat");
return false;
}
if(!(Checker3 == null))
{
System.err.println("#OccupyChecker landing piece error");
return false;
}
ownerID = Checker1.getOwner().getID();
victimID = Checker2.getOwner().getID();
if(ownerID == victimID)
{
System.err.println("owner ID: " + ownerID + " victimID: " + victimID);
System.err.println("#OCCUPY identity");
return false;
}
if(ownerID == 1 && king1)
{
if(axis == 3 || axis == 4)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
if(ownerID == 2 && king1)
{
if(axis == 1 || axis == 2)
System.err.println("#OccupyPoint wrong axis");
caneat = false;
}
return caneat;
}
Checker PointToPiece(Point piece)
{
Checker[] allPieces = allPieces();
Checker found = null;
for(Checker k : allPieces)
{
if(samePoint(k.getPosition(), piece))
found = k;
}
return found;
}
I'm trying to create a program that arranges 6 cards on a grid in a specific way so that no card is adjacent to other cards of the same type (the types being king, queen and jack). The grid is 4x4 but I can only place cards inside the following pattern:
[ ][ ][x][ ]
[x][x][x][ ]
[ ][x][x][x]
[ ][ ][x][ ]
Now, my main problem is when my method tries to check the adjacent cells for card types. When it starts at 0,0 it tries to check [row-1][column] which obviously won't work since that translates to -1,0. The problem is, I have no idea how implement this properly.
I apologise if this question has been asked before, as I wasn't sure what to search for exactly (or how to properly name this problem).
private boolean bordersCard(int row, int column, char cardChar)
{
Candidate center = board[row][column];
Candidate top;
Candidate bottom;
Candidate left;
Candidate right;
if (board[row-1][column] != null){
top = board[row+1][column];
}
else
{
top = new Candidate('?', 0);
}
if (board[row+1][column] != null){
bottom = board[row+1][column];
}
else
{
bottom = new Candidate('?', 0);
}
if (board[row][column-1] != null){
left = board[row][column-1];
}
else
{
left = new Candidate('?', 0);
}
if (board[row][column+1] != null){
right = board[row][column+1];
}
else
{
right = new Candidate('?', 0);
}
if ((center.getCardChar() == top.getCardChar()) || (center.getCardChar() == bottom.getCardChar()) ||
(center.getCardChar() == left.getCardChar()) || (center.getCardChar() == right.getCardChar())){
return false;
}
return true;
}
You have to add if fences to prevent the invalid checks:
if (row > 0 && board[row-1][column] != null){
top = board[row+1][column];
}
If any of the indexes are out of bounds assign them to NULL. In Candidate create a method isSameType(Candidate other);
isSameType(Candidate other)
{
if(other == null)
return false;
else
retrun getCardChar() == other.getCardChar();
}
change your if to:
if(center.isSameType(top) || center.isSameType(bottom) || ...)
{
return false;
}
As you have determined, checking [-1][0] doesn't work. But you don't need to check that non-existent slot. Just make sure you don't run off the beginning or the end of the array. Also, make sure you are performing the same math operation inside your if as in your condition:
if ((row - 1) >= 0 && (row - 1) < board.length && board[row-1][column] != null){
top = board[row-1][column]; // Use -1 to match condition.
}