Why does this do-while loop not function?

122 views Asked by At

I have made a game of battleships using 2D Arrays and need my do-while loop to work so if you place a ship where there already is one, you get asked to place the ship again. Below is the code that changes the array values from 0 to 1 to resemble a ships placement. It throws an IllegalArgumentException if you try place a ship where there is already a value of 1.

public int[][] changeMatrixValues(int i, int j, int k, int l) throws IllegalArgumentException {    // for a ship with dimensions k*l and starting grid[i][j]
    for (mRow = i; mRow < (i + k); mRow++) {
        for (mCol = j; mCol < (j + l); mCol++) {
                    if (mMatrix[mRow][mCol] == 0 && mMatrix[mRow][mCol] != 1)
                        mMatrix[mRow][mCol] = 1;
                    else
                        throw new IllegalArgumentException("Ship already in area");
        }
    }
    return mMatrix;
}

This is the code in a different class that prompts the user for where they want to place a certain type of ship. It picks up the IllegalArgumentException, however, the do-while loop does not work and if the user places a ship on top of another, they do not get another chance to place that specific ship and the game moves on to ask where you would like to place the next ship. If anyone can highlight why this do-while loop is not working that'd be great!

    private boolean keepPlacing;
    private void ship(String shipToPlace, Matrix matrix, int k, int l) {
    keepPlacing = true;
    do {
        try {
            System.out.println(shipToPlace);
            chooseGrid();            // enter co-ords of where you want to place ship
            matrix.changeMatrixValues(mRow, mCol, k, l);
            keepPlacing = false;
        } catch (IllegalArgumentException ie) {
            System.out.println(ie.getMessage());
        }
    } while (keepPlacing);

    matrix.printLabeledMatrix();
}
2

There are 2 answers

1
Vitali Biryukov On

In method changeMatrixValues you set array values to 1 and if throws IllegalArgumentException you don't rollback them.

0
Brian Clegg On

This change solves the issue:

private void ship(String shipToPlace, Matrix matrix, int k, int l) {
    boolean keepPlacing = true;
    do {
        try {
            System.out.println(shipToPlace);
            chooseGrid();
            if(matrix.validate(mRow, mCol, k, l) == true) {
                matrix.changeMatrixValues(mRow, mCol, k, l);
                keepPlacing = false;
            }
        } catch (IllegalArgumentException ie) {
            System.out.println(ie.getMessage());
        }
    } while (keepPlacing);

    matrix.printLabeledMatrix();
}

where the validate(mRow, mCol, k, l) method is:

public boolean validate(int i, int j, int k, int l) {
        for (mRow = i; mRow < (i + k); mRow++) {
            for (mCol = j; mCol < (j + l); mCol++) {
                if (mMatrix[mRow][mCol] == 1) {
                    System.out.println("Oops, try again");
                    return false;
                }
            }
        }
        return true;
}

Thanks for the help!