I would like to first say that this is not homework, but a pet project that I am working on in Java to better understand a complete Java program, and will hopefully be my first attempt at making my own GUI.
That aside, I have a question about creating a hand of cards from my current code. As it stands, I have a main class called DummyRummy, a class for creating cards, a class that creates a standard deck of cards (which includes Jokers and "shuffles" the deck when a new deck is created), and a PlayerHands class. I am strictly working with ArrayLists for all of the code, and the PlayersHands class should return two ArrayLists that will be used. However, when I try to call the PlayerHands() method in the public static void main(), PlayerHands cannot be located for some reason... Here is the code for PlayerHands:
package dummyrummy;
public class PlayerHands {
private Card[] playerOneCards;
private Card[] playerTwoCards;
private int[] value;
PlayerHands(deck d, int round)
{
value = new int[round+3];
playerOneCards = new Card[round+2];
playerTwoCards = new Card[round+2];
//(round+2) is the handsize at any given time
for (int x=0; x<round+3; x++)
{
playerOneCards[x] = d.drawFromDeck(); //fills up one hand.
playerTwoCards[x] = d.drawFromDeck(); //fills up second hand.
}
}
}
Here is the DummyRummy class.
package dummyrummy;
import java.util.*;
public class DummyRummy {
public static void main(String[] args) {
deck testDeck;
testDeck = new deck();
System.out.println(testDeck.getTotalCards());
System.out.println(testDeck.getClass());
int round = 1;
PlayerHands(testDeck, round); //This is where the error is occurring
}//End of arguments
}//End of DummyRummy class
Here is the Card class:
package dummyrummy;
public class Card
{
private short rank, suit;
private static String[] suits = { "Hearts", "Spades", "Diamonds", "Clubs", "Joker" };
private static String[] ranks = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
private static String[] jokers = {"Joker", "Joker"};
private static String[] ranks2 = {"0", "0"};
public static String rankAsString( int __rank ) {
if (__rank != 0){
return ranks[__rank];
}//End of if statement
return ranks2[__rank];
}//End of rankAsString class
Card(short suit, short rank)
{
this.rank=rank;
this.suit=suit;
}//End of Card Initializer
public #Override String toString()
{
if(suit == 5){
return "Joker";
}//End of if statement that calls jokers
if(rank == 0){
return "Joker";
}
return ranks[rank] + " of " + suits[suit];
}//End of toString method
public short getRank() {
return rank;
}//End of getRank method
public short getSuit() {
return suit;
}//End of getSuit method
}//End of Card
And finally, here is the deck() class:
package dummyrummy;
import java.util.Random;
import java.util.ArrayList;
public class deck {
private ArrayList<Card> cards;
deck()
{
cards = new ArrayList<Card>();
int index_1, index_2;
Random generator = new Random();
Card temp;
short jokerSuit=5;
short jokerRank = 0;
cards.add(new Card(jokerSuit, jokerRank));
cards.add(new Card(jokerSuit,jokerRank));
for (short suit=0; suit<=3; suit++)
{
for (short rank=0; rank<=12; rank++)
{
cards.add(new Card(suit,rank));
}
}//End of for-loop
int deckSize = 54;
for (int i=0; i<1000; i++)
{
index_1 = generator.nextInt( cards.size() );
index_2 = generator.nextInt( cards.size() );
temp = cards.get( index_2 );
cards.set( index_2 , cards.get( index_1 ) );
cards.set( index_1, temp );
}//End of for-loop
}//End of deck()
public Card drawFromDeck()
{
/*
* This method removes the top card of the already shuffled deck.
* The next step to take with this class is put the drawn card into another
* array that represents a players hand.
* This will take two arrays, and must be called depending on what player 'drawsFromDeck'.
*/
return cards.remove( 0 );
}//End of drawFromDeck()
public int getTotalCards()
{
return cards.size();
}//End of getTotalCards()
}//End of class deck
Thank you for your time, and I appreciate any help that may come. I would also be more than happy to provide my other code, if necessary.
EDIT: I have added the class and package above.
PlayerHands(deck, int) is a constructor. Therefore you have to call it like this (in class DummyRummy):
new PlayerHands(testDeck, round);
And since i guess you want to work with the instance you created, you should save the reference to a variable:
PlayerHands playerHands = new PlayerHands(testDeck, round);
PlayerHands(deck d, int round) is not a method, it is a constructor.
To correctly get the two hands, you can use this code:
...
int round = 1;
PlayerHands playerHands = new PlayerHands(testDeck, round); //This creates a new instance of the PlayerHands class
//access the players' hands like this:
Card[] player1Hand = playerHands.playerOneCards; //sets "player1Hand" to the "Card[] playerOneCards" contained in "playerHands"
Card[] player2Hand = playerHands.playertwoCards; //sets "player2Hand" to the "Card[] playerTwoCards" contained in "playerHands"
}//End of arguments
}//End of DummyRummy class
Related
So I only have one problem with my code and that is checking for the same card, because I do not want these cards to repeat. There is no reshuffling or whatsoever, its just random cards being dealt until there is none left. I have no clue on how to do it. Id appreciate some help; whether its theanswe or just a little nudge.
package Card;
import java.util.Random;
public class deckOfCards {
public String[] suite = { "Hearts", "Spade", "Diamonds", "Clubs" };
public String[] faceValue = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
public int deckCount = 0;
private Card[] deck = new Card[52];
public int index;
public void buildDeck() {
for (int i = 0; i < suite.length; i++) {
for (int j = 0; j < faceValue.length; j++) {
deck[deckCount] = new Card(suite[i], faceValue[j]);
deckCount++;
}
}
}
public Card shuffle(){
Random rand = new Random();
int index = rand.nextInt(52);
return deck[index];
}
}
this creates the card and randomizes them
package Card;
public class Card {
private String suite;
private String faceValue;
public Card(){
}
public Card(String suite, String faceValue){
this.setSuite(suite);
this.setFaceValue(faceValue);
}
public String getSuite(){
return suite;
}
//array list
//
public void setSuite(String suite){
this.suite = suite;
}
public String getFaceValue(){
return faceValue;
}
public void setFaceValue(String faceValue){
this.faceValue = faceValue;
}
}
package Card;
public class Driver {
public deckOfCards cards = new deckOfCards();
private Card [] discard = new Card[52];
public static void main(String[] args) {
Driver driver = new Driver();
driver.DealCards();
}
public void DealCards(){
int cardsLeft = 52;
cards.buildDeck();
Card randomCard = new Card();
for (int i = 0; i < 5; i++) {
cardsLeft--;
randomCard = cards.shuffle();
System.out.println(randomCard.getFaceValue() + " of " + randomCard.getSuite());
}
System.out.println("Cards left:" + cardsLeft);
}
}
this deals the cards. Again, any help is appreciated.
I think that what is missing is a method to remove a card from the deck.
Whenever a card is dealt, it needs to be removed, and a new random draw is performed on the remaining deck rather than on all 52 cards each time. This is called a draw without replacement. The current code performs a draw with replacement.
The quickest way to achieve this is to only modify the deckOfCards class:
Use a vector or cards rather than an array. This allows insertions and deletions. In an array, the size cannot be changed: a new array must be created every time, which is very inefficient.
In the shuffle function, instead of only returning a random card, you need to also remove it from the vector.
In the shuffle function, adapt 52 as the deck shrinks.
Recently, I've tried to create a Spades game in java. Ive managed to make the card and the deck class, but whenever I try to print out either a random card or a deck of cards, sans 2 of diamonds and clubs, I have an unexpected result. Here is my code:
Main class
package com.star.spades;
import com.star.cards.Card;
import com.star.cards.Deck;
public class Spades {
public static void main(String[] args) {
Deck deck = new Deck();
Card randCard = deck.drawCard();
System.out.println(deck);
System.out.println(randCard);
}
}
Card Class:
package com.star.cards;
public class Card
{
private int suit;
private int value;
private String [] suits = {"Diamonds", "Clubs", "Spades", "Hearts", };
private String [] values = {"Ace", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "Jack", "Queen", "King"};
private String [] joker = {"Joker"};
private String [] jokerValue = {"Little", "Big"};
public Card(int suit, int value)
{
this.suit = suit;
this.value = value;
}
public String outputCard()
{
return value + "of" + suit;
}
public String outputJoker()
{
return value + " " + suit;
}
Deck Class:
package com.star.cards;
import java.util.ArrayList;
import java.util.Random;
public class Deck {
private int numberOfSuits = 4;
private int numberOfValues = 52;
private int jokers = 1;
private int jokerSize = 2;
private ArrayList<Card> deck;
private ArrayList <Card> hands;
public Deck()
{
deck = new ArrayList<Card>();
for(int i = 0; i < numberOfSuits; i++)
for(int j =0; j < numberOfValues; j++)
{
deck.add(new Card(i, j));
}
for(int i = 0; i < jokerSize; i++)
for(int j = 0; j < jokers; j++)
{
deck.add(new Card(i, j));
}
deck.remove(1);
deck.remove(13);
}
//draws random card and removes it from deck.
public Card drawCard()
{
Random rand = new Random();
int index = rand.nextInt(deck.size());
return deck.remove(index);
}
//deals 13 random cards to the player
public ArrayList<Card> dealCards()
{
for(int i = 0; i < 13; i++)
{
hands.add(drawCard());
}
return hands;
}
}
and here is the result:
com.star.cards.Deck#143b9a5f
com.star.cards.Card#5513dd59
Could you let me know what I need to do to print out my deck and cards on the console?
You are trying to print objects directly. By default, the toString() method, which is called by print, will print out the reference to your object. So that weird thing you are getting is actually code for the location in memory where your object is stored. If you want to print out something else (for example some properties of the class) you must override the toString() method in your object's class.
You need to either implement toString in your classes or call a specific method that returns a string representation. Currently when you do System.out.println(card) it prints card's instance toString but since you didn't implement it yourself, it uses the parent class that did implement it - Object. Since Object has no information about your specific object, it prints a generic name and reference location address string.
If you choose to implement toString, all you have to do is add the method to your classes, for instance in Card class:
#Override
public String toString() {
return value + " " + suit;
}
And the same for your Deck class (not sure what you want to print there). Your Spades class is left untouched.
You need to implement/override the toString method in your classes. You will find many examples online for how to do that. For your Card class, a simple version could look like this:
#Override
public String toString()
{
return "Card[suit=" + suits[suit] + ",value=" + values[value] + "]";
}
I have an assignment to create a deck of cards and deal five random cards. I finally got it "working" but I need help with a couple things. One I just read that java now has a shuffle method to shuffle a list. We're on arrays right now so I think arrays were wanted is there a way to use the shuffle method with an array? If not can someone guide me in switching to a list? I think it will help with answer my next question. The only thing left for me to do is somehow state how many cards are left in the deck after the 5 random cards are dealt. However, seeing as how I'm using an array and you cannot remove items from an array because it's fixed (right?) I wanted to see if there was a way to simulate removing the cards from the array so that they aren't dealt again? Or would it just be easier to turn the arrays into a list/collection?
Here is my code. Any help is greatly appreciated. Also, I'll take any suggestions on cleaning the code up too...
public class CardGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle(1000);
Card b;
for (int i = 0; i < 5; i++) {
b = deck.deal();
System.out.println("Deal a card: " + b);
}
}
}
class Card {
public static final int SPADE = 4;
public static final int HEART = 3;
public static final int CLUB = 2;
public static final int DIAMOND = 1;
private static final String[] Suit = {"*", "Hearts", "Clubs", "Spades", "Diamonds"};
private static final String[] Rank = {"*", "*", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
private int cardSuit;
private int cardRank;
public Card( int suit, int rank ) {
if ( rank == 1 )
cardRank = 14; // Give Ace the rank 14
else
cardRank = (int) rank;
cardSuit = (int) suit;
}
public int suit() {
return ( this.cardSuit );
}
public String suitStr() {
return( this.Suit[ this.cardSuit ] );
}
public int rank() {
return ( this.cardRank );
}
public String rankStr() {
return ( Rank[ this.cardRank ] );
}
public String toString() {
return ( Rank[ this.cardRank ] + " of "+ Suit[ this.cardSuit ] );
}
}
class DeckOfCards {
public static final int NEWCARDS = 52;
private Card[] deckOfCards; // Contains all 52 cards
private int currentCard; // deal THIS card in deck
public DeckOfCards( ) {
deckOfCards = new Card[ NEWCARDS ];
int i = 0;
for (int suit = Card.DIAMOND; suit <= Card.SPADE; suit++)
for ( int rank = 1; rank <= 13; rank++ )
deckOfCards[i++] = new Card(suit, rank);
currentCard = 0;
}
//shuffle(n): shuffle the deck
public void shuffle(int n) {
int i, j, k;
for ( k = 0; k < n; k++ ){
i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random cards
j = (int) ( NEWCARDS * Math.random() ); // in the deck
//swap these randomly picked cards
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
}
currentCard = 0; // Reset current card to deal
}
//deal(): deal deckOfCards[currentCard] out
public Card deal() {
if (currentCard < NEWCARDS) {
return ( deckOfCards[currentCard++] );
}
else{
System.out.println("Out of cards error");
return ( null ); // Error;
}
}
public String toString() {
String s = "";
int k;
k = 0;
for ( int i = 0; i < 4; i++ ) {
for ( int j = 1; j <= 13; j++ )
s += (deckOfCards[k++] + " ");
s += "\n";
}
return (s);
}
}
After all the help I decided to rewrite my code and here is what I got but I'm having a little trouble bringing it all together and making it work!
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CardGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle();
Card b;
for (int i = 0; i < 5; i++) {
b = deck.deal();
System.out.println("Deal a card: " + b);
}
}
}
class Card {
enum Suit {
HEARTS(1),
CLUBS(2),
DIAMONDS(3),
SPADES(4);
private int suitValue;
private Suit (int suitValue)
{
this.suitValue = suitValue;
}
public int getSuitValue()
{
return suitValue;
}
}
private Suit suit;
private Value value;
public Card (Suit suit, Value value)
{
this.suit = suit;
this.value = value;
}
public Suit getSuit() {
return suit;
}
public Value getValue() {
return value;
}
/*
public int compareTo(Card o) {
return 0;
}
} */
class DeckOfCards
{
private List<Card> cards = new ArrayList<Card>();
public DeckOfCards () {
for (Suit suit : Suit.values()) {
for (Value value : Value.values()) {
Card card = new Card(suit, value);
cards.add(card);
}
}
}
public List<Card> getCards() {
return cards;
}
public void shuffleDeckOfCards() {
Collections.shuffle(cards);
}
public String toString() {
return this.Value + " of "+ this.Suit;
}
}
Here is a fully working sample program which demonstrates all the things you need - Shuffling and removing cards from an array.
Sample Card class:
public class Card {
private String value = "";
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Card(String value) {
super();
this.value = value;
}
}
Sample program:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class CardGame {
public static void main(String[] args) {
List<Card> pack = new ArrayList<Card>();
Card c1 = new Card("c1");
Card c2 = new Card("c2");
Card c3 = new Card("c3");
pack.add(c1);
pack.add(c2);
pack.add(c3);
System.out.print("List : ");
CardGame.displayCardList(pack);
Card[] packArr = cardListToArray(pack);
System.out.print("Array : ");
CardGame.displayCardArray(packArr);
// http://stackoverflow.com/questions/4228975/how-to-randomize-arraylist
long seed = System.nanoTime();
Collections.shuffle(pack, new Random(seed));
System.out.print("Shuffle List : ");
CardGame.displayCardList(pack);
packArr = cardListToArray(pack);
System.out.print("Shuffle Array : ");
CardGame.displayCardArray(packArr);
System.out.print("Remove Card from Array : ");
CardGame.removeCardFromArray(packArr, new Card("c1"));
CardGame.displayCardArray(packArr);
}
public static boolean removeCardFromArray(Card[] packArr, Card card) {
boolean cardFound = false;
for (int i = 0; i < packArr.length; i++) {
if (packArr[i].getValue().equalsIgnoreCase(card.getValue())) {
packArr[i] = null;
cardFound = true;
break;
}
}
return cardFound;
}
public static Card[] cardListToArray(List<Card> pack) {
Card[] packArr = new Card[pack.size()];
for (int i = 0; i < pack.size(); i++) {
packArr[i] = pack.get(i);
}
return packArr;
}
public static void displayCardList(List<Card> pack) {
for (Card c : pack) {
System.out.print(c.getValue() + ", ");
}
System.out.println();
}
public static void displayCardArray(Card[] packArr) {
for (Card c : packArr) {
if (c == null) {
System.out.print("REMOVED, ");
} else {
System.out.print(c.getValue() + ", ");
}
}
System.out.println();
}
}
Card
In the Card class the suits should be an enum. You can create the enum like this.
enum Suit {
SPADE,
HEART,
CLUB,
DIAMOND
};
Then the class should hold a variable of it's current suit like
Suit suit;
You can change the value of it very easily.
suit = Suit.HEART;
If you must use an index to access a suit you could use
suit = Suit.values()[index];
When getting the rank of the card you could use
return Rank[suit.ordinal()];
The name of the functions in the Card class are not the typical names you should use. Some of these should be getters. I would recommend names like getSuit() and getSuitName(), you want names that just by reading them you can understand what they do. Names like suit() are a little confusing, they don't tell you what they are doing with suit.
DeckOfCards
In the DeckOfCards class, when initializing the deck use a for each loop for the suits.
for (Suit suit : Suits.values()) {
...
}
This will loop over every suit.
If you wanted to switch over to a List you should declare your private variable deckOfCards to be an ArrayList.
private List<Card> deckOfCards = new ArrayList<>();
If you haven't worked with lists before, this is creating a list of Card objects. The diamond operator (<>) assumes the object type from the type you specified before (Card) This is a java 7 feature, if you are working with older version you would use
new ArrayList<Card>();
Instead of tracking your position in the deck, you add a card with the add() function
deckOfCards.add(card);
This would allow you to use Collections.shuffle(deckOfCards) to shuffle the cards around randomly.
To access a card, you use the get(int i) function
deckOfCards.get(index);
If you are still using arrays, when you are shuffling use a Random object. Throw a
Random random = new Random();
in the begging of your class. The inside of the for loop could look like this
int i = random.nextInt(NEWCARDS);
int j = random.nextInt(NEWCARDS);
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
In the shuffle function I would change the names of i, j, and k. Variable K should be called i because it is the iterator. Variable j and k should be renamed to more meaningful names.
If you want to convert Arrays to lists you can use
Arrays.asList(new ArrayList<Card>());
And the opposite of that, to convert back to an array.
list.toArray();//This will return an array of Objects[]
Card[] cards = new Card[NEWCARDS];
list.toArray(cards)//This will store the list into the array cards.
//Note if the lists is bigger than the array it is storing it in, the function will return a new array that can hold all of the elemnents in the list.
Note: In these example I have been using ArrayList, there are other implementations of the List class which you may want to research.
Personal Preference
I would remove the parenthesis off of the return statements except on your toString() for the Card class.
You have some extra spaces when using parenthesis in your code such as your DeckOfCards constructor. I would make it like so
public DeckOfCards() {
There also shouldn't be spaces surrounding the stuff inside parenthesis such as
i = (int) ( NEWCARDS * Math.random() );
//should be
i = (int) (NEWCARDS * Math.random());
I have an assignment for my summer class. FYI, I'm super new to programming in general and this is my first time with java and it's a summer class so it's going super fast (please be nice!) lol.
Basically I started writing my code in one class, then I split it up into a Card class and a DeckOfCards class and I now need to figure out how to get it all to work together. I get a little confused with calling methods sometimes, especially when separate classes are in play. I think I just need a method to deal out five cards that also tells how many cards are left in the deck. Then get it all working together correctly. Also, I need a toString method but I honestly do not know how to go about that. Any help is greatly appreciated! If you could help explain things too that would be awesome! I think I have everything SO FAR correct but I could be wrong and I'm sure there are better ways to write the code, I'll take any suggestions for a cleaner look too. FYI, I think the prof would rather arrays then enums since we're dealing with arrays right now.
Here are the directions...
Design and implement a class called Card that represents a standard playing card. Each card has a suit and a face value. Then create a class called DeckOfCards that stores 52 objects of the Card class. Include methods to shuffle the deck, deal a card and report the number of cards left in the deck. The shuffle methods should assume a full deck. Create a driver class (CardsGame) with a main method that deals five cards from the shuffled deck, printing each card as it is dealt. Make sure to write the appropriate constructors, getters, setters, toString and other methods as required for both classes.
The main class, CardsGame Class
import java.util.Scanner;
public class CardsGame {
public static void main (String [] args) {
}
}
Card Class
class Card {
public static final int SPADE = 4;
public static final int HEART = 3;
public static final int CLUB = 2;
public static final int DIAMOND = 1;
private int rank;
private int suit;
private static final String[] Suit = {"Hearts", "Clubs", "Spades", "Diamonds"};
private static final String[] Rank = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
private int cardSuit;
private int cardRank;
public Card(int suit, int rank) {
if (rank == 1)
cardRank = 14; // Give Ace the rank 14
else
cardRank = (int) rank;
cardSuit = (int) suit;
}
public int suit() {
return this.cardSuit;
}
public String suitStr() {
return(this.Suit[ this.cardSuit ]);
}
public int rank() {
return this.cardRank;
}
public String rankStr() {
return ( Rank[ cardRank ] );
}
public String toString() {
return ( Rank[ cardRank ] + Suit[ cardSuit ] );
}
}
DeckOfCards Class
class DeckOfCards {
public static final int NEWCARDS = 52;
private Card[] deckOfCards; // Contains all 52 cards
private int currentCard; // deal THIS card in deck
public DeckOfCards( ) {
deckOfCards = new Card[NEWCARDS];
int i = 0;
for ( int suit = Card.DIAMOND; suit <= Card.SPADE; suit++ )
for ( int rank = 1; rank <= 13; rank++ )
deckOfCards[i++] = new Card(suit, rank);
currentCard = 0;
}
//shuffle(n): shuffle the deck
public void shuffle(int n) {
int i, j, k;
for ( k = 0; k < n; k++ ) {
i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random cards
j = (int) ( NEWCARDS * Math.random() ); // in the deck?
//swap these randomly picked cards
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
}
currentCard = 0; // Reset current card to deal
}
}
How do I get it all to work together?
How do I instantiate the deck of cards?
To instantiate the deck of cards, use the following code DeckOfCards deck = new DeckOfCards();
How do I call the methods of this class?
To call a method in the class DeckOfCards, you first need to instantiate an object of type DeckOfCards (which we just did). Then, you simply refer to the instantiated variable name (deck), put a ., and call the name of the method.
public class CardsGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle();
}
}
DeckOfCards class structure
Currently, I don't believe the methods you wrote in DeckOfCards are accessible. function shuffle() should be placed outside of the constructor. If you wish to call it inside your constructor, simply call shuffle();
toString
Here is an example toString method for DeckOfCards
(note this should be placed after the constructor)
#Override public String toString() {
return "DeckOfCards";
}
I am making a card and deck class that make a deck of 52 cards and the cardProgram class is the driver.The Card class has a property for the card's suit and a property for the value (Ace, King,10,9, etc). It also has a constructor for the properties and a toString representation for the card. The deck class ahs a property to represent cards in the deck and a constructor wit no parameters that will create 52 cards and add them to the deck, a method to randomly remove a card and return the card object that was drawn, and a toString to show the cards contained in the deck. Tha main will create the deck of cards. The user enters the number they would like to draw. Each card they draw is printed and then the cards remaining in the deck will be printed. I am using ArrayList to do this and I would just like to know if I am going in the right direction. I keep getting errors and I know there is something wrong in my classes. I have never used ArrayList before so any information would be appreciated
public class Card
{
private int type, value;
private String[] cardType = {"Clubs", "Spades", "Diamonds", "Hearts"};
private String[] cardValue = {"Ace", "King", "Queen", "Jack", "10",
"9", "8", "7", "6", "5", "4", "3", "2"};
public Card(int types, int values)
{
type = types;
value = values;
//this.value = value;
}
public String toString()
{
String finalCard = cardValue[value] + " of " + cardType[type];
return finalCard;
}
}
import java.util.Random;
import java.util.ArrayList;
public class Deck
{
private ArrayList<Card> cards;
public Deck()
{
for(int a =0; a<=3; a++)
{
for(int b =0; b<=12;b++)
{
cards.add(drawRandomCard());
}
cards.addAll(cards);
}
}
public Card drawRandomCard()
{
Random generator = new Random();
int index = generator.nextInt(cards.size());
return cards.remove(index);
}
public String toString()
{
String result = "Cards remaining in deck: " + cards;
return result;
}
}
import java.util.Scanner;
public class CardProgram
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Card C;
Deck deck = new Deck();
System.out.println("Enter number of cards to be dealt: ");
int numberCards = scan.nextInt();
System.out.println("Cards drawn: ");
C = deck.drawRandomCard();
System.out.println(C.toString());
}
}
In terms of design guidelines there a couple things I would suggest:
1) Keep your local variables lower case (Card c)
2) Think about creating Java Enum for both rank and suit.
Your deck creation for loops would then look something like this:
cards = new ArrayList<Cards>();
for(Rank k : Rank.values())
for(Suit s: Suit.values())
cards.add(new Card(k,s));
3) An error you will get is probably an ArrayOutOfBoundsException since your Deck constructor is calling drawRandomCards() when initially cards is empty. Good Luck!
4) As was pointed out, you also haven't initialized cards yet.
Looking at your code, I think you are getting NullPointerException as you are talking about error.
You have defined private ArrayList<Card> cards; but you never initialized it in your Deck Class.
It should go something like
private ArrayList<Card> cards; // currently its null
cards = new ArrayList<Card>(); // initializing here and no more null
I think this is what you need. So what have I changed?
1.
When you initialised the deck, you need to populate the ArrayList with a card for each number combination. This is achieved by cards.add(new Card(a,b));. I've also removed the cards.addAll(cards) because you were adding the whole list to itself.
edit: oh yeh, and I initialised the ArrayList as well. That bits kind of important!
2.
In your CardProgram, you got the number of cards you wanted to draw, so I looped that many times calling, drawRandomCard().
3.
I haven't printed the remaining cards, that's up to you to figure out.
public class Card
{
private int type, value;
private String[] cardType = {"Clubs", "Spades", "Diamonds", "Hearts"};
private String[] cardValue = {"Ace", "King", "Queen", "Jack", "10",
"9", "8", "7", "6", "5", "4", "3", "2"};
public Card(int types, int values)
{
type = types;
value = values;
//this.value = value;
}
public String toString()
{
String finalCard = cardValue[value] + " of " + cardType[type];
return finalCard;
}
}
import java.util.Random;
import java.util.ArrayList;
public class Deck
{
private ArrayList<Card> cards;
public Deck()
{
cards = new ArrayList(52);
for(int a =0; a<=3; a++)
{
for(int b =0; b<=12;b++)
{
cards.add(new Card(a,b));
}
}
}
public Card drawRandomCard()
{
Random generator = new Random();
int index = generator.nextInt(cards.size());
return cards.remove(index);
}
public String toString()
{
String result = "Cards remaining in deck: " + cards;
return result;
}
}
import java.util.Scanner;
public class CardProgram
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Card C;
Deck deck = new Deck();
System.out.println("Enter number of cards to be dealt: ");
int numberCards = scan.nextInt();
System.out.println("Cards drawn: ");
for (int i = 0; i < numberCards; i++) {
C = deck.drawRandomCard();
System.out.println(C.toString());
}
System.out.println(C.toString());
}
}