Generating an array of random points in java with no duplicates - java

I am fairly new to Java, and I want to generate an array of random (x,y) coordinates of length 'number' that contains no duplicates. x or y values can be repeated, but there must be no repeated (x,y) coordinates. The output does not have to be Points, simply some way of holding x,y values for coordinates.
I can generate an array of random points, and have tried using a Set to ensure there are no duplicate values, but have run into problems. I tried using the condition "while (set.size)" and the 'add' method which should disallow duplicates, to create an output of the correct size which contains unique points.
This is the code:
Set<Point> set = new HashSet<Point>();
Random position = new Random();
Point test=new Point();
do{
test.x=position.nextInt(xx);
test.y=position.nextInt(yy);
//xx and yy are the random number limits called from another part of the code
set.add(test);
}
while (set.size()<number);
List<Object> list = new ArrayList<Object>(set);
Object[] coord = list.toArray();
This outputs an array of the correct length, but every element is the same. Can anyone offer any help?
Thanks

test points to the same variable in space everytime you loop, to fix that create a new instance inside the loop - not just once before it:
Set<Point> set = new HashSet<Point>();
Random position = new Random();
Point test;
do{
test = new Point();
test.x=position.nextInt(xx);
test.y=position.nextInt(yy);
//xx and yy are the random number limits called from another part of the code
set.add(test);
}
while (set.size()<number);
List<Object> list = new ArrayList<Object>(set);
Object[] coord = list.toArray();

You are modifying the same point object. However, since you change X and Y every time, you also changing hash code and equality of the point, so you end up placing the same object multiple times in the set. Interesting case.
try
do{
test = new Point();
test.x=position.nextInt(xx);
test.y=position.nextInt(yy);
//xx and yy are the random number limits called from another part of the code
set.add(test);
}
while (set.size()<number);

Value select Randomly but not repeated
Random rndm = new Random();
String[] selectedNumber = new String[15];
String[] sequanceNumber = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
//*****FIRST LOOP START*****//
for(byte a = 0; a < 15;){
int temp = rndm.nextInt(15)+1;
//*****SECOND LOOP START*****//
for(byte b = 0; b < 15; b++){
String s4 = temp+"";
//*****CHECKING CONDITION START*****//
if(s4.equals(sequanceNumber[b]) ){
selectedNumber[a] = s4;
String s1 = sequanceNumber[b];
s1 = s1.replace(s1, " ");
sequanceNumber[b] = s1;
a++;
}
//*****CHECKING CONDITION END*****//
}
//*****SECOND LOOP END*****//
}
//*****FIRST LOOP END*****//
//*****PRINT ALL RANDOM VALUES BUT NOT REPEATED VALUES*****//
System.out.println(Arrays.toString(selectedNumber));

Related

why is my random array not drawing a random texture on each render? what do I have to change?

Before I start I want to state that I am learning, I am completely new. Here i have added as much detail as possible.
So, I have an array of textures of different colors, and set a Random to randomize the textures, Like this:
Texture[] bubbles;
Random random = new Random();
int lowRange = 0;
int highRange = 3;
int result = random.nextInt(highRange -lowRange) + 1; //my random
ArrayList<Integer> BubbleXs = new ArrayList<>();
ArrayList<Integer> BubbleYs = new ArrayList<>();
#Override
public void create () {
bubbles = new Texture[4];
bubbles[0] = new Texture("blue.png");
bubbles[1] = new Texture("red.png");
bubbles[2] = new Texture("green.png");
bubbles[3] = new Texture("yellow.png");
}
Then I proceed to draw the texture at a random color falling from the top of the screen using a for loop, like this:
#Override
public void render () {
if (BubbleCount < 120) {
BubbleCount++;
} else {
BubbleCount = 0;
makeBubble();
}
public void makeBubble () {
float width = random.nextFloat() * Gdx.graphics.getWidth();
BubbleXs.add((int)width);
BubbleYs.add(Gdx.graphics.getHeight());
}
for (int i=0; i < BubbleYs.size(); i++) {
batch.draw(bubbles[result], BubbleXs.get(i), BubbleYs.get(i));
BubbleYs.set(i, BubbleYs.get(i) -4);
}
and it draws the textures at a a random perfectly, but only once, when its created, I want them to be a new random each time its looped, so its a different one every time one falls. why is it not doing that? what am I missing?
Thanks in advance!
Edit: I checked out this post: Change texture with random
but its not really helping any.
The reason they're all the same is that you assign a value to result only once, when it is initialized, and you never change it. If you want it to change, you need to use your Random to assign another value.
Your formula random.nextInt(highRange -lowRange) + 1 isn't right if you're wanting a random number between lowRange and highRange inclusive. That's giving you a number between lowRange + 1 and highRange + 1. The correct formula would be random.nextInt(highRange - lowRange) + lowRange.
The way to solve this would be create an additional variable for each bubble that stores the random int. You are already keeping a list for each of the two variables you're already storing (x and y). You could theoretically add a third, but it's to the point where you really just need to create a class for each bubble, so you can expand it easily if you add more features.
class Bubble {
int x;
int y;
int textureIndex;
}
Then replace your two array lists with:
ArrayList<Bubble> bubbles = new ArrayList<>();
And your makeBubble method should look like this:
void makeBubble(){
Bubble bubble = new Bubble();
bubble.x = (int)(random.nextFloat() * Gdx.graphics.getWidth());
bubble.y = Gdx.graphics.getHeight();
bubble.textureIndex = random.nextInt(3);
}
And your for loop for drawing them would look like this. I changed your textures array name here to bubbleTextures so bubbles can be used for the list of Bubble objects.
for (Bubble bubble : bubbles) {
batch.draw(bubbleTextures[bubble.textureIndex], bubble.x, bubble.y);
bubble.y -= 4;
}
There are numerous other issues I'm seeing with your code, but I think it would be overwhelming to explain them all. This at least gets you going in the right direction.

How to generate random unique numbers on java

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.

How to change an element in a list of lists Java

This is a peice of my code, i am making a grid of 5x5 with random colors set to each section. I need to set the specified y_loc and x_loc in the list to the color randomly picked except i have not been able to find out how. It should be the second last line that is not operating as id like. I understand that i could do this in much much longer code but it would be nice to do it in less.
//making the map
ArrayList<ArrayList<String>> fullmap = new ArrayList<ArrayList<String>>();
ArrayList<String> y_row_0 = new ArrayList<String>();
ArrayList<String> y_row_1 = new ArrayList<String>();
ArrayList<String> y_row_2 = new ArrayList<String>();
ArrayList<String> y_row_3 = new ArrayList<String>();
ArrayList<String> y_row_4 = new ArrayList<String>();
//adding each row
fullmap.add(y_row_0);
fullmap.add(y_row_1);
fullmap.add(y_row_2);
fullmap.add(y_row_3);
fullmap.add(y_row_4);
Random rn = new Random();
//loop to randomly pick colors then set them to their destined locations
for (int y_loc = 0; y_loc < 6; y_loc++){
for (int x_loc = 0; x_loc < 6; x_loc++){
colorPicked = false;
while (!colorPicked){
int ranNum = rn.nextInt();
if (ranNum ==0){
if (redTot < 5) {
redTot += 1;
fullmap.set(y_loc).set(x_loc, "Red"));
colorPicked = true;
Since you have lists in list here, to set something at a specific location, you'll have to get the inner list and then perform the set on it.
The following should work:
fullmap.get(y_loc).set(x_loc, "Red"));
Also, since you seem to always have a 5x5 matrix, I'd recommend using a double array instead. That'd make that line:
fullmap[x_loc][y_loc] = "Red";
You should have something like this:
fullmap.get(y_loc).set(x_loc, "Red"));
Notice the "get". You are "getting" the list at the y location, which returns an array list, then calling "set" against that array list to set the actual value in the index of the "x_loc" value.
You need to make a couple of changes:
While declaring the sub lists, you need to make sure they have 5 empty/null elements. Otherwise set will throw IndexOutOfBoundsException. E.g. you need to declare the lists like this:
ArrayList<String> y_row_0 = Arrays.asList(new String[5]);//Assuming it will have 5 elements
While setting the element, you first need to get the corresponding sub list, e.g. the following needs to be changed from:
fullmap.set(y_loc).set(x_loc, "Red"));
to
fullmap.get(y_loc).set(x_loc, "Red"));
Others have already discussed the indexing issue. Apart from that, I believe that your conditionals may not be executing as you expect. nextInt() will return a reasonable uniform random number in the range of -2147483648 to 2147483647. You have a 1/2^64 chance of getting a 0. Reduce the random number range to something more reasonable. For example, nextInt(10) will return a random number between 0 and 9.
Furthermore, if the probability is too low, you will not get 5 reds all the time. To guarantee 5 picks and for the sake of computational efficiency, it is better to randomly pick array indices and evaluate whether a color is set or not, such as the following pseudo-code
int redTot = 0;
while ( redTot < 5 ) {
int r = rn.nextInt( 5 );
int c = rn.nextInt( 5 );
String color = fullmap.get( r ).get( c );
if ( color == null ) {
fullmap.get( r ).set( c, "Red" );
redTot++;
}
}

java array from newboston lesson

While going over newboston java tutorial, I am looking at array lessons and wondering why assigning variable in array is ++freq[1+rand.nextInt(6)]. I understand the 1+rand.nextInt(6) part but ++freq, I do not.
Because I come from other script background, I would think freq[roll] = 1+rand.nextInt(6) is the right way(but clearly not right).. can someone explain to me why ++freq[1+rand.nextInt(6)] works here?
Another words,
Aren't I doing
freq[0] = 1+rand.nextInt(6);
freq[1] = 1+rand.nextInt(6);
freq[2] = 1+rand.nextInt(6);
------ continue till
freq[9] = 1+rand.nextInt(6);
??
class apples {
public static void main(String[] args) {
Random rand = new Random();
int freq[] = new int[7];
for ( int roll=1; roll < 10; roll++) {
//++freq[1+rand.nextInt(6)];
freq[roll] = 1+rand.nextInt(6);
}
It's for the increment of value of freq array positioned at the 1+rand.nextInt(6) index. What you're doing is assigning value 1+rand.nextInt(6) to freq[roll]. So you are replacing the value at the position not incrementing it.

How to randomly choose one of many objects to be added to an array list?

Say I have 4 objects and I am looking to populate an arraylist of 100 elements with these four objects. Basically each time we add an elements to the arraylist, there is a 1 in 4 chance each element will be chosen. I thought of one way to do it but I think there is a better, more "pretty" & effective way
just rough pseudo-code to help explain
for(int i = 0; i != 100; i++){
Random generator = new Random();
int i = generator.nextInt(4); // this will give us 0,1,2,or 3
if(i ==0){
arraylist.add(object1(param1, param2));
}
// etc.. continues with 3 other else if statments and objects
ideas? All the other objects I have also share the same interface, if that can help us
Start with an array containing the four objects:
Object[] objects = new Object[] {
object1(param1, param2),
object2(param1),
object3(param1, param2, param3, param4),
object4(param1, param2)
}
Then adjust your code:
Random generator = new Random();
for(int i = 0; i < 100; i++){
int j = generator.nextInt(4); // this will give us 0,1,2,or 3
arraylist.add(objects[j]);
// etc.. continues with 3 other else if statments and objects
}
Notice that you don't have to create a new generator on every iteration - you can create it just once and reuse the same instance.

Categories