0

I have 4 random variables...

int img1 = (int) Math.round((Math.random() * images.length)-1);
int img2 = (int) Math.round((Math.random() * images.length)-1);
int img3 = (int) Math.round((Math.random() * images.length)-1);
int img4 = (int) Math.round((Math.random() * images.length)-1);

I need to make sure that they never equal each other even though they're random. I am making an app where there is 4 imageviews that show a random shape (Saved in drawable folder). Below is an image of my app so you get a better understanding of what I mean...

shapegame

The 4 shapes in the bottom can never be the same however I need them to show randomly when the app is running. This is my code at the moment...

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    shape1 = (ImageView) findViewById(R.id.shape1);
    shape2 = (ImageView) findViewById(R.id.shape2);
    shape3 = (ImageView) findViewById(R.id.shape3);
    shape4 = (ImageView) findViewById(R.id.shape4);
    guessShape = (ImageView) findViewById(R.id.guessShape);
    shapes[0] = shape1;
    shapes[1] = shape2;
    shapes[2] = shape3;
    shapes[3] = shape4;

    //store all the shapes in an array
    int[] images = new int[] {R.drawable.img_0, R.drawable.img_1, R.drawable.img_2, R.drawable.img_3, R.drawable.img_4,
    R.drawable.img_5, R.drawable.img_6, R.drawable.img_7, R.drawable.img_8, R.drawable.img_9, R.drawable.img_10,
            R.drawable.img_11, R.drawable.img_12, R.drawable.img_13, R.drawable.img_14, R.drawable.img_15, R.drawable.img_16,
            R.drawable.img_17};

    int[] outlines = new int[] {R.drawable.outline_0, R.drawable.outline_1, R.drawable.outline_2,
            R.drawable.outline_3, R.drawable.outline_4, R.drawable.outline_5, R.drawable.outline_6,
            R.drawable.outline_7, R.drawable.outline_8, R.drawable.outline_9, R.drawable.outline_10,
            R.drawable.outline_11, R.drawable.outline_12, R.drawable.outline_13, R.drawable.outline_14,
            R.drawable.outline_15, R.drawable.outline_16,R.drawable.outline_17};

    //generate random number between 0 and image.length

    int img1 = (int) Math.round((Math.random() * images.length)-1);
    int img2 = (int) Math.round((Math.random() * images.length)-1);
    int img3 = (int) Math.round((Math.random() * images.length)-1);
    int img4 = (int) Math.round((Math.random() * images.length)-1);
    System.out.println(img1);
    System.out.println(img2);
    System.out.println(img3);
    System.out.println(img4);


    int whichImg = (int) Math.round((Math.random() * 4));

    System.out.println(whichImg);

    if(whichImg == 1){
        whichImg = img1;
    } else if(whichImg == 2){
        whichImg = img2;
    } else if(whichImg == 3){
        whichImg = img3;
    } else {
        whichImg = img4;
    }

    int outlineID = outlines[whichImg];

    //conditions so that the 4 boxes don't have the same image
    if(img1 == img2 && img1 !=0 || img1 == img3 && img1 != 0 || img1 == img4 && img1 != 0){ //if img1 and another img is the same

        img1 = img1 - 1;
    }
    else if(img2 == img3 && img2 != 0 || img2 == img4 && img2 != 0){ //if img2 and another img is the same
        img2 = img2 - 1;
    }

    else if(img3 == img4 && img3 !=0){ //if img3 and another image is that same
        img3 = img3 - 1;
    }
    else if(img1==0 && img2==0 && img3 == 0 && img4 == 0){ //if all the images were 0
        img1 = img1 + 10;
        img2 = img2 + 5;
        img3 = img3 + 7;
        img4 = img4 + 14;
    }
    else if(img1==img2 && img2 == img3 && img1 !=0 && img1 != 17){ //if img1 and 2 others were the same
        img1 = img1 - 1;
        img3 = img3 + 1;
    }
    else if(img2==img3 && img3 == img4 && img2 != 0 && img2 != 17){ //if img2 and 2 others were the same
        img2 = img2 - 1;
        img4 = img4 + 1;
    }
    else if(img3 == img4 && img4 == img2 && img3 != 0 && img3 != 17){ //if img3 and 2 others were the same
        img3 = img3 - 1;
        img2 = img2 + 1;
    }
    else if(img1 == 17 && img2 == 17 && img3 == 17 && img4 == 17){
        img1 = img1 - 1;
        img2 = img2 - 2;
        img3 = img3 -3;
    }
    else {
        System.out.println("Finished comparing 4 variables");//this doesnt work..fix!
    }

    //set the image
    guessShape.setBackgroundResource(outlineID);
    shape1.setBackgroundResource(images[img1]);
    shape2.setBackgroundResource(images[img2]);
    shape3.setBackgroundResource(images[img3]);
    shape4.setBackgroundResource(images[img4]);

There must be an easier way of making sure they never equal each other rather than so many if statements. Please help me !

Az Islam
  • 133
  • 11
  • 1
    Explain the logic you're using to handle the problem right now, or what you have tried, then we can help you improve it. – coinbird Apr 20 '17 at 18:31
  • 1
    Possible duplicate of [Generating Unique Random Numbers in Java](http://stackoverflow.com/questions/8115722/generating-unique-random-numbers-in-java) – 4castle Apr 20 '17 at 19:04
  • i used if statements @coinbird but it looks like a lot to write out, im new to coding (3 months precisely), i want to build my first app. But im logical enough to know with coding, there must be an easier way to make sure 4 random number variables dont ever be the same. – Az Islam Apr 20 '17 at 19:22

3 Answers3

1

If the total number of images is large, then just check each time you pick a new one whether it is already in your set. In the unlikely event that it is, reject it and pick again.

If the total number of images isn't so large, it's not so unlikely that a repeat occurs. In that case, pick the first one from the indexes 0 to (n-1). Then swap the one that you pick into position 0. Next, pick the second one from the indexes 1 to (n-1). Then swap that one into position 1. Continue until you have completed your set, which in your case will be in positions 0 to 3. (This algorithm is called the Fisher-Yates shuffle.)

David Wright
  • 765
  • 6
  • 15
0

Here are two possibilities:

First: Create a list with all the randoms, and just iterate through it.

final List<Integer> collect = IntStream.range(0, args.length).boxed().collect(Collectors.toList());
Collections.shuffle(collect);

Alternately, just get 4:

Set<Integer> randoms = new HashSet<>();
Random r = new Random();
while(randoms.size() < 4){ randoms.add(r.nextInt(args.length)); }
Turing85
  • 18,217
  • 7
  • 33
  • 58
Kylar
  • 8,876
  • 8
  • 41
  • 75
  • i like the second option. Now that I implement that, what do i used that in my game? do I put shape1.setBackgroundResource(randoms.get(0));? – Az Islam Apr 20 '17 at 19:37
  • That seems logical. – Kylar Apr 20 '17 at 20:03
  • I can't get an element from randoms? – Az Islam Apr 20 '17 at 20:23
  • I mean it is, it's me saying I can't actually get an element from the HashSet called 'randoms' you suggested. You said "That seems logical" to me asking you what I do next but in fact, there is no way to "get" an element from a HashSet. Your blunt responses suggest you have no more time for my problem. Cheers anyway pal – Az Islam Apr 21 '17 at 14:18
  • It appears that you don't know the difference, or how to use Sets vs Lists - Which, yes, I don't have time to answer. You should research that on your own, as there is lots of good documentation. You could take the elements of the Set and move them into a List, or use an iterator through the Set's elements. Read this question, and especially the third answer:http://stackoverflow.com/questions/8185090/is-there-an-insertion-order-preserving-set-that-also-implements-list – Kylar Apr 21 '17 at 16:56
0

If I understand your question properly that you need ANY four random numbers that don't equal each other, you may try this:

int max = 4; // the maximum number of the random numbers
Set<Integer> uniqueCollection = new HashSet<Integer>();
while(uniqueCollection.size()<max){
    uniqueCollection.add((int)(Math.random()*max*10)+1); // the 1 here for 0 values if any
}
for(Integer r : uniqueCollection){ // to test it
    System.out.println(r);
}
Yahya
  • 13,349
  • 6
  • 30
  • 42