2

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 | 
karel
  • 5,489
  • 46
  • 45
  • 50
henryke9
  • 23
  • 3
  • It is not clear (at least to me) what you are trying to achieve. How would a correct output look like? – Eritrean Apr 14 '21 at 13:58
  • Sorry if I wasn't clear, the correct output would be something like this: 0 | 18 | 23 | 30 | 48 | 0 | 0 | 76 | 0 | /End of row 1 0 | 12 | 24 | 0 | 0 | 58 | 61 | 78 | 0 | /End of row 2 1 | 17 | 0 | 0 | 42 | 54 | 0 | 0 | 86 | /End of row 3 With 5 numbers at a random position in each row, and then the colums with the respetive limit of values! Column 1 from the 1-9, column 2 from 10-19, column 3 from 21-29 until in reaches 90 in the last one! – henryke9 Apr 14 '21 at 17:48
  • Edited the main post for a better sense of the output! – henryke9 Apr 14 '21 at 17:49
  • @henryke9 can each column contain the same number more than once? – WJS Apr 14 '21 at 19:43

3 Answers3

2

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
WJS
  • 36,363
  • 4
  • 24
  • 39
  • I think possible duplicates must be avoided. OP needs, if I have understood it correctly, 5 different random numbers – Eritrean Apr 14 '21 at 15:06
  • I don't think I was clear enough i'm sorry! I've edited the post with the expected output in the last sentence. I'm just trying to generate one card where all this rules must be followed: Column 1 from the 1-9, column 2 from 10-19, column 3 from 21-29 until in reaches 90 in the last one! (9 Columns) and then in each row there have to be 5 numbers of the 9 slots avaliable per row. The column generator is working great the problem is to put the five numbers each row. Thank you for the help! – henryke9 Apr 14 '21 at 17:55
1

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]
Community
  • 1
  • 1
Eritrean
  • 15,851
  • 3
  • 22
  • 28
0

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 |