Edwin Torres
Edwin Torres

Reputation: 483

Putting a number at random spots in 2D array

I have a 2D Array that has 5 rows and 5 columns. I want it so that at 8 random spots in that 2D array (make it pick a random row and column) to put a char of '1'.

What I did was call the Random class and generate a number between 0 and 4 (for the 5 spots of the array) then I have two for loops that run 8 times (for the 8 random spots I want), one that goes through the row, the other through the column.

This is the code I have so far:

char[][] battleship = new char[5][5];
//I didn't include this but I have a for loop that populates all the rows and columns with a char of '0'
        Random random = new Random();
        int randomNum = random.nextInt(4);

        for (int i = 0; i < 8; i++)
        {
              for (int o = 0; o < 8; o++)
        {

            battleship[randomNum][randomNum] = '1';

        }
        }

The issue I am getting is that instead of it putting the '1' at 8 random spots, it's putting in 5 spots back to back.

How do I correct this?

Here is an example of the output:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0

The '1' isn't in 8 random spots.

Where did I go wrong?

Upvotes: 3

Views: 7924

Answers (3)

user3437460
user3437460

Reputation: 17454

Having nested loop running 8 times each will iterate it 64 times. You don't need nested loops to do that. One of the easy ways will be using a while-loop and distribute the 8 random spots till all 8 spots are taken:

int occupiedSpots = 0;
Random random = new Random();

while(occupiedSpots < 8){
    int x = random.nextInt(array.length);
    int y = random.nextInt(array[0].length);
    if(battleship[x][y] == 0){
        battleship[x][y] = 1;
        occupiedSpots++;
    }
}

Also ensure you are generating new random numbers in every iteration, else you will always be using the same random values.

Using a while-loop also ensures all 8 spots are on different locations. If you simply implement it with a for-loop without checking, there is a tendency some spots may fall on the same location twice.

Upvotes: 4

Czyzby
Czyzby

Reputation: 3139

You are getting a random number before the loop, so it never changes. Basically, randomNum variable was rolled and assigned once - you should call the nextInt method multiple times. Try this:

    for (int i = 0; i < 8; i++) {
        int randomX = random.nextInt(battleship.length);
        int randomY = random.nextInt(battleship[randomX].length);
        battleship[randomX][randomY] = '1';
    }

Note that this do not address the issue of collisions - you can be unlucky enough to get the same position multiple times and fill only 1-7 spots.

From the documentation of nextInt(int):

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.

Upvotes: 3

Frans
Frans

Reputation: 4022

I would take a different approach. If you pretend your 5x5 2D array is actually one long 25-element one-dimensional array, than basically all you need to do is produce 8 distinct numbers between 0 and 25.

Your code also doesn't guarantee the 8 random numbers are all different.

Try this:

    // Initialize random number array
    int[] positions = new int[25];
    for (int i = 0; i < 25; i++) {
        positions[i] = i;
    }

    char[][] battleship = new char[5][5];

    // Fill the battleship field
    for (int i = 0; i < 8; i++) {
        int random = (int)(Math.random() * (25 - i - 1));
        int position = positions[random];
        positions[random] = positions[25 - i - 1];
        int row = position / 5;
        int col = position % 5;
        battleship[row][col] = '1';
    }

    // Show the field
    for (int row = 0; row < 5; row++) {
        for (int col = 0; col < 5; col++) {
            System.out.print(battleship[row][col] + " ");
        }
        System.out.println();
    }

Upvotes: 0

Related Questions