TheCardyMan
TheCardyMan

Reputation: 11

Java code stuck in infinitely repeating while loop

I have some code that shuffles a deck of cards by assigning randomly chosen cards from a 2D array cards into an ArrayList deck, but when I run the code it gets stuck in an infinite loop.

It was working fine at first but seemed to randomly stop working with little change to the code.

cards is a 13 x 4 array with a different card in each position.

ArrayList<String> deck = new ArrayList<String>();
        for (int i = 0; i < 52; i++)  {
            int v = 0;
            int s = 0;
            Boolean notInDeck = false;
            while (!notInDeck) {
                v = rand.nextInt(13);
                s = rand.nextInt(4);
                if (!deck.contains(cards[v][s])) {
                    notInDeck = true;
                    deck.add(cards[v][s]);
                }
            }
        }

I tried adding outputs at different points to try and track what was happening

ArrayList<String> deck = new ArrayList<String>();
        for (int i = 0; i < 52; i++)  {
            System.out.println("1");
            int v = 0;
            int s = 0;
            Boolean notInDeck = false;
            while (!notInDeck) {
                System.out.println("2");
                v = rand.nextInt(13);
                s = rand.nextInt(4);
                if (!deck.contains(cards[v][s])) {
                    System.out.println("3");
                    notInDeck = true;
                    deck.add(cards[v][s]);
                }
                System.out.println("4");
            }
            System.out.println("5");
        }
        System.out.println("6");

There are no error messages.

The output is fine for the first bunch of run-throughs, being 1 2 3 4 5 1 2 3 4 5, but ends up infinitely repeating 2 4 2 4 2 4...

It should be like 1 2 3 4 5 1 2 3 4 5 then maybe sometimes 1 2 4 2 3 4 5 when it repeats a set of random numbers.

Here is my code for the cards 2D array.

String[][] cards = new String[13][4];

        String suit = " ";
        String value = "";

        for (int i = 0; i < 13; i++)  {
            for (int j = 0; j < 4; j++)  {
                if (j == 0) {
                    suit = "C";
                } else if (j == 1) {
                    suit = "H";
                } else if (j == 2) {
                    suit = "S";
                } else if (j == 3) {
                    suit = "D";
                }
                if (i == 0) {
                    value = "A";
                } else if (i == 10) {
                    value = "J";
                } else if (i == 11) {
                    value = "Q";
                } else if (i == 12) {
                    value = "K";
                } else {
                    value = Integer.toString(i+1);
                }
                cards[i][j] = value;
            }
        }

Edit: I realised the issue was with this line

cards[i][j] = value;

It should be

cards[i][j] = value + " " + suit;

Upvotes: 1

Views: 105

Answers (2)

Yevgen
Yevgen

Reputation: 1667

It shouldn't run indefinitely unless you are having an unlucky day or have initialized cards array with wrong values.

So, this is what happening. Since you are using a random guess to put a card into the deck, with each attempt it's harder and harder for random generator to find, so to say, a card that was not placed in the deck yet. At the of the day you will have more and more attempts to place last cards correctly. The number of those attempts could reach hundreds and even thousands.

I have added a couple of lines to your code and visualized the problem on Ideone.

ArrayList<String> deck = new ArrayList<String>();

HashMap<Integer, Integer> guesses = new HashMap<>();

for (int i = 0; i < 52; i++) {
  int guess = 0;

  int v = 0;
  int s = 0;
  Boolean notInDeck = false;

  while (!notInDeck) {
    v = rand.nextInt(13);
    s = rand.nextInt(4);
    guess++;
    if (!deck.contains(cards[v][s])) {
      notInDeck = true;
      deck.add(cards[v][s]);
      guesses.put(i, guess++);
    }
  }

}

for (Map.Entry<Integer, Integer> entry: guesses.entrySet()) {
  System.out.printf("%2s : %s\n", entry.getKey(), entry.getValue());
}

If you execute the code several times, you will clearly see the pattern—the number of guesses grows significantly at the end.

Upvotes: 1

Antoniossss
Antoniossss

Reputation: 32550

You are making your life harder.

In real life, you are not taking gazillion of cards and you are not randomly picking cards until you complete full 52 cards deck. In fact, you start with 52 cards and you suffle them. Do the same here

  1. Create collection of 52 cards
  2. Shuffle that collection (eg. with Collections.shuffle)

While this is simply linear operation, your solution is indeterministic.

Upvotes: 2

Related Questions