0

I'm writing a program to create a bingo game for a class assignment, however I'm a little stuck on how to have a different numbers for each column in the 5x5 array. The code I have now is creating random numbers for the array, however some runs have the same numbers in a column. Any help would be greatly appreciated.

Below is some coding for the first two columns.

public static void newCard() {
        System.out.println("B" + "  " + "I" + "  " + "N" + "  " + "G" 
            + "  " + "O");
        int card [][] = new int[5][5];
        for (int i = 0; i < card.length; i++) {
            for (int j = 0; j < card[i].length; j++) { 
                    card[i][0] = (int)(Math.random() * 15 + 1);
                     if (card[i][0] == card[i][j]) {
                    card[i][0] = (int)(Math.random() * 15 + 1);
            card[i][1] = (int)(16 + Math.random() * 15);
                 if (card[i][1] == card[i][j]) {
                card[i][1] = (int)(16 + Math.random() * 15);
                    }
//New Code 
public static void main(String[] args) {
        int[][] card = newCard();
        System.out.println("B  I  N  G  O");
        for (int i = 0; i < card.length; i++) {
            for (int j = 0; j < card[i].length; j++) {
                System.out.printf("%2d ", card[j][i]);
            }
            System.out.println();
        }
        Scanner input = new Scanner(System.in);
        while (calledCard()) {
        System.out.println("Enter the called number: ");
        int number = input.nextInt();
        }
    }
public void calledCard(int number) {
        for(int i = 0; i <= 4; i++) {
            for(int j = 0; j <= 4; j++) {
                if(newCard()[i][j]==number) {
                    newCard()[i][j] = 0;
                }  else  {
                    continue;
                }
            }
        }

    }
The results I get are allowing each column to have some of the same numbers shown.
  • 3
    Fill up a List with numbers 1-99, then call `Collections.shuffle` - see https://stackoverflow.com/a/3732080/2310289 – Scary Wombat Jun 14 '19 at 02:06
  • Please format the code a little better, and be sure to add all the code. The current code is missing closing braces so it's hard to see the logic you are employing in the current attempt. – theawesometrey Jun 14 '19 at 02:21
  • Unrelated, but maybe just `System.out.println("B I N G O");` would be sufficient. I can't make heads or tails of your code. Is it steganography based on indentation? – Dave Newton Jun 14 '19 at 03:36

2 Answers2

1

INFO:

A typical Bingo game utilizes the numbers 1 through 75. The five columns of the card are labeled 'B', 'I', 'N', 'G', and 'O' from left to right. The center space is usually marked "Free" or "Free Space", and is considered automatically filled. The range of printed numbers that can appear on the card is normally restricted by column, with the 'B' column only containing numbers between 1 and 15 inclusive, the 'I' column containing only 16 through 30, 'N' containing 31 through 45, 'G' containing 46 through 60, and 'O' containing 61 through 75.

you can use Collections.shuffle to randomize each List, here is how to use it:

     public static void newCard() {
        List<List<Integer>> nums = new ArrayList<>();
        int k=1;
        for (int i = 0; i <5; i++) {
            nums.add(new ArrayList<>());
            for(int j=0; j<15; j++){
                nums.get(i).add(k++);
            }
//            System.out.println(nums.get(i));
        }


        System.out.println("B" + "  " + "I" + "  " + "N" + "  " + "G"
                + "  " + "O");
        int card [][] = new int[5][5];
        for (int i = 0; i < card.length; i++) {
            Collections.shuffle(nums.get(i));
        }

        for (int i = 0; i < card.length; i++) {
            for (int j = 0; j < card[i].length; j++) {
                card[i][j] = nums.get(j).get(i);
                //System.out.print(card[i][j]+" ");
            }
            //System.out.println("");
        }
//        System.out.println(card);
    }
MD Ruhul Amin
  • 4,386
  • 1
  • 22
  • 37
  • 1
    For readabilty and easier verification, I would rather use a simple incrementing int variable rather than `i*card.length)+j` – Scary Wombat Jun 14 '19 at 02:46
  • This answer is fully random whereas a bingo card has a valid range for each column. – theawesometrey Jun 14 '19 at 02:53
  • @TreyGraham hmm, I thought that bingo values were simply between 1 && 99 - please explain the valid ranges. – Scary Wombat Jun 14 '19 at 02:57
  • Bingo columns are ranged 1-15 for B, 16-30 for I, 31-45 for N, 46-60 for G, and 61-75 for O. A quick search on Google will explain it in more depth if you want to check my facts. – theawesometrey Jun 14 '19 at 03:00
-1

Since there is a valid range of values for each column (1-15 for B, 16-30 for I, 31-45 for N, 46-60 for G, and 61-75 for O), you can create a list containing the valid range, randomly shuffle it, and then pick the first five values from the list to fill the bingo card column.

Here is code to generate an array with values on the range [begin, end]:

public static int[] rangeClosed(int beginInclusive, int endInclusive) {
    if (beginInclusive > endInclusive) {
        throw new IllegalArgumentException("Begin must be less than or equal to end for range.");
    }
    int[] range = new int[endInclusive - beginInclusive + 1];
    for (int i = 0; i < range.length; i++) {
        range[i] = beginInclusive + i;
    }
    return range;
}

Here is code to swap two values in an array:

public static void swap(int[] array, int index1, int index2) {
    if (index1 < 0 || index1 >= array.length) {
        throw new IllegalArgumentException("Swap index one is out of bounds for the given array.");
    } else if (index2 < 0 || index2 >= array.length) {
        throw new IllegalArgumentException("Swap index two is out of bounds for the given array.");
    }
    int tmp = array[index1];
    array[index1] = array[index2];
    array[index2] = tmp;
}

Here is code to randomly shuffle an array by iterating through the array and randomly swapping each index with another:

public static void shuffle(int[] array) {
    Random rand = new Random();
    for (int i = 0; i < array.length; i++) {
        swap(array, i, rand.nextInt(array.length));
    }
}

Finally, here is the code to randomly generate the bingo card along with a main function to display it:

public static int[][] randomBingoCard() {
    int bingoRange = 15;
    int bingoCardSize = 5;
    int[][] card = new int[bingoCardSize][bingoCardSize];
    for (int i = 0; i < card.length; i++) {
        int[] columnRange = rangeClosed(i * bingoRange + 1, i * bingoRange + bingoRange); 
        shuffle(columnRange);
        for (int j = 0; j < card[i].length; j++) {
            card[i][j] = columnRange[j];
        }
    }
    return card;
}

public static void main(String[] args) {
    int[][] card = randomBingoCard();
    System.out.println("B  I  N  G  O");
    for (int i = 0; i < card.length; i++) {
        for (int j = 0; j < card[i].length; j++) {
            System.out.printf("%2d ", card[j][i]);
        }
        System.out.println();
    }
}

EDIT:

For your new question to fill in the card, I have included 3 new functions along with an updated main. One function to govern the loop by checking to see if all the numbers have been called, one to mark a number when called, and one function to print out the current card.

public static boolean allNumbersMarked(int[][] card) {
    for(int i = 0; i < card.length; i++) {
        for(int j = 0; j < card[i].length; j++) {
            if(card[i][j] != 0) {
                return false;
            }
        }
    }
    return true;
}

public static void markNumber(int[][] card, int number) {
    for(int i = 0; i < card.length; i++) {
        for(int j = 0; j < card[i].length; j++) {
            if(card[i][j] == number) {
                card[i][j] = 0;
            }
        }
    }
}

public static void printCard(int[][] card) {
    System.out.println("B  I  N  G  O");
    for (int i = 0; i < card.length; i++) {
        for (int j = 0; j < card[i].length; j++) {
            System.out.printf("%2d ", card[j][i]);
        }
        System.out.println();
    }
}

public static void main(String[] args) {
    int[][] card = randomBingoCard();
    printCard(card);
    Scanner input = new Scanner(System.in);
    while (!allNumbersCalled(card)) {
        System.out.println("Enter the called number: ");
        int number = input.nextInt();
        markNumber(card, number);
        printCard(card);
    }
    input.close();
}

Due to the new methods that are being added it makes sense to make a BingoCard object that does this for you. Before when you just wanted a card, a simple static function and main were sufficient, however now it would be worth while to make this program Object Oriented.

theawesometrey
  • 389
  • 2
  • 11
  • This is actually really helpful, thank you so much. Quick question, for IntStream.rangeClosed(i * 15 + 1, i * 15 + 15), how exactly does this randomize each spot in the array? Only learned about Math.random in class so this is new. – awilliams21416 Jun 14 '19 at 19:56
  • The IntStream portion is to generate the number range. For example, the first colum (B column) it would generate a list of integers from 1-15. The randomize part is in the next line of code where I call the shuffle code. The shuffle portion randomly swaps values in the array as it iterates through. I updated to give a better understanding since it sounds like you are new to java. I plan to replace the stream with an iterative function to help your understanding, however streams are awesome so pay attention if you go over them in class. – theawesometrey Jun 14 '19 at 22:42
  • I really appreciate that. I'm starting to catch on the more I mess around with it. Seems a lot more helpful than Math.random as well, just a few more steps. But thank you again! – awilliams21416 Jun 15 '19 at 17:22
  • Of course. Glad to help. Let me know if you have any more questions. Not sure why I'm downvoted on this, but as long as you get what you need all is good. – theawesometrey Jun 15 '19 at 17:33
  • One last question, I'm trying to call the calledCard method to check through the card and change each called number to 0. I have the method correct I believe, however just having trouble calling it. This is the code below. – awilliams21416 Jun 15 '19 at 18:58
  • public static void main(String[] args) { int[][] card = newCard(); System.out.println("B I N G O"); for (int i = 0; i < card.length; i++) { for (int j = 0; j < card[i].length; j++) { System.out.printf("%2d ", card[j][i]); } System.out.println(); } Scanner input = new Scanner(System.in); while (calledCard()) { System.out.println("Enter the called number: "); int number = input.nextInt(); } } – awilliams21416 Jun 15 '19 at 19:01
  • public void calledCard(int number) { for(int i = 0; i <= 4; i++) { for(int j = 0; j <= 4; j++) { if(newCard()[i][j]==number) { newCard()[i][j] = 0; } else { continue; } } } } – awilliams21416 Jun 15 '19 at 19:01
  • From first glance tho, you are calling the new card function multiple times which will generate a new random card everytime (probably not what you want). To fix that, allow the called card function to allow for you to pass in the actual card. Also, you can remove the continue from the for loop since that is going to happen at the end of the loop anyways. Finally you need to make the called card function return boolean, where the boolean is true if card is completely zeroed out and false otherwise. – theawesometrey Jun 15 '19 at 19:53
  • If you would like more info or this addressed in my answer, add the code to the end of your original question. But at least give a try to the comments I gave above before adding it please. – theawesometrey Jun 15 '19 at 19:55