I'm new to Java and im trying to randomize non-repeating numbers for a game. My code generates unique random numbers from 1 to 75 only if i do not add a break statement, (which i have to do to only get one number at the time). What do I do? edit -(i was wondering if the reason it kept resetting is because i called on the method multiple times? im not too sure how to fix that)
public static void genNumber() {
Random random = new Random();
int num;
String u;
String letter = "";
HashSet<Integer> used = new HashSet<>(75);
for (int i = 1; i <= 75; i++){
ball.add(i);
}
while(used.size() > 0) {
num = 1 + random.nextInt(75);
if (used.contains(num)){
used.remove(new Integer(num));
u = Integer.toString(num);
System.out.print(u + "\n");
break;
}
if (!used.contains(num)){
continue;
}
}
The numbers are unique and random but i only want one number at the time (without repeating) not all 75 at once.
Perhaps shuffle the list each time you want a new random sequence, like a deck of cards. Each element is guaranteed to be unique.
List<Integer> balls = new ArrayList<>();
for (int i = 1; i <= 75; ++i) {
balls.add(i);
}
for (;;) {
// Shuffle the list every 75 draws:
Collections.shuffle(balls);
System.out.println(Arrays.toString(balls.toArray()));
// Consume the sequence
for (Integer ball : balls) {
take(ball);
}
}
I would make a 75 element array of boolean values and set all the values to true. Make a method that generates one random number and update your boolean array at that value to false. Each time you generate a number check your array to see if that value is set to true. Then you can keep generating numbers one at a time and not have to worry about getting repeats. You can have a while loop that asks the user to input yes or no and if they answer no it won't call your method and set your while loop condition to false. and if they answer yes it does call the method and keeps looping.
Related
I need to generate players(any number) of large numbers with the condition that all of them will be less than P. But for some reason, when generating the resulting array, it either goes beyond the players range or generates numbers greater than P. How to generate it correctly?
ArrayList<BigInteger> C = new ArrayList<>(players);
for(int i = 0; i < players; i++) {
do {
C.add(i, new BigInteger(64, random));
} while (C.get(i).compareTo(P) > 0);
}
the reason for your error is you are adding the integer into the C regardless whether the generated number is larger than P. meaning your list will grow larger than your players
also please follow the naming convention and use camel case for your variable names
do sth like this instead
ArrayList<BigInteger> integerList = new ArrayList<>(players);
while (integerList.size()<players-1){
BigInteger randomInt = new BigInteger(64, random);
if(randomInt.compareTo(p) > 0){
integerList.add(randomInt);
}
}
Hello everyone I have this command:
for (z = 0; z < utenti.length; z++) {
utenti[z] = rand.nextInt(1000) + 1;
}
After it's done generating random numbers between 1 and 1000 I want it to stop, the command is one of the functions in my program, but everytime i recall it the numbers generete randomly again. Is there a way to stop the random generation after the first time?
Is there a way to stop the random generation after the first time?
Yes. Don't execute that code after the first time. For example:
if (firstTime) {
for (z = 0; z < utenti.length; z++) {
utenti[z] = rand.nextInt(1000) + 1;
}
firstTime = false;
}
I you don't want to run the piece of code twice, then why are you calling it twice?
Since this piece of code is required to be executed just once, it probably is in the wrong place. It perhaps belongs in a constructor or something, depending on your program structure.
You might just do what Stephen C did in his answer, using a boolean to keep track of whether it's the first time or not. That might be the simplest option for you.
In addition to the other answer, also note that one the constructors of the Random class accepts a seed. If you keep the seed the same, the sequence of pseudo-random numbers will be the same. This saves you the memory usage of the utenti array, especially with large arrays.
private long seed;
private void determineSeed() {
long seed = new Random().nextLong();
}
And then use:
Random rand = new Random(this.seed);
for (int i = 0; i < utenti.length; i++) {
int number = rand.nextInt(1000) + 1);
// Don't save it to an array, do something with number
}
A drawback is that you cannot usage specific element of the sequence (for example, utenti[i]), you must use the random numbers in sequence.
So I'm working on a program which is supposed to randomly put people in 6 rooms (final input is the list of rooms with who is in each room). So I figured out how to do all that.
//this is the main sorting sequence:
for (int srtM = 0; srtM < Guys.length; srtM++) {
done = false;
People newMove = Guys[srtM]; //Guys is an array of People
while (!done) {
newMove.rndRoom(); //sets random number from 4 to 6
if (newMove.getRoom() == 4 && !room4.isFull()) {
room4.add(newMove); //adds person into the room4 object rList
done = true;
} else if (newMove.getRoom() == 5 && !room5.isFull()) {
room5.add(newMove);
done = true;
} else if (newMove.getRoom() == 6 && !room6.isFull()) {
room6.add(newMove);
done = true;
}
}
The problem now is that the code for reasons I don't completely understand (something with the way I wrote it here) is hardly random. It seems the same people are put into the same rooms almost every time I run the program. For example me, I'm almost always put by this program into room 6 together with another one friend (interestingly, we're both at the end of the Guys array). So how can I make it "truly" random? Or a lot more random than it is now?
Thanks in advance!
Forgot to mention that "rndRoom()" does indeed use the standard Random method (for 4-6) in the background:
public int rndRoom() {
if (this.gender == 'M') {
this.room = (rnd.nextInt((6 - 4) + 1)) + 4;
}
if (this.gender == 'F') {
this.room = (rnd.nextInt(((3 - 1) + 1))) + 1;
}
return this.room;
}
if you want it to be more random try doing something with the Random method, do something like this:
Random random = new Random();
for (int i = 0; i < 6; i++)
{
int roomChoice = random.nextInt(5) + 1;
roomChoice += 1;
}
of course this is not exactly the code you will want to use, this is just an example of how to use the Random method, change it to how you want to use it.
Also, the reason I did random.nextInt(5) + 1; is because if random.nextInt(5) + 1; gets you a random number from 0 to 5, so if you want a number from 1 to 6 you have to add 1, pretty self explanatory.
On another note, to get "truly" random is not as easy as it seems, when you generate a "random" number it will use something called Pseudo random number generation, this, is basically these programs produce endless strings of single-digit numbers, usually in base 10, known as the decimal system. When large samples of pseudo-random numbers are taken, each of the 10 digits in the set {0,1,2,3,4,5,6,7,8,9} occurs with equal frequency, even though they are not evenly distributed in the sequence.
There might be something wrong with code you didn't post.
I've build a working example with what your classes might be, and it is distributing pretty randomly:
http://pastebin.com/u8sZRxi6
OK so I figured out why the results don't seem very random. So the room sorter works based on an alphabetical people list of 18 guys. There are only 3 guy rooms (rooms 4, 5 and 6) So each guy has a 1 in 3 chance to be put in say, room 6. But each person could only possibly be in 2 of the 6 spots in each room (depending on where they are in the list).
The first two people for example, could each only be in either the first or second spot of each room. By "spot" I mean their place in the room list which is printed in the end. Me on the other hand am second last on the list, so at that point I could only be in either the last or second last spot of each room.
Sorry if it's confusing but I figured out this is the reason the generated room lists don't appear very random - it's because only the same few people could be put in each room spot every time. The lists are random though, it's just the order in which people appear in each list which is not random.
So in order to make the lists look more random I had to make people's positions in the room random too. So the way I solved this is by adding a shuffler action which mixes the Person arrays:
public static void shuffle(Person[] arr) {
Random rgen = new Random();
for (int i = 0; i < arr.length; i++) {
int randPos = rgen.nextInt(arr.length);
Person tmp = arr[i];
arr[i] = arr[randPos];
arr[randPos] = tmp;
}
}
TL;DR the generated room lists were random - but since the order of the people that got put into the rooms wasn't random the results didn't look very random. In order to solve this I shuffled the Person arrays.
Ok so i have looked about for an answer. I am using a random generator to generate numbers based on the user input. This will then select a random number from that and assign them a special position in the game. However the problem is i keep getting repeated values which isn't what i want. So could anyone help?
in
(blueprint class)
int getRoll()
{
roll=rand.nextInt(totalNum);
return roll;
}
(main class)
for(numberOfWerewolves=0;numberOfWerewolves!=wolves.werewolfNum;numberOfWerewolves++)
{
playerNumber++;
wolves.getRoll();
System.out.println(wolves.roll);
}
anyone can help me would be great thanks
It sounds like you want several random numbers within the same range, but you don't want any repeats. If so, what you want is called a "shuffle." Fill an array with the numbers from 1 to N (or 0 to N-1, or whatever), shuffle the array, and then start using the numbers from the beginning of the array.
A good description and implementation of shuffling is given here:
https://stackoverflow.com/a/1520212/1441122
Create a list to keep track of previous random numbers, and loop to keep recalculating the random number until it doesn't match any of them in the list:
public static boolean checkIfExists(ArrayList<Double> list, double x) {
for (double d : list) {
if (d == x) {
return false;
}
}
return true;
}
ArrayList<Double> list = new ArrayList<Double>();
int getRoll()
{
while (true) {
roll = rand.nextInt(totalNum);
if (checkIfExists(list, roll)) {
list.add(roll);
return roll;
}
}
return -100; // -100 means it couldn't generate a number
}
You should not keep the while condition to be true; you should modify it so that it only loops for until you're sure that a unique number can't be generated.
static int n = -1;
private static int repeatBuffer[] = new int[10];
static {
repeatBuffer[0] = 0;
//and more
repeatBuffer[9] = 9;
}
static public void randomize() {
do {
Random r = new Random();
randomNumber = r.nextInt(20);
} while (!uniqueInt(randomNumber));
Log.e(TAG, "" + randomNumber); //here I need have a unique int
}
private static Boolean uniqueInt(int random) {
for (int i = 0; i < 9; i++) {
if (random == repeatBuffer[i]) {
return false;
}
}
if (++n > 9)
n = 0;
repeatBuffer[n] = random;
return true;
}
Sometimes I'm getting same int twice, I'm wondering where is the problem? And is it even work? I spend quite a lot of time on this, and I give up. I think I need some minor tweaks in code :)
An easier way to get a random int is to create a List of integers List<Integer>, adding it with numbers that you would like to have. Then shuffling the List using Collections.shuffle(list);. Now start reading from the beginning of the list and you will get a unique random int each time.
Just make sure that each time you "read" a number from the list, either remove it from the list or increase the index for where you read.
That's the normal behavior of a random number generator, it's correct to generate repeated numbers as long as the number distribution remains uniform.
If you need a set of unique random numbers, you can generate them inside a loop and ask at every iteration if the newly generated number is present in the set of generated numbers. If not, add it, if yes, keep iterating - until the set has the desired size.
Er, a unique random between 1 and 20? What happens when it runs the 21st time?
Try making a List of the Integers between 1 and 20. Use Collections.shuffle() to shuffle the list. Then pop the first item off the front of the list and use that.