Reputation: 3
I made this for class to get 7 random cards. Now want to modify it to get 21 random cards that are not repeating. I am trying to build another program that is a card guessing game. I have modified it to give me 21 cards but I always get repeating cards. I was thinking maybe use a seed. But I dont know enough about them to use them effectively.
import java.util.*;
public class SuchaDeal
{
public static void main(String[] args)
{
Random generator = new Random();
int i = 1;
String cardSuit;
int card; // a card number from 0 to 51
int cardNum;
String cardRank = "";
while (i <= 21) // loop through 21 times
{
card = generator.nextInt(52); // Returns 0 – 51
cardNum = card % 13; // number between 0-12 for the rank
//classify card into suits here
if ( card <= 12)
{
cardSuit = " Clubs ";
}
else if ( card >= 13 && card <= 25 )
{
cardSuit = " Diamonds ";
}
else if ( card >= 26 && card <= 38)
{
cardSuit = " Spades ";
}
else
{
cardSuit = " Hearts ";
}
//name the ranks
switch (cardNum)
{
case 0: cardRank = "Ace"; break;
case 10: cardRank = "Jack"; break;
case 11: cardRank = "Queen"; break;
case 12: cardRank = "King"; break;
default: cardRank = "" + (cardNum + 1);
}
//print the results
System.out.println("Card " + i + " is a " + cardRank + (" of ") + cardSuit);
i++; // increment the counter
}
}
}
I know it is not the most pretty code but this is one of the first programs that I am going to write in java.
Upvotes: 0
Views: 257
Reputation: 2745
If you want to use this approach, you should increment i
only when the card you've made is unique, perhaps storing the created cards in some array, and then checking if the newly generated card is already present, discarding it and re-running the loop/calculation if it is present.
However, if you're going to build a full deck, this approach is pretty naive - because the likelihood of randomly producing a unique card gets lower and lower as the number of cards already produced gets higher and higher. (Once you have 51 cards, you'll likely have to run this loop upwards of 52 times before you randomly generate the only remaining card)
Instead, you could build out a deck of 52 cards programmatically, or as a hard-coded array, and then use a shuffling algorithm like Fisher-Yates:
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
Now, you have a 'full deck' that's been randomly shuffled. Then, take the first 21 cards using Arrays.copyOfRange
:
Arrays.copyOfRange(cardArray, 0, 20);
Upvotes: 2
Reputation: 40066
As suggested in comment, you should do a deck shuffling instead of generating individual cards by random.
Another suggestion I will give is to properly model a card and suit.
pseudo-code:
enum Suit {
SPADE, HEART, DIAMOND, CLUB
}
class Card {
private Suit suit;
private int number; // 1 = Ace... 13 = King
Card(Suit suit, int number) {....}
// Getters, toString(), equals(), hashCode()
// no setters, as this is good candidate for immutable class
}
Main logic
List<Card> deck = new ArrayList<>();
for (suit : Suit.values) {
for (num = 1 to 13) {
deck.add(new Card(suit, num));
}
}
// now you have a deck of 52 cards
// shuffle the decek
Collections.shuffle(deck);
// take first 20 card from deck, by whatever way you like
Upvotes: 0