How do you write a program that prints 20 random cards?

D

David

I have to write a program that prints 20 random cards (suit,
faceValue). I have to have a driver program and write a constructor
with my own methods. I am fairly new at java, and this concept is
confusing to me at the moment. So far, I have written both the driver
and constructor programs. However, they do not work. It compiles and
runs, but every card says "Spade null". I think it has something to
do with my random number generator. Please help. Here's my driver
program:

***********************************************************
import java.util.Random;

class CardGenerator
{
public static void main (String [] args)
{
// Use to get random numbers
Random generator = new Random();

// Print out to screen
System.out.println ("Dealing 20 random cards: ");


// repeat this loop 20 times to get 20 cards
for (int i=1; i<=20; i++)
{
// declare new object
Card myCard = new Card (1,1);

// get random numbers for suit and faceValue
int suit = generator.nextInt(4) +1;
int faceValue = generator.nextInt(13) +1;

// get number from my methods
suit = myCard.getSuit();
faceValue = myCard.getFaceValue();

// print card
System.out.println (myCard);
}
}
}

************************************************************
Here's the program with the constructor and my methods:
************************************************************

// import classes
import java.util.Random;

class Card
{

// declare variables
private int suit;
private int faceValue;
String cardType;
String suitType;

// constructor
public Card (int suit, int faceValue)
{
// call methods
getSuit();
getFaceValue();
}

// gets value for suit
public int getSuit()
{
return suit;
}

// gets value for faceValue
public int getFaceValue()
{
return faceValue;
}

// decides the suit and card according to the random number
picked
public String toString()
{
// if statements to get suit type
if (suit == 1)
suitType = "Heart";
else if (suit == 2)
suitType = "Diamond";
else if (suit == 3)
suitType = "Club";
else
suitType = "Spade";

// switch statement to get card type
switch (faceValue)
{
case 1:
cardType = "Ace";
break;

case 2:
cardType = "2";
break;

case 3:
cardType = "3";
break;

case 4:
cardType = "4";
break;

case 5:
cardType = "5";
break;

case 6:
cardType = "6";
break;

case 7:
cardType = "7";
break;

case 8:
cardType = "8";
break;

case 9:
cardType = "9";
break;

case 10:
cardType = "10";
break;

case 11:
cardType = "Jack";
break;

case 12:
cardType = "Queen";
break;

case 13:
cardType = "King";
break;

}

// returns string
return (suitType + "\t" + cardType);

}
}
******************************************************
If someone could help me, please do. Because I am stuck and lost
right now. Thanks.

David
 
T

The Law of Lorentz

I'm sorry, there are a lot of errors in your code, we can start with class
Card:
// constructor
public Card (int suit, int faceValue)
{
// call methods
getSuit();
getFaceValue();
}
In this constructor you have to set the variables not to read !!!!
then the correct is:
// constructor
public Card (int suit, int faceValue)
{
// call methods
this.suit = suit;
this.faceValue =faceValue;
}

Then in the class CardGenerator you write:
// repeat this loop 20 times to get 20 cards
for (int i=1; i<=20; i++)
{
// declare new object
Card myCard = new Card (1,1);

// get random numbers for suit and faceValue
int suit = generator.nextInt(4) +1;
int faceValue = generator.nextInt(13) +1;

// get number from my methods
suit = myCard.getSuit();
faceValue = myCard.getFaceValue();

// print card
System.out.println (myCard);
}
the correct code is:
// repeat this loop 20 times to get 20 cards
for (int i=1; i<=20; i++)
{
// declare new object
// get random numbers for suit and faceValue
int suit = generator.nextInt(4) +1;
int faceValue = generator.nextInt(13) +1;

Card myCard = new Card (suit , faceValue);
// get number from my methods
// suit = myCard.getSuit();
// faceValue = myCard.getFaceValue();
// print card
System.out.println (myCard);
}

Warning: with this program you probably exctract one card more times...
Try to think how change the code for manage the real situation...

I hope my suggestion is useful for you
Bye


David said:
I have to write a program that prints 20 random cards (suit,
faceValue). I have to have a driver program and write a constructor
with my own methods. I am fairly new at java, and this concept is
confusing to me at the moment. So far, I have written both the driver
and constructor programs. However, they do not work. It compiles and
runs, but every card says "Spade null". I think it has something to
do with my random number generator. Please help. Here's my driver
program:

***********************************************************
import java.util.Random;

class CardGenerator
{
public static void main (String [] args)
{
// Use to get random numbers
Random generator = new Random();

// Print out to screen
System.out.println ("Dealing 20 random cards: ");


// repeat this loop 20 times to get 20 cards
for (int i=1; i<=20; i++)
{
// declare new object
Card myCard = new Card (1,1);

// get random numbers for suit and faceValue
int suit = generator.nextInt(4) +1;
int faceValue = generator.nextInt(13) +1;

// get number from my methods
suit = myCard.getSuit();
faceValue = myCard.getFaceValue();

// print card
System.out.println (myCard);
}
}
}

************************************************************
Here's the program with the constructor and my methods:
************************************************************

// import classes
import java.util.Random;

class Card
{

// declare variables
private int suit;
private int faceValue;
String cardType;
String suitType;

// constructor
public Card (int suit, int faceValue)
{
// call methods
getSuit();
getFaceValue();
}

// gets value for suit
public int getSuit()
{
return suit;
}

// gets value for faceValue
public int getFaceValue()
{
return faceValue;
}

// decides the suit and card according to the random number
picked
public String toString()
{
// if statements to get suit type
if (suit == 1)
suitType = "Heart";
else if (suit == 2)
suitType = "Diamond";
else if (suit == 3)
suitType = "Club";
else
suitType = "Spade";

// switch statement to get card type
switch (faceValue)
{
case 1:
cardType = "Ace";
break;

case 2:
cardType = "2";
break;

case 3:
cardType = "3";
break;

case 4:
cardType = "4";
break;

case 5:
cardType = "5";
break;

case 6:
cardType = "6";
break;

case 7:
cardType = "7";
break;

case 8:
cardType = "8";
break;

case 9:
cardType = "9";
break;

case 10:
cardType = "10";
break;

case 11:
cardType = "Jack";
break;

case 12:
cardType = "Queen";
break;

case 13:
cardType = "King";
break;

}

// returns string
return (suitType + "\t" + cardType);

}
}
******************************************************
If someone could help me, please do. Because I am stuck and lost
right now. Thanks.

David
 
V

VisionSet

David said:
It compiles and
runs, but every card says "Spade null". I think it has something to
do with my random number generator. Please help. Here's my driver
program:

***********************************************************
import java.util.Random;

class CardGenerator
{
public static void main (String [] args)
{
// Use to get random numbers
Random generator = new Random();

// Print out to screen
System.out.println ("Dealing 20 random cards: ");


// repeat this loop 20 times to get 20 cards
for (int i=1; i<=20; i++)
{
// declare new object
Card myCard = new Card (1,1);

You only ever create cards of of this type (1,1)
// get random numbers for suit and faceValue
int suit = generator.nextInt(4) +1;
int faceValue = generator.nextInt(13) +1;

But you do nothing with the variables suit & faceValue
try:
Card myCard = new Card (suit,faceValue);
// get number from my methods
suit = myCard.getSuit();
faceValue = myCard.getFaceValue();

but you do nothing with the values.
// print card
System.out.println (myCard);
}
}
}

************************************************************
Here's the program with the constructor and my methods:
************************************************************

// import classes
import java.util.Random;

class Card
{

// declare variables
private int suit;
private int faceValue;
String cardType;
String suitType;

// constructor
public Card (int suit, int faceValue)

But you do nothing with these values you pass in.
{
// call methods
getSuit();
getFaceValue();

This does nothing, nothing is done with the values they retrieve, and the
values they retrieve are null, because the attributes are never set.
Don't call them here, try this:

this.suit = suit;
this.faceValue = faceValue;
}

// gets value for suit
public int getSuit()
{
return suit;
}

// gets value for faceValue
public int getFaceValue()
{
return faceValue;
}

// decides the suit and card according to the random number
picked
public String toString()

break this logic into two methods that can be called by getSuit() &
getFaceValue()
{
// if statements to get suit type
if (suit == 1)
suitType = "Heart";
else if (suit == 2)
suitType = "Diamond";
else if (suit == 3)
suitType = "Club";
else
suitType = "Spade";

// switch statement to get card type
switch (faceValue)
{
case 1:
cardType = "Ace";
break;
[2-10 snipped]
case 11:
cardType = "Jack";
break;

case 12:
cardType = "Queen";
break;

case 13:
cardType = "King";
break;

default: cardType = String.toString(faceValue); // a little
simpler!
 
N

Neal Gafter

David said:
I have to write a program that prints 20 random cards (suit,
faceValue). I have to have a driver program and write a constructor
with my own methods. I am fairly new at java, and this concept is
confusing to me at the moment. So far, I have written both the driver
and constructor programs. However, they do not work. It compiles and
runs, but every card says "Spade null". I think it has something to
do with my random number generator. Please help. Here's my driver
program:

Just a plug for the upcoming version 1.5 (Tiger) of the language: here's the
solution to your problem:


import java.util.*;
import static java.lang.System.*;

enum Suit { spades, hearts, diamonds, clubs }
enum Rank { deuce, three, four, five, six, seven, eight, nine,
ten, jack, queen, king, ace }
class Card {
final Suit suit;
final Rank rank;
public String toString() {
return rank + " of " + suit;
}
Card(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
}
class Main {
public static void main(String[] args) {
List<Card> deck = new ArrayList<Card>();
for ( Suit suit : Suit.VALUES )
for ( Rank rank : Rank.VALUES )
deck.add(new Card(suit, rank));
Collections.shuffle(deck);
for (int i=0; i<20; i++)
out.println((i+1) + ": " + deck.get(i));
}
}
 
B

Brad BARCLAY

David said:
I have to write a program that prints 20 random cards (suit,
faceValue). I have to have a driver program and write a constructor
with my own methods. I am fairly new at java, and this concept is
confusing to me at the moment. So far, I have written both the driver
and constructor programs. However, they do not work. It compiles and
runs, but every card says "Spade null". I think it has something to
do with my random number generator. Please help.

I'd suggest a different approach. An easier way of doing what you're
trying to do would be to create a deck of cards (by creating 52
instances of a Card class, each representing one of the standard 52
cards) by storing them in an array. Then, "shuffle" (randomize) the
cards in the deck, and pick off the first 20 cards. One good way of
shuffling the cards would be to pick any two random cards and swap their
locations in the array, and repeat a sufficiently large number of times.

Once the array has been randomized, as mentioned above, just take the
first 20 and do what you need to do with them. The advantage of this
method is that it will ensure that you don't select the same card twice.
It's easier to code, and will typically be more efficient to run.

HTH!

Brad BARCLAY
 
T

Tr0mBoNe-

Roedy Green said:
If you can get 20 random numbers 0..51 should be most of the way
there. All you have to do is eliminate dups. Use % to get suit and
number.

see http://mindprod.com/jgloss/randomnumbers.html

The simplist way to see this is that you only have to generate random
numbers between 1 and 13 inclusive, then 1 and 4 inclusive.

int nextCard = (Math.abs(rand.nextInt() % 13) + 1);
int nextSuite = (Math.abs(rand.nextInt() % 4) + 1);

this is all good to produce the numbers, then you can go through your
conditional statements or switches to produce names to each value.
 
R

Roedy Green

The simplist way to see this is that you only have to generate random
numbers between 1 and 13 inclusive, then 1 and 4 inclusive.

int nextCard = (Math.abs(rand.nextInt() % 13) + 1);
int nextSuite = (Math.abs(rand.nextInt() % 4) + 1);

this is all good to produce the numbers, then you can go through your
conditional statements or switches to produce names to each value.

you would write that more tersely as:

int nextCard = rand.nextInt( 13 );
int nextSuite = rand.nextInt( 4 );

You probably want 0..12 and 0..3 for indexing.

Be careful with %. It is a tricky operator. Best to do your abs first
before using it to avoid surprises.

See http://mindprod.com/jgloss/modulus.html
 
R

Roedy Green

One good way of
shuffling the cards would be to pick any two random cards and swap their
locations in the array, and repeat a sufficiently large number of times.

see Collections.shuffle
 
M

Michael Dunn

: I have to write a program that prints 20 random cards (suit,
: faceValue). I have to have a driver program and write a constructor
: with my own methods. I am fairly new at java, and this concept is
: confusing to me at the moment. So far, I have written both the driver
: and constructor programs. However, they do not work. It compiles and
: runs, but every card says "Spade null". I think it has something to
: do with my random number generator. Please help. Here's my driver
: program:
:
<snip>


Here's something to play around with, there might be something in it for you.
(wasn't sure of the best way for random, so there's an extra commented-out one)


class Cards
{
private static int deck[] = new int[52];
private static int hands[][] = new int[4][];
private static final String suit[] = {"Hearts","Diamonds","Clubs","Spades"};
private static final String face[] = {"Ace","Two","Three","Four","Five",
"Six","Seven","Eight","Nine","Ten","Jack", "Queen","King"};

public static void main(String args[])
{
putTheDeckInOrder();
printTheDeck();
shuffleTheDeck();
dealTheHands();
printTheHands();
System.exit(0);
}

private static void putTheDeckInOrder()
{
for(int i = 0; i < deck.length; i++) deck = i;
}

private static void printTheDeck()
{
for(int i = 0; i < deck.length; i++)
{
System.out.println(face[deck % 13] + " of " + suit[deck / 13]);
}
}

private static void shuffleTheDeck()
{
int temp;
int shuffled[] = new int[52];
for(int i = 52; i > 0; i--)
{
temp = ((int)(Math.random() * Integer.MAX_VALUE) % i);
//temp = (int)(Math.random() * i);
shuffled[i-1] = deck[temp];
while(temp < i - 1)
{
deck[temp] = deck[temp + 1];
temp++;
}
}
for(int i = 0; i < 52; i++) deck = shuffled;
}

private static void dealTheHands()
{
int temp = 0;
for(int i = 0; i < hands.length; i++)
{
hands = new int[5];
}
for(int i = 0; i < hands[0].length; i++)
{
for(int ii = 0; ii < hands.length; ii++)
{
hands[ii] = deck[temp++];
}
}
}

private static void printTheHands()
{
for(int i = 0; i < hands.length; i++)
{
System.out.println("\nHand " + (i+1) + ":");
for(int ii = 0; ii < hands.length; ii++)
{
System.out.println(face[hands[ii] % 13] + " of " + suit[hands[ii] / 13]);
}
}
}
}
 
G

Gary Labowitz

Brad BARCLAY said:
I'd suggest a different approach. An easier way of doing what you're
trying to do would be to create a deck of cards (by creating 52
instances of a Card class, each representing one of the standard 52
cards) by storing them in an array. Then, "shuffle" (randomize) the
cards in the deck, and pick off the first 20 cards. One good way of
shuffling the cards would be to pick any two random cards and swap their
locations in the array, and repeat a sufficiently large number of times.

Once the array has been randomized, as mentioned above, just take the
first 20 and do what you need to do with them. The advantage of this
method is that it will ensure that you don't select the same card twice.
It's easier to code, and will typically be more efficient to run.

It is also more general. Suppose the specs change to be a pinochle deck. You
change the creation of the deck to produce a valid pinochle deck and it
still works. For that matter, it could be a deck of cards for Old Maid.
 
D

Dale King

Brad BARCLAY said:
I'd suggest a different approach. An easier way of doing what you're
trying to do would be to create a deck of cards (by creating 52
instances of a Card class, each representing one of the standard 52
cards) by storing them in an array. Then, "shuffle" (randomize) the
cards in the deck, and pick off the first 20 cards. One good way of
shuffling the cards would be to pick any two random cards and swap their
locations in the array, and repeat a sufficiently large number of times.


Actually it is not a good way as it is not unformly random. Even if you had
a perfect random number generator, not all permutations are equally likely.

See here for an explanation and the correct approach to shuffle an array:

http://c2.com/cgi/wiki?LinearShuffleSummary
 
N

Neal Gafter

Larry said:
Dale King wrote:




Hmmm....I assume Collections.shuffle() uses the correct
approach?

Of course! (See for yourself by looking in the sources)
 
G

Gary Labowitz

Larry Coon said:
Hmmm....I assume Collections.shuffle() uses the correct
approach?

Last time I looked, Collections.shuffle( ) uses exactly the proposed method:
it generates random numbers using Random.nextInt( ) and swaps that position
with positions gotten by iterating through the List.
This simulates the action of shuffling a card deck and is as random as you
will get.
 
R

Roedy Green

Last time I looked, Collections.shuffle( ) uses exactly the proposed method:
it generates random numbers using Random.nextInt( ) and swaps that position
with positions gotten by iterating through the List.
This simulates the action of shuffling a card deck and is as random as you
will get.

Someone has invented a machine to rapidly shuffle cards. It uses a
random number generator to figure out the position, then pulls the
cards in that order.
 
W

Wojtek

Someone has invented a machine to rapidly shuffle cards. It uses a
random number generator to figure out the position, then pulls the
cards in that order.

There is something wrong with that idea, but just I cannot put my
finger on it :))
 
R

Roedy Green

There is something wrong with that idea, but just I cannot put my
finger on it :))

There are problems with it. It is still a PSEUDO random number
generator. There is a possibility you could greatly narrow down the
odds seeing the first N cards what the last 52-N are.

The second is it could be programmed to deal any hand you wanted. How
would a user know?

I think it is primarily for the casino. They can trust it more than
they can trust human dealers. It is also faster, allowing more plays
per hour which is inevitably drains the pockets of the players.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top