0

Here is the code:

basically, this code prints out 52 cards with the suit + rank.

package javaapplication52;

public class JavaApplication52 {

    public static void deck() {

        String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
        String[] rank = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack",
                "Queen", "King", "Ace" };

        // avoid hardwired constants
        int SUITS = suit.length;
        int RANKS = rank.length;
        int N = SUITS * RANKS;
        // initialize deck
        String[] deck = new String[N];
        for (int i = 0; i < RANKS; i++) {
            for (int j = 0; j < SUITS; j++) {
                deck[SUITS * i + j] = rank[i] + " of " + suit[j];

            }
        }
        // shuffle
        for (int i = 0; i < N; i++) {
            int r = i + (int) (Math.random() * (N - i));
            String t = deck[r];
            deck[r] = deck[i];
            deck[i] = t;
        }

        // print shuffled deck
        for (int i = 0; i < N; i++) {
            System.out.println(deck[i]);

        }

    }

    public static void main(String[] arg) {

        JavaApplication52 d = new JavaApplication52();

        d.deck();

    }
}

The code that made no sense to me

deck[SUITS * i + j] = rank[i] + " of " + suit[j]

What i did not under stand was, why did they multiply SUITS multiply I then added j. What was confusing was SUITS ( which is equals to 4), multiplied i ( which is 13), then added j ( which ( has the value of 4), does not equal 52 at all. So please explain, how this function worked.

Shashi
  • 12,487
  • 17
  • 65
  • 111
pur3extrme
  • 75
  • 1
  • 2
  • 10
  • 3
    Maxmium value of `i` is 12, `j` is 3. So 4 * 12 + 3 = 51 (52nd value of array). – Mics Jul 15 '13 at 05:13
  • I wrote similar code in C# and just by adding this line in the inner for loop after the line which is confusing you, make things self explanatory Console.WriteLine("deck[{0}]={1}", SUITS * i + j, deck[SUITS * i + j]); (Please convert it into Java based output for console (or command prompt)...and then try to understand.. – Nitin Agrawal Jul 15 '13 at 05:18
  • 2
    you should visit http://codereview.stackexchange.com/ – zEro Jul 15 '13 at 06:14

5 Answers5

5

Your i variable will only go between 0 and 12, and j variable will go 0 to 3, so maximum value for the index is 4 * 12 + 3 = 51, which is the maximum index of your deck. Such a deck would have 52 elements, making sense for a deck of cards.

Kon
  • 10,702
  • 6
  • 41
  • 58
4

It is a common idiom to put a 2D array of things into a 1D array by something like this:

for (row = 0; row < ROWS; ++row) {
    for (col = 0; col < COLUMNS; ++col) {
        array[row * ROWSIZE + col] = . . .
    }
}

this is called unrolling the matrix in "row major order", that is, each row is filled before starting on the next row. Instead of actual row indicies, each row starts in the 1D array at the row number * the row size (and row size is just the number of columns). Using "ROWSIZE" instead of "COLUMNS" makes the code clearer.

You can also do it in "column major order", like this:

. . . array[col * ROWS + row] = . . .

Let's say you had 3 rows and 4 columns. The first code would fill the array like this:

0 1 2 3 4 5 6 7 8 9 10 11

the latter would fill the array like this:

0 4 8 1 5 9 2 6 10 3 7 11

...but since the very next thing he does is shuffle the array, it doesn't matter what order it is created in.

As an aside, using strings for cards is a terrible idea. Check out representing playing cards in software.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • i was intrigued by your mention of row major order, but i could not relate your row major order formula with the one provided in question. If i'd relate suits to rows and ranks to columns then your formula doesn't fit and same happens for vice and versa. On wikipedia the row major order formula is different : row * COLUMNSIZE + col. Can you please have a look at it or relate it with the question ? Anyways +1 for explaining the algo. – Sikorski Jul 15 '13 at 06:37
  • I don't see the text you mention. The Wikipedia article I see says `offset = row*NUMCOLS + column`, which is correct. (As I said, "row size" and "number of columns" are the same thing). – Lee Daniel Crocker Jul 15 '13 at 06:40
2

the index "i" will take the value from 0 to 12

slaterade
  • 454
  • 4
  • 8
2
// avoid hardwired constants
    int SUITS = suit.length;
    int RANKS = rank.length;
    int N = SUITS * RANKS;
    // initialize deck
    String[] deck = new String[N];
    for (int i = 0; i < RANKS; i++) {
        for (int j = 0; j < SUITS; j++) {
            deck[SUITS * i + j] = rank[i] + " of " + suit[j];

        }
    }

SUITS has a length of 4, RANKS has a length of 12, and N has a size of 52 (meaning that String[] deck has 52 positions)

Therefore, int i = 0; i < RANKS; i++ will go from 0 to 12, and int j = 0; j < SUITS; j++ will go from 0 to 3.

Therefore, 4 * 12 + 3 is 51 - or card 52.

Singular1ty
  • 2,577
  • 1
  • 24
  • 39
  • I took out SUITS * 1 + j and replaced with 52; it gave me an error, is their a difference? – pur3extrme Jul 15 '13 at 05:30
  • @pur3extme sorry, bad math on my behalf. There are 52 positions in the array - but arrays are 0-indexed, so 51 is the largest position you could use. I'll edit my post. – Singular1ty Jul 15 '13 at 05:46
  • it still gave me null – pur3extrme Jul 15 '13 at 05:56
  • Well if you replace `SUITS*i + j` with a fixed number, only that array position will be assigned a value. Every other value in the array would just output as null. – Singular1ty Jul 15 '13 at 06:01
  • @pur3extrme The code above works fine, it the explanation is simply getting your head around the ranges of `i` and `j`, along with remembering arrays are 0-indexed. – Singular1ty Jul 15 '13 at 06:02
1

before it's shuffled; it is basically a 2-dimensional array over a linear array ..

ARRAY[CURRENT_ROW][CURRENT_COLUMN]

= ARRAY[(NUMBER_OF_COLUMNS * CURRENT_ROW) + CURRENT_COLUMN]

Where indices CURRENT_ROW and CURRENT_COLUMN start from 0

Khaled.K
  • 5,828
  • 1
  • 33
  • 51