0

I am trying to loop asking coordinates and getting input from the scanner. I want to ask for input until the coordinates are valid. However I am really new with java and the loops confused me for this task. First I should print a console output asking the player to input a pair of board coordinates.

If the inputs are valid coordinates I will return the coordinates as a string array.

If the inputs are not valid coordinates I should print an error message and then ask again until I get valid coordinates.

public static String[] positionQuery(int dim, Scanner test_in) {
    Scanner stdin = new Scanner(System.in);
    System.out.println("Provide origin and destination coordinates.");
    System.out.println("Enter two positions between A1-H8:");
    String s1 = stdin.nextLine();
    String[] coordinates = s1.split(" ");
    String origin = coordinates[0];
    String dest = coordinates[1];

    while (!validCoordinate(origin, dim) && !validCoordinate(dest,dim)) {
        System.out.println("ERROR: Please enter valid coordinate pair separated by space.");
        String s2 = stdin.nextLine();
        String[] coordinates2 = s2.split(" ");
        String origin2 = coordinates[0];
        String dest2 = coordinates[1];
    }
    return new String[0];
}

I created a helper function validCoordinate(String, int) that checks the validity. How can I fix my code?

Abra
  • 19,142
  • 7
  • 29
  • 41
Kale Joe
  • 163
  • 6
  • 1
    For your information, parameter `test_in` of method `positionQuery()` is not used. – Abra Feb 14 '20 at 16:47

3 Answers3

2

You should consider a 'do-while' loop, since you want to run the code once regardless of whether or not the condition is fulfilled. Then, at the end of the loop, you can check if the condition is fulfilled. If it is not fulfilled, it will run again. For example:

public static String[] positionQuery(int dim) {

    boolean errorEncountered = false;
    String[] coordinates;
    Scanner stdin = new Scanner(System.in);

    do {
        if(errorEncountered)
             System.out.println("ERROR: Please enter valid coordinate pair separated by space.");
        else {
            System.out.println("Provide origin and destination coordinates.");
            System.out.println("Enter two positions between A1-H8:");
        }
        String s1 = stdin.nextLine();
        coordinates = s1.split(" ");
        String origin = coordinates[0];
        String dest = coordinates[1];
        if(!validCoordinate(origin, dim) || !validCoordinate(dest,dim) || coordinates.length != 2) //makes sure there's only 2 coords
            errorEncountered = true;
        else
            errorEncountered = false;
    } while (errorEncountered);

    return coordinates;
}

In this example, I have taken the liberty of removing the Scanner test_in input, since you didn't use it.

I also noticed you were returning the String[] wrong. If you just want to return the String[] as generated by the split(), you should be returning that variable. Not making a new String[] (See the above example).

This loop (like all loops) could also be accomplished with a while(true) that breaks or returns for the right condition. However, these are sometimes considered bad practice (see Are "while(true)" loops so bad?) because when you learn to write more complicated code, a bunch of break's or return's can make the code very confusing and difficult to read. Thus, you're better-off getting in the habit of using booleans.

JosephG
  • 3,111
  • 6
  • 33
  • 56
1

This is how it can be. With while(true), you get an input. If the coordinates are valid, it will return them. Just implement the validation method the way you want and you're good to go.

public static String[] positionQuery(int dim) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Provide origin and destination coordinates.");
    System.out.println("Enter two positions between A1-H8:");
    while(true) {
        String line = scanner.nextLine();
        String[] coordinates = line.split(" ");
        if(coordinates.length == 2) { // valid input with just one space
            String src = coordinates[0];
            String dst = coordinates[1];
            if(validCoordinate(src, dst, dim)) {
                return coordinates;
            }
        }
        System.out.println("ERROR: Please enter valid coordinate pair separated by space.");
    }
}

/**
 * checks the validity of source and destination
 * @param src source
 * @param dst destination
 * @param dim 
 * @return true if the coordinates are valid, otherwise false
 */
private static boolean validCoordinate(String src, String dst, int dim) {
    // TODO
}
eta32carinae
  • 473
  • 4
  • 12
0

You can use a recursion: call method which reads coordinate validetes them and calls himself again if validation failed. Here is final code of my implementation:

public class Main {

    public static void main(String[] args) {
        int dim = 0;
        Scanner scanner = new Scanner(System.in);
        positionQuery(dim, scanner);
    }


    private static String[] positionQuery(int dim, Scanner scanner) {
        System.out.println("Provide origin and destination coordinates.");
        System.out.println("Enter two positions between A1-H8:");
        return readAndValidateCoordinates(dim, scanner);//read coordinates while they will be valid
    }

    /**
     * Reads coordinates from console and validates them.
     * If validation validation failed the recursion of this method will be invoked
     * @param dim
     * @param scanner
     * @return array of {@link String} coordinates
     */
    private static String[] readAndValidateCoordinates(int dim,  Scanner scanner) {
        String s1 = scanner.nextLine();
        String[] coordinates = s1.split(" ");
        String origin = coordinates[0];
        String dest = coordinates[1];
        if (validCoordinate(origin, dim) && validCoordinate(dest, dim)) {
            return coordinates;
        } else {
            System.out.println("ERROR: Please enter valid coordinate pair separated by space.");
            return readAndValidateCoordinates(dim,  scanner); //read coordinates again
        }
    }

    private static boolean validCoordinate(String origin, int dim) {
        //perform your validation
        return true;
    }
}