2D array random index Lotto game

509 views Asked by At

I'm trying to do a Lotto game where I have to generate a random card and in the first column numbers go from 1-9, second 10-19 all the way to 90. Another rule of the card is that it can only have 5 numbers at random positions in each line and that's what I'm having trouble with.

I've started with this to put numbers in each column:

int[][] numberCard = new int[3][9];

for (int i = 0; i < numberCard.length; i++) {
    numberCard[i][0] = randInt(1, 9);
}

for (int j = 0; j < numberCard.length; j++) {
    numberCard[j][1] = randInt(10, 19);
}

And then do put 5 numbers in a number position in each line of the array i tried this:

//Five numbers first line
Random random0 = new Random();
int randomLocation = 0;

while (randomLocation < 5) {
    int z0 = random0.nextInt(numberCard.length);
    int b0 = random0.nextInt(numberCard[0].length);

    if (numberCard[z0][b0] > 0) {
        numberCard[z0][b0] = 0;
        randomLocation++;
    }
}

//Five numbers second line
Random random1 = new Random();
int randomLocation1 = 0;

while (randomLocation1 < 5) {
    int z1 = random1.nextInt(numberCard.length);
    int b1 = random1.nextInt(numberCard[1].length);

    if (numberCard[z1][b1] > 0) {
        numberCard[z1][b1] = 0;
        randomLocation1++;
    }
}

And then the same for the third one.

Output:

0 | 18 |  0 |  0 | 46 |  0 | 61 | 72 | 88 |
0 | 18 |  0 | 31 |  0 | 55 |  0 |  0 |  0 | 
0 |  0 | 23 | 34 | 45 |  0 |  0 |  0 | 80 |

The problem is that sometimes I get 5 numbers, sometimes 6 and sometimes 4 when sometimes i get the perfect 5 numbers in each line. More frustrating that not working is only working sometimes...

I thought and I think it is because of the random numbers that sometimes repeat themselves so they go to the same index, but then sometimes I have more than the 5 numbers so that makes no sense.

Correct output expected:

0 | 18 | 23 | 30 | 48 |  0 |  0 | 76 |  0 | 
0 | 12 | 24 |  0 |  0 | 58 | 61 | 78 |  0 | 
1 | 17 |  0 |  0 | 42 | 54 |  0 |  0 | 86 | 
3

There are 3 answers

2
Eritrean On BEST ANSWER

I think your approach is complicated than it should be. I would recomend to do it like below:

For each row of your 2D-Array, generate a random number between [1 - 90) and put it to the spot where it belongs by dividing the random number with 10 (will give you values [0 - 8]) while checking that that position doesn't have a random value aready assigned. Reapet this 5 times.

public static void main(String[] args) {
    int[][] numberCard = new int[3][9];

    Random rand = new Random();
    for (int i = 0; i < numberCard.length; i++) {
        for (int j = 0; j < 5; j++) {
            int x = rand.nextInt(89) + 1;
            while (numberCard[i][x / 10] != 0) {
                x = rand.nextInt(89) + 1;
            }
            numberCard[i][x / 10] = x;
        }
    }

    //print or do whatever with your numberCard array

    for (int[] row : numberCard) {
        System.out.println(Arrays.toString(row));
    }
}

Sample output:

[0, 0, 24, 0, 40, 55, 0, 71, 86]
[0, 16, 0, 0, 42, 56, 0, 70, 84]
[5, 12, 0, 0, 49, 0, 69, 0, 82]
2
WJS On

Here is the pretty much the same code as before. The cards have become the rows.

public static void lottery() {
    System.out.println("  1  2  3  4  5  6  7  8  9");
    System.out.println("---------------------------");

    for (int card = 1; card<= 5; card++) {
        List<Integer> numbers = new ArrayList<>();
        for (int i = 0; i <= 8; i++) {
            int s = i > 0 ? 0 : 1;  
            numbers.add(ThreadLocalRandom.current().nextInt(i*10 + s,(i+1)*10));
        }
        Collections.shuffle(numbers);
        int[] row = new int[9];
        for (int s = 0; s < 5; s++) {
            int pick = numbers.get(s);
            row[pick/10] = pick; 
        }
        for (int i = 0; i < 9; i++) {
            System.out.printf("%3d", row[i]);
        }
        System.out.println();
    }
}

Prints

  1  2  3  4  5  6  7  8  9
---------------------------
  5  0  0  0 47  0 67 71 81
  1  0 22  0  0 55 65  0 88
  1 11  0 30  0 58  0 76  0
  0 10 24  0 43  0  0 75 88
  3 16  0  0  0  0 60 71 81
0
AudioBubble On

You can do it like this:

  • The card consists of 3 rows.
  • Each row consists of 9 random cells: 5 filled and 4 hollow.
  • Column ranges: 1-9 first, 80-90 last, x0-x9 others.
  • No duplicate numbers in every column.
List<int[]> card = new ArrayList<>();
IntStream.range(0, 3)
        // prepare a list of cell indices of the row
        .mapToObj(row -> IntStream.range(0, 9)
                .boxed().collect(Collectors.toList()))
        // random order of cell indices
        .peek(Collections::shuffle)
        // list of 5 random cell indices in the row
        .map(list -> list.subList(0, 5))
        // fill the cells with random numbers
        .map(list -> IntStream.range(0, 9)
                // if this cell is in the list, then fill
                // it with a random number, otherwise 0
                .map(i -> {
                    int number = 0;
                    if (list.contains(i)) {
                        // unique numbers in each column
                        boolean isPresent;
                        do {
                            // [1-9] first, [80-90] last, [x0-x9] others
                            number = (int) ((i > 0 ? i * 10 : 1)
                                    + Math.random()
                                    * (i < 8 ? (i > 0 ? 10 : 9) : 11));
                            isPresent = false;
                            for (int[] row : card)
                                if (row[i] == number)
                                    isPresent = true;
                        } while (isPresent);
                    }
                    return number;
                }).toArray())
        // add this row to the card
        .forEach(card::add);
// output
card.stream()
        // row of numbers to string
        .map(row -> Arrays.stream(row)
                .mapToObj(j -> j == 0 ? "  " : String.format("%2d", j))
                // concatenate cells into one row
                .collect(Collectors.joining(" | ", "| ", " |")))
        .forEach(System.out::println);

Output:

|  7 | 20 |    |    | 47 | 53 |    |    | 86 |
|    |    | 27 | 38 |    |    | 63 | 80 | 85 |
|  4 |    | 26 |    |    |    | 69 | 77 | 81 |