Reputation: 47
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.
Upvotes: 0
Views: 677
Reputation: 159086
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));
Upvotes: 1
Reputation: 963
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.
Upvotes: 1
Reputation: 1212
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.
Upvotes: 0
Reputation: 3124
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.
Upvotes: 0