javachallenge-response

Java Bot saves Princess Challenge


Princess Peach is trapped in one of the four corners of a square grid. You are in the center of the grid and can move one step at a time in any of the four directions. Can you rescue the princess?

Input format

The first line contains an odd integer N (3 <= N < 100) denoting the size of the grid. This is followed by an NxN grid. Each cell is denoted by '-' (ascii value: 45). The bot position is denoted by 'm' and the princess position is denoted by 'p'.

Grid is indexed using Matrix Convention

Output format

Print out the moves you will take to rescue the princess in one go. The moves must be separated by '\n', a newline. The valid moves are LEFT or RIGHT or UP or DOWN.

Here is my code:

package challenges;

import java.util.*;

public class Solution {
static void displayPathtoPrincess(int n, int p,String [][] grid){
int botRow=0,botCol=0;

for(int r=0;r<n;r++){
   for (int c = 0; c < grid.length; c++) {
        if(grid[r][c].equals('m')) {
            botRow=r;
            botCol=c;
            continue;
        }
   }
        if(grid[0][0].equals('P')) {
            while(botRow>0) {
                botRow--;
                System.out.println("UP\n");
            }
            while(botCol>0) {
                botCol--;
                System.out.println("LEFT\n");
            }
        }
        else if(grid[0][p-1].equals('P')) {
            while(botRow>0) {
                System.out.println("UP\n");
                botRow--;
            }
            while(botCol<p-1) {
                botCol++;
                System.out.println("RIGHT\n");
            }
        }
        else if(grid[n-1][0].equals('P')) {
            while(botRow<n-1) {
                botRow++;
                System.out.println("DOWN\n");
            }
            while(botCol>0) {
                botCol--;
                System.out.println("LEFT\n");
            }
        }
        else if(grid[n-1][p-1].equals('P')) {
            while(botRow<n-1) {
                botRow++;
                System.out.println("DOWN\n");
            }
            while(botCol<p-1) {
                botCol++;
                System.out.println("RIGHT\n");
            }
        }   
   }
}
public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int m,n;
    m = in.nextInt();
    n=m;
    int j=0;
    String grid[][] = new String[m][n];
    for(int i = 0; i < m; i++) {
       while(j<n){
            grid[i][j] = in.next();             
        j++;
       }     
    }

displayPathtoPrincess(m,n,grid);

}
}

Its giving Null Pointer Exception.can anyone please tel what am i doing wrong in here?


Solution

  • Ok, no offence but this code is a mess.

    I know what I will answer won't be exactly what you want, but it might be very helpful for you in the future.

    What would I change? (After you change all of this, the error will more likely become apparent or it will be clear enough to ask for help)

    First: Variable types.

    This is just a tiny detail, but I don't like the way you did it; why use a String if every cell will be represented by a char?

    Every time you create a variable (or an Array, or anything at all) think about what you need it to store, and create the variable in a way it will store what you need. If you needed it to store if something is true or false, you wouldn't create a String variable and store "true" or "false", you would use a boolean.

    Apply this every time and you will improve faster.

    Second: use functions.

    Functions are a great way to abstract yourself from the implementation details.

    I mean, you can easily see the difference between something like your code, and something like:

    static void displayPathtoPrincess(int n, int p,char [][] grid){
    
        Point bot;
        Point princess;
    
        getInitialPositions(bot, princess, grid);
    
        Point dif = getRelativePrincessPosition(bot, princess);
    
        while (!bot.equals(princess)) {
            switch (dif.y) {
                case UP:
                    move (UP_MOVEMENT);
                    break;
                case DOWN:
                    move (DOWN_MOVEMENT);
                    break;
            }
            switch (dif.x) {
                case LEFT:
                    move(LEFT_MOVEMENT);
                    break;
                case RIGHT:
                    move(RIGHT_MOVEMENT);
                    break;
            }
        }
    }
    

    (And then implement the necessary methods, and create the constants, that is something pretty easy to do)

    Third: use the appropriate loop every time.

    If you know you want to go from j = 0, while j < n, increasing j every iteration; that's not called a while, that's called a for. (Also, as someone else commented in their answer, you forgot to restart the j; so it only goes in once.

    Finally: Let's go with your error now.

    I believe your code might be pretty buggy and not give you the desired output, but the NullPointerException is something more specific.

    Since you don't use the appropriate loop in the main, for j, and you forgot to restart it's value, you didn't fill the whole array.

    When you try to read a value you didn't fill (in the for where you find the robot's position), that value is null, and the value for some rows will be null too; hence the NullPointerException (because you try to access the value of a null array).