Jennifer
Jennifer

Reputation: 115

Method doesn't go through 2d array


I am doing a method that goes through a 2d array like a maze and the goal is to reach the position containing the integer 0. I am able to document the path, but it won't move, it stays at the initial position.
Here is an example of what I mean by doesn't move:

Please input the size of the board (between 5 and 20):
5
Please choose a starting index from the 4 options below:
    Press 1 for "top-left"
    Press 2 for "top-right"
    Press 3 for "bottom-left"
    Press 4 for "bottom-rigth"
Enter your choice:
1
2   1   1   1   4   
2   3   4   1   3   
1   1   1   2   4   
3   0   3   3   2   
3   2   3   4   2   
Move south 2, Move north 2, Move east 2, Move west 2, 

Can someone help me please?
Here is my method so far:

public static boolean MagicBoard_recursive(int[][] board, int size, int startRow, int startCol) {
        boolean solvable = true;
        int number = board[startRow][startCol];

        int[] moves = {startRow+number, startRow-number, startCol+number, startCol-number}; // This array contains all the possible moves we can do
        
        
        for(int i = 0; i < 4; i++) {
            // If we reached the position containing the integer 0
            if(board[startRow][startCol] == 0) {
                solvable = true;
                break;
            }
            if(startRow+number > size && startRow-number < 0 && startCol+number > size && startCol-number<0) {
                solvable = false;
                break;
            }
            solvable = true;
            // If we try moving south
            if(i == 0) {
                //int destinationNumber = board[startRow+number][startCol];
                // If we move to this position, will we be able to continue, if not, then we try another move
                if(startRow+number > size) {
                    solvable = false;
                    continue;
                }
                else {
                    while(solvable) {
                        startRow +=number;
                        System.out.print("Move south " + number + ", ");
                        MagicBoard_recursive(board, size, startRow, startCol);
                    }
                }
            }
            
            // If try moving north
            else if(i == 1) {
                // If we move to this position, will we be able to continue. If not, then we try another move
                if(startRow-number < 0) {
                    solvable = false;
                    continue;
                }
                else {
                    while(solvable) {
                        startRow -=number;
                        System.out.print("Move south " + number + ", ");
                        MagicBoard_recursive(board, size, startRow, startCol);
                    }
                }
            }
            
            // If try moving east
            else if(i == 2) {
                if(startCol+number > size) {
                    solvable = false;
                    continue;
                }
                else {
                    while(solvable) {
                        startCol += number;
                        System.out.print("Move east " + number + ", ");
                        MagicBoard_recursive(board, size, startRow, startCol);
                    }
                }
            }
            
            // If try moving west
            else if(i == 3) {
                if(startCol-number < 0) {
                    solvable = false;
                    break;
                }
                else {
                    while(solvable) {
                        startCol -=number;
                        System.out.print("Move west " + number + ", ");
                        MagicBoard_recursive(board, size, startRow, startCol);
                    }
                }
            }
        }
        return solvable;
    }

Here is a picture that shows an example of the movement that the program would do to solve a board:

enter image description here enter image description here

Upvotes: 0

Views: 64

Answers (1)

Omar Abdel Bari
Omar Abdel Bari

Reputation: 964

I think the approach you are taking is more difficult than it needs to be.

Consider instead of a int[][] array representing the board use something like Tile[][] where Tile is a class containing the following properties.

public class Tile {
    boolean visited;
    int value; //Maybe short will suffice instead?
}

The point of the visited property is to ensure you don't repeatedly test reachable tiles that you already visited before, as in a breadth-first or depth-first search.

Then you might have a class that makes use of a Queue. It's been a while for me and Java but a candidate seems like ArrayDeque for this situation (due to it's resizability). In the class containing your method you would add this as a member.

ArrayDeque<TileCoordinate> tilesToVisit = new ArrayDeque<>();

The TileCoordinate object is simply a class containing the coordinates for your object. You can instead put the coordinate directly into Tile if you wish to but I prefer to keep them separate.

public class TileCoordinate
{
    public int x;
    public int y;

    public TileCoordinate(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Then here's how this can help simplify your problem. When the user first chooses the starting corner you instead insert the coordinate into your queue rather than processing it directly. Following that you can create a loop which visits any coordinate that is in the queue.

//Get input regarding starting corner from user then,
tilesToVisit.add(new TileCoordinate(x, y)); //Insert coordinate corner into queue

while (!tilesToVisit.isEmpty && solvable == false) {
    TileCoordinate tileToVisit = tilesToVisit.removeFirst();
        
    Visit(tileToVisit); //This is where your business logic happens
}

//If loop is completed before solvable is set to true, this means it's not solvable

Then in your process method you would want to apply your movement logic to determine what else to visit in your queue.

public static void Visit(TileCoordinate coord) {
    Tile tile = board[coord.x, coord.y];
    tile.visited = true; //Make sure you do this first so you don't process this again later!
    
    if (tile.value == 0) {
        //mark solvable to true, which would be a class state variable
    }
    
    //Foreach tile that is reachable from this tile where visited = false, add into your queue 'unvisitedReachableTileCoordinate'
    tilesToVisit.Add(unvisitedReachableTileCoordinate);
}

I apologize I haven't coded Java in a while and my netbeans setup is messed up. However I did lookup many of these functions in oracle documentation so it should generally work. This should give you the general idea of this approach.

Upvotes: 1

Related Questions