0

I have an array containing all 52 cards in a deck.

ImageIcon[] cards = {aceSpadesIcon, twoSpadesIcon, ... }

Then I shuffle that array

for(int i = 0; i < cards.length; i++)
{
    int r = (int)(Math.random()*(i+1));
    ImageIcon swap = cards[r];
    cards[r] = cards[i];
    cards[i] = swap;
} 

Now I make four new arrays to fill with the cards array.

ImageIcon[] row1 = new ImageIcon[13];
ImageIcon[] row2 = new ImageIcon[13];
ImageIcon[] row3 = new ImageIcon[13];
ImageIcon[] row4 = new ImageIcon[13];

Now I fill these arrays with the now random cards array

int j = 0;  
            while(j < cards.length)
            {
                if(j <= 13)
                {
                    Arrays.fill(row1, cards[j]);
                    j++;
                }
                else if(j <= 26)
                {
                    Arrays.fill(row2, cards[j]);
                    j++;
                }
                else if(j <= 39)
                {
                    Arrays.fill(row3, cards[j]);
                    j++;
                }
                else
                {
                    Arrays.fill(row4, cards[j]);
                    j++;
                }
            }

Then I display it in a swing window but I have some errors. I should have 4 rows with 13 diffrent random cards each, but instead I get 4 rows each with 1 random card displayed 13 times. How can I fix my loop so it fills the arrays with different cards?

enter image description here

1
  • What is row1? Could you not simply iterate over the different values as before? Commented Feb 5, 2014 at 4:11

5 Answers 5

2

Use System.arraycopy to fill the rows:

public static void main(String[] args) {
    Integer[] allCards = new Integer[52];
    for (int i = 0; i < allCards.length; i++) {
        allCards[i]=i;
    }
    List<Integer> cardList = new ArrayList<Integer>(Arrays.asList(allCards));
    Collections.shuffle(cardList);
    Integer[] cards = cardList.toArray(allCards.clone());

    Integer[] row1 = new Integer[13];
    Integer[] row2 = new Integer[13];
    Integer[] row3 = new Integer[13];
    Integer[] row4 = new Integer[13];

    int index = 0;
    System.arraycopy(cards, index, row1, 0, 13);
    index+=13;
    System.arraycopy(cards, index, row2, 0, 13);
    index+=13;
    System.arraycopy(cards, index, row3, 0, 13);
    index+=13;
    System.arraycopy(cards, index, row4, 0, 13);

    System.out.println(Arrays.toString(cards));
    System.out.println(Arrays.toString(row1));
    System.out.println(Arrays.toString(row2));
    System.out.println(Arrays.toString(row3));
    System.out.println(Arrays.toString(row4));


}
Sign up to request clarification or add additional context in comments.

Comments

0

Check the javadoc for Arrays.fill it sets all array's elements to the specified value. What you need is row1[j] = cards[j], and so on. BTW, if I were you I would iterate just 13 times in a loop setting row1[j] = cards[j], row2[j] = cards[j+13], etc. as this shows your intent more clearly.

Comments

0

From the Java SE 7 docs:

fill
public static void fill(Object[] a,
        Object val)

Assigns the specified Object reference to each element of the specified array of Objects.

Parameters:
    a - the array to be filled
    val - the value to be stored in all elements of the array
Throws:
    ArrayStoreException - if the specified value is not of a runtime type that can be stored in the specified array

So what you're doing is (repeatedly) filling each array with one value. What you'd want would be something more along the lines of:

while(j < cards.length)
        {
            if(j < 13)
            {
                row1[j] = cards[j];
            }
            else if(j < 26)
            {
                row2[j%13] = cards[j];
            }
            else if(j < 39)
            {
                row3[j%13] = cards[j];
            }
            else
            {
                row4[j%13] = cards[j];
            }
            j++;
        }

This is still pretty messy (avoid hard-coded constants if at all possible) but at least it will do what you set out to do. Note your original array should be 0-indexed, so your logic should shift over one. Also, try and avoid duplicated code (notice the increment happening only once since it is common to all passes through the loop).

Comments

0

Do not use Arrays.fill, that is filling the entire array with the value you give it. Try something like this maybe:

for (int j = 0; j < cards.length; j++)
{
    if(j < 13)
    {
        row1[j] = cards[j];
    }
    else if(j < 26)
    {
        row2[j - 13] = cards[j];
    }
    else if(j < 39)
    {
        row3[j - 26] = cards[j];
    }
    else
    {
        row4[j - 39] = cards[j];
    }
}

Comments

0

Simply assign the array like following

            if(j <= 13)
            {
                row1[j] = card[j];
                j++;
            }

from the doc of Arrays.fill

Assigns the specified boolean value to each element of the specified array of booleans.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.