-1

Using edwards revised code, i now have this:

        int k, l, tempA, tempB;
    for (k = 0; k < 13; k++) {
    for (l = 0; l < 4; l++) {
    tempA = rndm.get(k);
    tempB = suit.get(l);
    // increment # and convert into string
    buttonNumber++;
    buttonName = Integer.toString(buttonNumber);
    // assign new button to the array
    cardButton[k * 4 + l] = new JButton(buttonName);
    // assign button image icon
    cardButton[k * 4 + l].setIcon(cardImage[tempA][tempB]);
    // assign value to the check variable
    check[k * 4 + l] = Integer.toString(tempA+1);
    // make button invisible for now
    cardButton[k * 4 + l].setVisible(false);
    // add the button to the board
    board.add(cardButton[k * 4 + l]);
}

}

but my problem with this is that I need a replacement for the nested loop because the way it is set up now, it displays x value in 4 different suits before displaying the next value, when what i need is for it to display x value and x suit without repeating a value once, unless done randomly. The reason this is happening is because of the nested loop which iterates through k once, and then through l four times.

  • 1
    When `l` is 4, what does `j < 52 || k < 13 || l < 4` evaluate to? – shmosel Jun 23 '16 at 00:17
  • "But my problem is that i've set the values within the array beforehand," Clearly you think you have values in the array, but you are wrong. The ArrayList hasn't just decided that your 4 items are numbered 5-9 instead of 0-3 like everyone elses. Hmmm. Index 4 where available values are 0, 1, 2, 3... – John3136 Jun 23 '16 at 00:19
  • Get rid of every instance of `j`. You don't need any of it, including the `for-loop`. Then, replace every instance of `j` with `k * 4 + l`, and place your code inside the `l` loop, where `tempA` and `tempB` are being defined. That should fix it. – xes_p Jun 23 '16 at 00:40
  • I've edited my answer to display the full block of code that you should have. – xes_p Jun 23 '16 at 00:43
  • ive edited the question and hopefully you can help resolve it – Carlos Gordillo Jun 23 '16 at 01:30

3 Answers3

0

I believe your for-loop condition is incorrect. j < 52 || k < 13 || l < 4 will return true until j >= 52. Looking at your code, this throws an out of bounds error because k and l will also increase to 52. If I were you, I'd place them in separate conditions.

It appears (according to your comment) that you want to iterate over a 2D array. In that case, I'd use 2 for-loops:

for (k = 0; k < 13; k++) {
    for (l = 0; l < 4; l++) {
        tempA = rndm.get(k);
        tempB = suit.get(l);
        cardButton[k * 4 + l].setIcon(cardImage[tempA][tempB]);
        check[k * 4 + l] = Integer.toString(tempA+1);
    }
}

Note that we're replacing your j variable with some math instead. Every time you go through your l loop, k is incremented by one. Thus, we can tell what card we're on by multiplying k by 4, since l goes through 4 times. If we add l, we can get the current card that you're looking at. This code should work right out of the box.

Edit: Your full code should be as followed.

int k, l, tempA = 0, tempB = 0;
    // create temporary variables
for (k = 0; k < 13; k++) {
    for (l = 0; l < 4; l++) {
        tempA = rndm.get(k);
        tempB = suit.get(l);
        // increment # and convert into string
        buttonNumber = buttonNumber+1;
        buttonName = Integer.toString(buttonNumber);
        // assign new button to the array
        cardButton[k * 4 + l] = new JButton(buttonName);
        // assign button image icon
        cardButton[k * 4 + l].setIcon(cardImage[tempA][tempB]);
        // assign value to the check variable
        check[k * 4 + l] = Integer.toString(tempA+1);
        // make button invisible for now
        cardButton[k * 4 + l].setVisible(false);
        // add the button to the board
        board.add(cardButton[k * 4 + l]);
    }
}

Also, instead of doing buttonNumber = buttonNumber + 1, you can use buttonNumber++

xes_p
  • 501
  • 4
  • 14
  • I've tried that, but this seems to be the only way, could you help me figure this out if i post the rest of the code? – Carlos Gordillo Jun 23 '16 at 00:18
  • What are you trying to accomplish with that loop? – xes_p Jun 23 '16 at 00:19
  • // assign button image icon cardButton[j].setIcon(cardImage[tempA][tempB]); // assign value to the check variable check[j] = Integer.toString(tempA+1); // make button invisible for now – Carlos Gordillo Jun 23 '16 at 00:19
  • there are 52 buttons, k is = 13 because there are 13 cards per suit and 4 suits total (l) – Carlos Gordillo Jun 23 '16 at 00:20
  • Please see my revised answer. – xes_p Jun 23 '16 at 00:26
  • thanks dude, idk if that will work by removing the j variable because i need it for the rest of the code, but this works very well for this sort section of code, I will implement it and let you know what my results are. – Carlos Gordillo Jun 23 '16 at 00:30
  • @CarlosGordillo if you need to have a `j` variable, then initialize the variable outside the loop, and increment it every time it goes through the `l` loop. – xes_p Jun 23 '16 at 00:33
  • for the full code, its assigning images to the cards in a weird way, the k value works fine and randomizes a number then assigns it to the button but as I expected, the nested for loop makes it so that there are 4 of the same cards (6 for example) in each suit (spade, heart, etc) instead of being a random number with a random suit, its the same number 4 times in its different suits, that is why i attempted to put all the variables in one for loop, to avoid the fact that the nested loop would go through k once, then l 4 times. – Carlos Gordillo Jun 23 '16 at 01:00
  • Yes, because that's how many there are in a deck, correct? If you're looking to shuffle the deck, then that's a different question. My answer achieves what your question was originally asking. – xes_p Jun 23 '16 at 01:03
  • What I need is for the code to randomize a number AND suit and place the image on cardButton, i want it to go through k and l together instead of k once and l 4 times, which is what the nested loop achieves – Carlos Gordillo Jun 23 '16 at 01:07
  • I'd take a look at [this question and answer](http://stackoverflow.com/questions/1519736/random-shuffling-of-an-array) and apply what you learn there to shuffle your cards. – xes_p Jun 23 '16 at 01:20
  • I already have the shuffling through the use of collections.shuffle(rndm) and collections.shuffle(suit), my problem is i need to get past the nested loop doing k once and l four times instead of k once, l once. – Carlos Gordillo Jun 23 '16 at 01:27
0

If you're trying to get every permutation of rndm and suit, you'll need a nested loop:

for (int i = 0; i < 13; i++) {
    for (int j = 0; j < 4; j++) {
        tempA = rndm.get(i);
        tempB = suit.get(j);
        //...
    }
}
shmosel
  • 49,289
  • 6
  • 73
  • 138
0

You are misunderstanding how logical operators work. Double vertical bar is "or" operator. It takes two expressions that can be casted to boolean values and returns true if at least one of them is true.

boolean test = (1 == 2 || 5 < 3);
// test == true

Your for loop is iterating outside of the array bounds. Let's simplify your code a little bit. Let's create two arrays with fixed size, 1 and 2 elements, and then iterate over them in a loop similar to yours.

Integer[] arrayA = new Integer[1];
Integer[] arrayB = new Integer[2];

for (int i = 0, j = 0; i < 1 || j < 2; i++, j++) {
    arrayA[i] = i; // Will throw ArrayIndexOutOfBounds
    arrayB[j] = j;
}

Now, let's see how the counters will change during loop execution:

  1. i == 0 and j == 0, i < 1 == true and j < 2 == true, we increment both
  2. i == 1 and j == 1, i < 1 == false but still j < 2 == true, one of the conditions is true (and we need only one to be true in order for || operator to return true) so the loop code is executed even though i index is out of bounds!

Your code throws an exception for the same reason. Even though l < 4 == false, whole condition evaluates to true, therefore loop code will be executed.

What you want is to change all of the || operators to &&:

for (j = 0, k = 0, l = 0; j < 52 && k < 13 && l < 4; j++, k++, l++)

You can read more about boolean algebra and difference between and and or operators here - http://www.tutorialspoint.com/computer_logical_organization/boolean_algebra.htm

On a side note, don't do loops like that. So many variables in one statement are very confusing, as you might have noticed. Consider using enchanced for loops if you are always accessing objects with the exact same index as your counter variable.

Jezor
  • 3,253
  • 2
  • 19
  • 43
  • im now getting a different error: Exception in thread "main" java.lang.NullPointerException – Carlos Gordillo Jun 23 '16 at 00:38
  • please let me know how this can be fixed – Carlos Gordillo Jun 23 '16 at 00:43
  • I wrote it in the answer, depending on what you'd like to do (because I'm not sure about it), you should replace `or` operators with `and`s like that: `for (j = 0, k = 0, l = 0; j < 52 && k < 13 && l < 4; j++, k++, l++)`. – Jezor Jun 23 '16 at 00:46
  • well yes, replacing the or operates with ands solved the previous problem but is now giving me a different error: Exception in thread "main" java.lang.NullPointerException – Carlos Gordillo Jun 23 '16 at 00:52