0

I'm trying to create a Bingo game using NetBeans IDE 6.9.1 (I'm a noob at coding). Right now I'm stuck at trying to create the bingo card. For the 5x5 card's boxes I used jButtons. I can't randomize the "B" bingo balls down the "B" column. I have a code that "works" for randomizing which "B" ball goes in which "B" jButton, but my method will not work for the jLabel I'm using to output the randomly drawn bingo ball. Here's my "random B-ball code:"

String[] Bball1 = {"B5", "B6", "B11"};
String Brandom1 = (Bball1[new Random().nextInt(Bball1.length)]);
String[] Bball2 = {"B1", "B8", "B15"};
String Brandom2 = (Bball2[new Random().nextInt(Bball2.length)]);
String[] Bball3 = {"B3", "B10", "B13"};
String Brandom3 = (Bball3[new Random().nextInt(Bball3.length)]);
String[] Bball4 = {"B2", "B9", "B14"};
String Brandom4 = (Bball4[new Random().nextInt(Bball4.length)]);
String[] Bball5 = {"B4", "B7", "B12"};
String Brandom5 = (Bball5[new Random().nextInt(Bball5.length)]);

Here is the code for when the user clicks the submit button when they pick a bingo pattern and the card would be generated (incomplete):

    btnSubmit.setEnabled(false);
    cboPattern.setEnabled(false);
    btn1B.setText(Brandom1);
    btn2B.setText(Brandom2);
    btn3B.setText(Brandom3);
    btn4B.setText(Brandom4);
    btn5B.setText(Brandom5);

Yes, this is repetitive, and not overly random, but I did some research on Arrays, as I have not learned them in my Computer Science class, and got this:

    public static void main(String[] Bballs) {
    String[] Bball;
    Bball = new String[2];
    Bball[0] = "B1";
    Bball[1] = "B2";
    Bball[2] = "B3";

    int num = (int) (Math.random() * 2);
    System.out.println(Bball[num]);
}

This is just a test code, and as you can see I could still get B1 more than one time which isn't what I want for the bingo card and the randomly picked bingo balls (which I haven't started yet). Plus, whenever I run my program it doesn't print out the last line. I need this done by the end of Wednesday :/ (It's a late ISU project, and no I did not start it late). Thanks for your time.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Michael
  • 47
  • 1
  • 6
  • Note: Random.nextInt is preferred over Math.random. See http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint – Michael Markidis Jun 21 '16 at 03:13

4 Answers4

1

I hope this is not too far ahead of where you are, but the easiest way to pull M elements from a bag of N items (balls) without repetition, is to simply add all the elements to a List and shuffle() it, then take the first M values using subList().

Here is a generic method for doing that:

private static List<String> draw(String ballPrefix, int noOfBalls, int noToDraw) {
    List<String> balls = new ArrayList<>();
    for (int ballNo = 1; ballNo <= noOfBalls; ballNo++)
        balls.add(ballPrefix + ballNo);
    Collections.shuffle(balls);
    return balls.subList(0, noToDraw);
}

Test

System.out.println(draw("B", 15, 5));

Sample output

[B9, B5, B3, B2, B15]

UPDATE

Ok, in the interest of teaching a bit, a List is somewhat similar to an array, but much more powerful. It contains a sequence of values, like an array, and the values are indexed starting at 0, also like an array.

Unlike an array, where you get the length using arr.length, for a list you call list.size(). Instead of retrieving a value using arr[2], you call list.get(2).

Instead of assigning a value using arr[2] = 7, you can call list.set(2, 7) but that is unusual. This is because, unlike an array that is allocated using new String[5], which allocates a fixed-size array of 5 values, a list is allocated using new ArrayList(), and it will grow in size as needed when calling add(), like the method above does.

After that super short introduction, here is how you use the method above:

List<String> balls = draw("B", 15, 5);
btn1B.setText(balls.get(0));
btn2B.setText(balls.get(1));
btn3B.setText(balls.get(2));
btn4B.setText(balls.get(3));
btn5B.setText(balls.get(4));
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • I get an error for this line of code: `List balls = new ArrayList<>();` because diamond operator is not supported in -source 1.6, I have to use -source 7 or higher. I tried downloading Java JDK 7 but it doesn't show up in the combo box under "Source/Binary Format." My teacher told us not to update NetBeans as the new versions are harder to work with. – Michael Jun 21 '16 at 21:34
  • @Michael So just add the type: `new ArrayList()` – Andreas Jun 21 '16 at 23:10
  • Thanks, but what is my mistake now: `private static List draw(String ballPrefix, int noOfBalls, int noToDraw) { List balls = new ArrayList(); noOfBalls = 15; noToDraw = 5; ballPrefix = "B"; for (int ballNo = 1; ballNo <= noOfBalls; ballNo++) { balls.add(ballPrefix + ballNo); } Collections.shuffle(balls); return balls.subList(0, noToDraw); System.out.println(draw(ballPrefix, noOfBalls, noToDraw)); }` – Michael Jun 21 '16 at 23:46
  • Why did you add the `println()` statement to the `draw()` method? Remove it. Did you understand that the `draw()` method must be inside *some* class, even though I didn't show the class declaration? If so, can you understand that the `println()` statement must be inside *some* method, where it can call *this* method, even though I didn't show the method where the test statement should be, e.g. `main()`? – Andreas Jun 21 '16 at 23:49
  • I've fixed my stupid mistake now, but how do I display `(draw("B", 15, 5))` into jButtons? – Michael Jun 22 '16 at 18:01
  • Method returns a list of `noToDraw` elements. Call [`get(0)`](https://docs.oracle.com/javase/8/docs/api/java/util/List.html#get-int-) to get the first string, `get(1)` to get the second string, and so on... – Andreas Jun 22 '16 at 22:42
  • I get an error that integers can not be dereferenced. `String Bball1 = noToDraw.get(0);` – Michael Jun 22 '16 at 23:27
  • Method returns a list!!! The list have a number of elements in it. The number of elements equal the value you supplied to parameter `noToDraw`. If you assign the return value of the method to a variable of type `List`, you can extract the strings from the list. You do that by calling the `get()` method. --- As I said in the answer "I hope this is not too far ahead of where you are". Since all this seems to be over your head, please disregard this answer, and come back when you've learned more about Java and collections. Hopefully, one of the other answers will be able to help you. – Andreas Jun 23 '16 at 01:46
  • I thank you for helping me, yes this is over my head and my teacher is not going to teach us any more lessons as we are starting exams... so she wanted the class to figure out what to do on our own - and everyone is struggling because time isn't on our side. Plus, I tried `String Bball1 = (drawB("B", 15, 5)).get(0);` but it says line is unreachable because I need a return statement... – Michael Jun 23 '16 at 01:56
  • Btw, I chose to work with your answer because it looked "simpler" to me, and plus you have the most reputation here. – Michael Jun 23 '16 at 01:59
  • Thanks so much for your help. – Michael Jun 25 '16 at 16:48
1

If you want to get a random number, you can use Math.random() or Random, which don't matter your problem. Your problem is what you want to show. One way is get random from a special Max num, and the Max is not changed. I guess this is what you now use. Another way, when you get a random from special Max num ,and then remove the random, ensure every number(from Min to Max) will be used. Java has a Collections.java tool, which has shuffle function, it can make the whole list random. Below is example test code for you. If you want every num(from Min to Max) come out with equal rate, you can use averageRandom_1 or averageRandom_2.

 import java.util.*;
public class Main {

    public static void main(String[] args) {
        System.out.println("Hello World!");
        String[] src = new String[]{"B1", "B2", "B3", "B4", "B5"};
        List<String> srcList = Arrays.asList(src);

   /*     for(int i = 0; i < srcList.size(); i++){
            System.out.print(" random = " + getRandom_2(0, srcList.size()));
        }*/

        averageRandom_2(srcList);
    }

 /**
 * @param min
 * @param max
 * @return [min, max), note it can't return max
 */
public static int getRandom_1(int min, int max){
    return (int)(min + Math.random()*(max-min));
}

/**
 * @param min
 * @param max
 * @return [min, max), note it can't return max
 */
public static int getRandom_2(int min, int max){
    Random random = new Random();
    return random.nextInt(max-min) + min;
}

    public static void averageRandom_1(List<String> data){
        List<String> dataCopy = new ArrayList<>();
        dataCopy.addAll(data);
        Collections.shuffle(dataCopy);
        for(String item : dataCopy){
            System.out.println("--" + item + "--");
        }
    }

    public static void averageRandom_2(List<String> data){
        List<String> dataCopy = new ArrayList<String>(data);
        while(dataCopy.size() > 0) {
            int random = getRandom_2(0, dataCopy.size());
            System.out.println("random = " + random + "--" + dataCopy.get(random) + "--");
            dataCopy.remove(random);
        }
    }
}

Please remember random.nextInt(value)return 0 to (value - 1). Hope to help you.

yanzi1225627
  • 893
  • 11
  • 13
0

You have to know that Math.random() gives a number within 0 and 1.

It never gives 1.

0 < Math.random() < 1
0 < Math.random() * 2 < 2
0 <= (int)(Math.random() * 2) <= 1

Notice the flooring logic, it makes you never get index 2.

Tommy
  • 3,044
  • 1
  • 14
  • 13
  • For no repetition, take a look of while loop or List class - which you will learn later. – Tommy Jun 21 '16 at 03:09
0

Don't try to use Math.random you wont get an even distribution. Using List and Random.nextInt(int) you get a fairly simple solution like so.

Random rand = new Random();
List<String> inRandomOrder = new ArrayList<>();
List<String> items = new ArrayList<>();
items.add("blah1");
items.add("blah2");
items.add("blah3");

while (!items.isEmpty()) {
    String removed = items.remove(rand.nextInt(items.size()));
    inRandomOrder.add(removed)
}

Then you have a list of your items in some random order. It's not really random is only pseudo random if you needed truly random you would have to use SecureRandom. I am sure this is probably an easier way to do this functionally with Java 8 streams, but I haven't had a ton of time to mess with them so sorry if the answer is old fashioned.

David Stocking
  • 1,200
  • 15
  • 26