Home > Software design >  Java: Questions about using nested loops to create a deck of cards
Java: Questions about using nested loops to create a deck of cards

Time:02-24

I am new to programming. I am trying to understand what the code means and how to create a deck of cards using a nested loop.

String [] rank = {"A" , "2" , "3", "4", "5", "6", "7", "8", "9", "10" , "J", "Q" , "K"};

String [] suit = {"C", "D", "S" , "H"};

String [] deck = new String [52]

I tried to write:

    for(int i = 0; i < rank.length; i  ){    
         for (int j = 0; j < suit.length; j  ){
             System.out.println(suit[i]   cards[j]);
           }
       }

but this will only print (CA, C2, C3, C4, DA...) my code will not print C5, C6...

but if I switch cards and suit, putting suit to outside loop, it will print all. I can't figure out why?

for(int i = 0; i < suit.length; i  ){
        for (int j = 0; j < rank.length; j  ){

Also, the answer key is:

    for(int i = 0; i < cards.length; i  ){    
        for (int j = 0; j < suit.length; j  ){
           deck[i   13*j] = rank [i]   suit [j];
               }
           }

I really don't understand what does deck[i 13*j] = rank [i] suit [j] mean?

The answer key indicates if we want to change deck to put the cards in rank order in the array, we only need to change the code to deck[4*i j] = rank [i] suit [j]

I was wondering if anyone can help me understand what does deck[4*i j] and deck [i 13*j] mean in the code?

How to change my code to print "AC, AD, AS, AH, 2C, 2D, 2S, 2H...)?

Sorry, it is hard to describe my questions. Thank you very much for your time and help!

CodePudding user response:

Since your counter variable i is iterating through your rank and j iterates through suit, switching the variables will output them correctly:

  for(int i = 0; i < rank.length; i  ){    
     for (int j = 0; j < suit.length; j  ){
         System.out.println(suit[j]   rank[i]);
       }
   }

Output:

CA
DA
SA
HA
C2
D2
S2
H2
C3
D3
S3
H3
C4
D4
S4
H4
C5
D5
S5
H5
C6
D6
S6
H6
C7
D7
S7
H7
C8
D8
S8
H8
C9
D9
S9
H9
C10
D10
S10
H10
CJ
DJ
SJ
HJ
CQ
DQ
SQ
HQ
CK
DK
SK
HK

However, if you want to store these values in the array, some more work is required.

i represents the current rank/value we are on while j represents the current suit we are on. If we want the list to go: {CA,DA,SA,HA,C2,D2....}, then we need to do some math.

i goes from 0 to 12 and j goes from 0 to 3. We want our first i-j pair, 0 and 0, to link to the first index of deck, 0, and our last i-j pair, 12 and 3, to link to our final index of deck, 51.

In terms of words, the index for every i-j pair is "the current rank we are on times 4 plus our current suite."

An "equation" to model this would be: Index = i * 4 j

Thus our code would be:

for(int i = 0; i < rank.length; i  ){    
     for (int j = 0; j < suit.length; j  ){
         deck[4 * i   j] = suit[j]   rank[i];
        
       }
   }

Alternatively you could think of it as "Multiply our current suite by 13 and add our rank" which produces the code you provided. This would order by the ranks so it would go like:

{CA,C2,C3,....DA,D2,D3....}

Either one works!

I hope this helped, please let me know if you need any further details or clarification :)

CodePudding user response:

As the Answer by Ani M explained, you mixed up your i and j. As this Comment explains, you mixed up your array names.

Let's improve your array names and contents. Usually a plural name makes more sense for a collection. And Unicode defines characters for card suits, so let's use them.

String[] ranks = { "A" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "Q" , "K" };
String[] suits = { "♠" , "♣" , "♥" , "♦" };  // Order in which they are defined in Unicode.
String[] deck = new String[ 52 ];

Using the for-each syntax rather than conventional for loop makes the code easier to read and write.

int index = 0;
for ( String rank : ranks )
{
    for ( String suit : suits )
    {
        deck[ index ] = rank   suit;
        index  ;
    }
}

Dump the results to console.

System.out.println( "deck = "   Arrays.toString( deck ) );

When run.

Arrays.toString( ranks ) = [A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K]
Arrays.toString( suits ) = [♠, ♣, ♥, ♦]
Arrays.toString( deck ) = [A♠, A♣, A♥, A♦, 2♠, 2♣, 2♥, 2♦, 3♠, 3♣, 3♥, 3♦, 4♠, 4♣, 4♥, 4♦, 5♠, 5♣, 5♥, 5♦, 6♠, 6♣, 6♥, 6♦, 7♠, 7♣, 7♥, 7♦, 8♠, 8♣, 8♥, 8♦, 9♠, 9♣, 9♥, 9♦, 10♠, 10♣, 10♥, 10♦, J♠, J♣, J♥, J♦, Q♠, Q♣, Q♥, Q♦, K♠, K♣, K♥, K♦]

So that code addresses your question of:

How to change my code to print "AC, AD, AS, AH, 2C, 2D, 2S, 2H...)?

As for your answer-key solution, the clever math is explained in the other Answer by Ani M. I will simply add a note that such clever code can be more of a liability than an aid in real work. When trying to fix a bug in the middle of the night, such code can be a nightmare to debug and modify. Writing stupid-simple code is often preferable to flashy clever solutions.


For fun, let's get final cards represented by specific Unicode characters.

We can determine a character by its official name designated by the Unicode Consortium. See this Answer on another Question about using Character.codePointOf(String name) method.

String[] ranks = { "ACE" , "TWO" , "THREE" , "FOUR" , "FIVE" , "SIX" , "SEVEN" , "EIGHT" , "NINE" , "TEN" , "JACK" , "QUEEN" , "KING" };
String[] suits = { "SPADES" , "CLUBS" , "HEARTS" , "DIAMONDS" };
String[] deck = new String[ 52 ];

int index = 0;  // Annoying zero-based counting.
for ( String rank : ranks )
{
    for ( String suit : suits )
    {
        String characterName = "PLAYING CARD "   rank   " OF "   suit;
        int codePoint = Character.codePointOf( characterName );
        String cardCharacter = Character.toString( codePoint );
        deck[ index ] = cardCharacter;
        index  ;
    }
}

Results:

Arrays.toString( deck ) = [

  • Related