0

I'm trying to create a poker program that will generate a hand of 5 random cards. One problem that I've run into is that the program will occasionally generate the same card twice.

THe best way I've thought of to fix this would be to implement a while loop that looks like this.

while (randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3) { 

randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   

}

This breaks the syntax of a while loop though and refuses to run.

Is there any way to create a while loop similar to the one above with many complex conditions... only one that's syntactically valid?

Thanks!

1
  • 1
    Wrap that whole condition in () and it'll probably work. Commented Apr 12, 2013 at 15:21

4 Answers 4

3

Yes, add more parenthesis.

while ((randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3))  {
    // Do whatever
}

A while loop will test everything in the parenthesis immediately following the while keyword. You can nest conditions infinitely within those parenthesis using more parenthesis or whatever operators you please, as long as whatever is in those parenthesis can be evaluated to true or false.

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

Comments

1

it looks like you're missing a parenthesis

while ((randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 &&      randSuit2 == randSuit3)) { 

randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   

}

Comments

1

Just use parenthesis to group a condition, like this :

while( (randFace == randFace2 && randSuit == randSuit2) || (randFace2 == randFace3 && randSuit2 == randSuit3)) { 
randSuit2 = Math.round(Math.random()*3);                    
randFace2 = Math.round(Math.random()*13);   
}

Comments

0

It sounds to me like a XY problem, so notice that this answer doesn't reply to the question's subject but to the problem itself.

First, you should use Math.floor, because Math.round will give you a non-uniform distribution:

function randomInt(max) {
    return Math.floor(Math.random() * (max + 1))
} 

Then you have to store all this values somewhere, right? So why you don't use an object or an array? I would assume you're using a deck of 52 cards. If you have a convention like:

  • Hearts: index 0 - 12
  • Diamonds: index 13 - 25
  • Clubs: index 26 - 38
  • Spades: index 39 - 51

Then your "deck" representation is just an array of int:

var deck = [];
for (var i = 0; i < 52; i++)
  deck.push(i);

Now you can create a "playing deck" just shuffling the regular one:

// Using the Fisher Yates shuffle: http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

function shuffle(array) {
  var len = array.length;
  var shuffled = array.slice();

  while (len--) {
    random = randomInt(len + 1);
    // swap
    shuffled[len] = [shuffled[random], shuffled[random] = shuffled[len]][0];
  }

  return shuffled;
}

// creating a new, shuffled deck from the original
var playingDeck = shuffle(deck);

And use the playingDeck to actually distribute your card. Let's say you want to give the first 5 cards to a player1:

var player1Hand = playingDeck.splice(0, 5);

Then your player1Hand will be a five elements array, where the elements are token from the "top of the playing deck" (the first five elements). Therefore if you're querying now the playingDeck.length, will be 47. You want to give other 5 cards to the player 2? Same code:

var player2Hand = playingDeck.splice(0, 5);

And if you want to shuffle the card in the middle of the game? Just shuffle the playingDeck and assign it to itself:

playingDeck = shuffle(playingDeck);

You could also draw a single card from the top:

var card = playingDeck.shift();

(Notice that in this case it's not a list of card – array - but a card itself – number.)

And basically use any Array methods you want, simulating a real deck.

As you can see it's a more natural way to deal with simulated cards, you don't have to concatenate many condition in your loop to draw some cards.

I would use the convention I mentioned at the beginning, but keep in mind that if you want to have a different representation of the card it's okay too: the method described still works and you don't have to change the code; only the array's value are different, so only the generation of the deck. For instance, you could have strings:

var deck = ["1H", "2H", /*etc*/, "10H", "JH", "QH", "KH", /* etc */];

Where the last letter is the suit, and the remains are the value of the card. Or you could actually use an object too:

var deck = [{"suit": "Hearts", "face": "1"}, /* etc */];

It really doesn't matter. What makes easier for you to deal with. But the rest of the approach will be still the same.

Hope it helps!

4 Comments

Thanks so much Zero! I really appreciate your responce.
Some of these suggestions are a little beyond my level... but one thing I'm definately curious about is the Math.random method. I'm trying to generate one of four random suits. Each are paired with an array index between 0 & 3. If I use randSuit2 = Math.floor(Math.random()*4); isn't there a chance I could generate the number 4? How would I avoid that? Thanks again! These comments are super helpful.
If you have any doubt, feel free to ask, I can imaging that a couple of things could be not immediate to understand. About your question, if you're using Math.floor(Math.random() * 4) there is no chance you will generate the number 4. That's because Math.random generates a floating point number between 0 (inclusive) and 1 (exclusive), so you could have maybe 0.99 * 4, that is 3.96, and because Math.floor returns the largest integer less than or equal to a number, the results will be 3.
Perfect! That makes much more sense. Thanks!

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.