How to access an object within object? - java

I am trying to build a blackjack game. I have created a deck, now I want to display it.
I know I'm doing something wrong because I cannot access displayStack within CardStack class. Also, I have a feeling that I'm not doing inheritance correctly. How could I fix this?
Here is my code:
public class CreateCardDeck {
int deckSize = 52;
CardStack cardStack = new CardStack(deckSize);
public void CreateDeck() {
String[] suit = {"clubs", "diamonds", "hearts", "spades"};
int[] rank = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
for (int i = 0; i < rank.length; i ++) {
for (int j = 0; j < suit.length; j++) {
cardStack.push(suit[j], rank[i]);
}
}
}
}
Card class:
class Card {
String suit;
int rank;
Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
public String getSuit() {
return suit;
}
public String getRank() {
String nameTheRank;
if (rank == 1)
nameTheRank = "Ace";
else if (rank == 11)
nameTheRank = "Jack";
else if (rank == 12)
nameTheRank = "Queen";
else if (rank == 13)
nameTheRank = "King";
else
nameTheRank = String.valueOf(rank);
return nameTheRank;
}
}
CardStack class:
class CardStack {
public void displayDeck() {
for (int i = 0; i < stackArray.length; i ++)
System.out.println(stackArray[i]);
}
}
The Main Class:
public class MainClass {
public static void main(String[] args) throws IOException {
CreateCardDeck c = new CreateCardDeck();
c.CreateDeck();
// How to display my deck?
}
}

I would redesign your types to start with. CreateCardDeck sounds like it should really be a static method called createDeck within a CardDeck or possibly just Card type. It also sounds like the knowledge of suits and number shouldn't really be part of that method. Cards are often used as a demonstration of enums in Java - one enum for the values (ace to king) and one for the suits.
Think about what it really means to have an instance of CreateCardDeck - does that really make sense to you? It feels more like a verb (a method) than a noun (a type).
Now you could have a CardDeckFactory or something similar - but then I wouldn't expect the deck to be part of the state of the object; it would just be returned by a method.

Are you looking for this ie. extend class CreateCardDeck and refer it's cardStack variable?
class Card extends CreateCardDeck
{
public void displayDeck()
{
for (int i = 0; i < cardStack.size(); i ++)
System.out.println(cardStack.get(i));
}
}

you did not display your CardStack class, and did not display all of the Card class
basically you should have a showCards() method in it ,
and also in the card itself it would be useful to implement toString that represent the card:
something like this:
suppose you have a list or array of cards :
public void showCards() {
for (Card card : cards) {
System.out.println(card);
}
}
and in the Card:
public class Card {
private String suit;
private int rank;
public String toString() {
return rank + " of " + suit;
}
//...the rest of the code
}
in CreateCardDeck add a getter:
public CardSTack getCardStack() {
return cardStack;
}
and then in your main just add:
c.getCardStack().showCards();

Let's be simple as possible : you need a card to begin to play cards, it's better.
Then you need a Deck to stock all your card.
So you can just have two classes : Deck and Card. When you create an instance of a deck, it generates the 52 cards you need to play.
public class Card{}
public class Deck
{
int deckSize = 52;
// Here you certainly need a list or a stack to stock your card
SomeContainer cardStack;
public Deck()
{
String[] suit = {"clubs", "diamonds", "hearts", "spades"};
int[] rank = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
for (int i = 0; i < rank.length; i ++)
{
for (int j = 0; j < suit.length; j++)
{
cardStack.push(new Card(suit[j], rank[i]));
}
}
}
public void Display()
{
for (int i = 0; i < cardStack.length; i ++)
System.out.println(cardStack[i]);
}
}
public class MainClass
{
public static void main(String[] args) throws IOException
{
Deck deck = new Deck();
deck.Display();
}
}

Related

How to create a randomized deck of cards?

I need to create a deck of cards by using two string: "HSCD" and "A2345678910JQK".
public class Deck {
Random random=new Random();
Queue cards=new Queue(112);
String suits="HSCD";
String rands="A2345678910JQK";
public Deck() {
for (int i = 0; i < suits.length(); i++) {
for (int j = 0; j < rands.length(); j++) {
char suit = suits.charAt(random.nextInt(suits.length()));
char rand = rands.charAt(random.nextInt(rands.length()));
if (rand == '1' || rand == '0') {
String s = Integer.toString(10);
cards.enqueue(new Card(suit, s));
} else {
String s1 = Character.toString(rand);
cards.enqueue(new Card(suit, s1));
}
}
}
}
public void display(){
for (int i = 0; i < cards.size(); i++) {
System.out.print(cards.peek());
cards.enqueue(cards.dequeue());
}
}
public Queue getCards() {
return cards;
}
public void setCards(Queue cards) {
this.cards = cards;
}
public String getSuits() {
return suits;
}
public void setSuits(String suits) {
this.suits = suits;
}
public String getRands() {
return rands;
}
public void setRands(String rands) {
this.rands = rands;
}}
I have Deck and Card classes.
public class Card {
private char rand;
private String suit;
public Card(char rand, String suit) {
this.rand = rand;
this.suit = suit;
}
public Card(){}
public char getRand() {
return rand;
}
public void setRand(char rand) {
this.rand = rand;
}
public String getSuit() {
return suit;
}
public void setSuit(String suit) {
this.suit = suit;
}
public String toString(){
return "\t"+rand + suit;
}}
But i couldn't solve that every suits must have 13 rands. In my program my deck is randomly created. And my deck must be shuffled. I can't use list or array structures because teacher told us so :). Can you help me?
You are creating 14 cards per suit, not 13: you're creating 10 twice. Remove with 0 or 1 from rands.
It will be easier if you first create the cards, then shuffle them.
Creation of cards should be similar to what you're already doing, minus the randomization - just go through suits and values in order:
for each suit:
for each value:
sortedCards.add(new Card(suit, value));
Then, shuffle the cards as follows:
while (sortedCards is not empty):
shuffledCards.add(sortedCards.get(random.nextInt(sortedCards.size())))
Just duplicate four time the second string. After you take two random numbers one correspond to the sign and one to the number. Finally you put sign+number in memory and you remove the number in the string :
String signs = "HSCD";
String numbersH = "A2345678910JQK";
String numbersS = "A2345678910JQK";
String numbersC = "A2345678910JQK";
String numbersD = "A2345678910JQK";
ArrayList<String> deck = new ArrayList<String>();
Random random = new Random();
while(deck.size()<52){
int sign = random.nextInt(signs.lenght());
if(sign==0 && numbersH.lenght()>0){
int number = random.nextInt(numbersH.lenght());
deck.add(signs.charAt(sign)+numbersH.charAt(number));
numbersH = numbersH.substring(0,number)+numberH.substring(number+1);
}//here the same for other signs
}
Another method : Create your deck like iluxa say you and shuffle with this :
Random rand = new Random();
for(int i=0;i<300;i++){
int a = rand.nextInt(deck.size());
int b = rand.nextInt(deck.size());
Card cA = deck.get(a);
deck.set(a, deck.get(b));
deck.set(b, cA);
}
That's code will suffle your deck by switch two random cards many times.
You haven't included the Queue class so help is going to be limited. Here are some other suggestions.
String suits="HSCD";
String ranks="A23456789TJQK";
for (int i = 0; i < 52; i++) {
int suit = i/13; // index into suit 0 to 3 inclusive
int rank = i%13; // index into rank 0 to 12 inclusive
cards.enqueue(new Card(suits.charAt(suit), ranks.charAt(rank));
}
Also, quite often, card game software uses a T for ten, which is what I did in this example. It can be changed but in your implementation you can't store 10 as as a single character and it is cumbersome to maintain two types for card ranks. So you should probably make all your ranks and suits as type String.

Classifying Poker Hands in Java

I am currently working on a CS project that classifies player's hands. I solved the first half of the project to print out the deck, shuffled deck and the hands of player1, player2 and remaining deck. The problem comes up when I have to evaluate the hands. My code has to somehow evaluate which classification the hands are, and print out whether player1 or player2 wins. I have three classes so far:
public class Card {
static String[] card_suit = {"hearts", "diamonds", "clubs", "spades"};
static int[] card_rank = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};// 11 is Jack, 12 is Queen, 13 is King and 14 is Ace
public int[] getRank() {
return card_rank;
}
public String[] getSuit() {
return card_suit;
}
}
public class Driver {
public static void main(String[] args) {
Card card = new Card();
Deck deck = new Deck();
deck.getDeck();
System.out.print("ORIGINAL DECK: ");
deck.printDeck();
deck.shuffleDeck();
System.out.print("SHUFFLED DECK: ");
deck.printDeck();
System.out.println();
System.out.print("PLAYER ONE: ");
System.out.println(java.util.Arrays.toString(deck.playerOneHands()));
System.out.print("PLAYER TWO: ");
System.out.println(java.util.Arrays.toString(deck.playerTwoHands()));
System.out.print("REMAINING DECK: ");
System.out.println(java.util.Arrays.toString(deck.remainingDeckCards()));
}
}
import java.util.Arrays;
import java.util.Collections;
public class Deck extends Card {
Card card = new Card();
private String[] deck_card = new String[52];
public String[] getDeck() {
int i = 0;
for(int s = 0; s < 4; s++) {
for(int r = 0; r < 13; r++) {
deck_card[i]=(card_suit[s] + " of " + card_rank[r]);
i++;
}
}
return deck_card;
}
public void printDeck() {
System.out.println (java.util.Arrays.toString (deck_card));
}
public void shuffleDeck() {
Collections.shuffle(Arrays.asList(deck_card));
}
public String[] playerOneHands() {
String [] firsthand = new String[5];
for(int a = 0; a < 5; a++) {
firsthand[a] = deck_card[a];
}
return firsthand;
}
public String[] playerTwoHands() {
String[] secondhand = new String[5];
for(int a = 0; a < 5; a++) {
secondhand[a] = deck_card[a+5];
}
return secondhand;
}
public String[] remainingDeckCards() {
String[] remainDeck = new String[42];
for(int a = 0; a < 42; a++){
remainDeck[a] = deck_card[a+10];
}
return remainDeck;
}
}
What I thought it would work is because the Deck class extends from the Card class, I can use the getRank method to compare each hand, but I am not sure how to construct the conditionals.
Any help is greatly appreciated. Thanks.
For modelling the game, first identify entities like Card, Deck etc. (which mostly you have done). I would add few more like Player, Evaluator(explained below) etc.
Rank and Suit are NOT string/ int but they are predefined (not going to change in life time of game) possible variations in Cards. Always use domain vocabulary for best model. Each Card belongs to one Suit and one Rank. (think of making Rank and Suit as enums, this will avoid unknown values breaking the code at run time.
Not giving set method for suite and rank in Card is essential (they form an identity of Card in combination)
Full Deck (at initialization) is formed by cross product of Suit and Rank. Meaning Deck has (contains) multiple cards. Remember Card can be alive outside of Deck (when in players hand) as well, hence its not composition. Inheriting Deck from Card is absolutely wrong. It translates to statement Deck is a kind of Card, which is not correct. Deck will have collection of Cards. Using inheritance, will lead to violation of Liskov's Substitution Principle (One of the SOLID).
To model Deck, consider the fact that Deck does not contain duplicate cards, Deck does not change its order once formed (unless shuffled). This being tricky selection between Set and List, I would go for List with added programmatic constraint for avoiding duplicates (needs to be done only when initialization).
But instead of Modelling Deck as java collection, it will be best to let class Deck contain java collection of suitable choice and Deck class work as wrapper by defining required API (from domain perspective) like shuffle, getTopCard() etc. This is called as Object Adapter design pattern. This makes our design platform (implementation) independent.
You need to model few more classes like Player holds CardInHand etc.
About evaluating Cards in hand, its better to model it as separate class as its different concern and rules can change independent of other classes.
Poker game is best assignment to learn Object Oriented Programming.
Without wanting to do your homework for you...
This is a problem:
class Deck extends Card
A deck isn’t a subtype of a card. A deck has cards, so:
class Deck {
List<Card> cards;
}
is a better choice.
Also, the following code does nothing to the deck:
public void shuffleDeck() {
Collections.shuffle(Arrays.asList(deck_card));
}
It shuffles a copy of the deck, leaving the deck untouched.
Also, you shouldn’t be building strings in a loop. Instead, implement (override) a toString() method on Card and Deck.
Also, make suit an enum.
Also, delete card_rank entirely - it serves no purpose. Instead, add a int rank; field to Card, or better make rank an enum.
Fix these things first, then re-attack the problem by writing a method that is passed a Hand (a new class) that has a List and a method that returns a HandType (another enum) by evaluating if the hand is a straight flush, else four of a kind, else ... all the way down to high card - highest to lowest.
It seems that you class Card only has static fields; I would change it so that an instance of Card would represent a single card from a Deck. I would also make the suites an enum type. You can also add integer constants for the figures and aces. The class can implement Comparable<Card>:
public class Card implements Comparable<Card> {
public enum Suite {CLUBS, DIAMONDS, HEARTS, SPADES};
public static final int JACK = 11;
public static final int QUEEN = 12;
public static final int KING = 13;
public static final int ACE = 14;
public final Suite suite;
public final int rank;
public Card(Suite suite, int rank) {
if (suite == null) {
throw new IllegalArgumentException("Suite cannot be null");
}
if (rank < 2 || rank > 14) {
throw new IllegalArgumentException(
"Value must be between 2 and 14");
}
this.suite = suite;
this.rank = rank;
}
public Suite getSuite() {
return suite;
}
public int getRank() {
return rank;
}
#Override
public String toString() {
StringBuilder buf = new StringBuilder();
if (rank >= 2 && rank <= 10) {
buf.append(rank);
} else {
switch (rank) {
case JACK:
buf.append("jack");
break;
case QUEEN:
buf.append("queen");
break;
case KING:
buf.append("king");
break;
case ACE:
buf.append("ace");
break;
}
}
buf.append(" of ");
buf.append(suite.toString().toLowerCase());
return buf.toString();
}
#Override
public int compareTo(Card other) {
if (rank > other.rank) {
return 1;
} else if (rank < other.rank) {
return -1;
} else {
return suite.compareTo(other.suite);
}
}
}
Note that you could also have two subclasses of Card: one for the numbers and one for the figures.
The Deck is a collection of 52 cards. It is initialised by adding each card to a list. One can shuffle a deck, or take a card from the deck:
public class Deck {
private final List<Card> cards = new ArrayList<>();
public Deck() {
for (Card.Suite suite: Card.Suite.values()) {
for (int i = 2; i <= 14; ++i) {
cards.add(new Card(suite,i));
}
}
}
public void shuffle() {
Collections.shuffle(cards);
}
public boolean isEmpty() {
return cards.isEmpty();
}
public Card take() {
if (cards.isEmpty()) {
throw new IllegalStateException("Deck is empty");
}
return cards.remove(0);
}
}
You can take shuffle and take 5 cards from the deck like this:
Deck deck = new Deck();
deck.shuffle();
for (int i = 0; i < 5; ++i) {
Card card = deck.take();
System.out.println(card);
}
Now a Hand is a set of five cards taken from a Deck. We can declare Hand as implementing Comparable<Hand> so that we can know which of two hands have the highest value:
public class Hand implements Comparable<Hand> {
private final Card[] cards = new Card[5];
public Hand(Deck deck) {
for (int i = 0; i < 5; ++i) {
cards[i] = deck.take();
}
Arrays.sort(cards);
}
#Override
public int compareTo(Hand other) {
...
}
}
Now here comes the fun part: you must identify the hand type as one of the following (enum type):
public enum HandType {
SINGLE, PAIR, TWO_PAIRS, THREE, STRAIGHT, FLUSH, FULL_HOUSE, FOUR,
STRAIGHT_FLUSH, ROYAL_FLUSH;
}
Note that the constants are arranged from the lowest to the highest. In addition, the cards must be arranges so that in case of a tie, you can compare the cards to identify the winner.
I would suggest you make groups of cards of same rank; in the case where you have five different groups, it still can be a flush or a straight.
Another approach would consist in declaring a subclass of Hand for each HandType, but I don't think you would gain much by doing this.
public class Hand implements Comparable<Hand> {
public enum HandType {
SINGLE, PAIR, TWO_PAIRS, THREE, STRAIGHT, FLUSH, FULL_HOUSE, FOUR,
STRAIGHT_FLUSH, ROYAL_FLUSH;
}
private final Card[] cards = new Card[5];
private final int[] groupSize;
private final HandType type;
public Hand(Deck deck) {
for (int i = 0; i < 5; ++i) {
cards[i] = deck.take();
}
groupSize = group(cards);
type = identifyType(groupSize, cards);
}
#Override
public int compareTo(Hand other) {
int r = type.compareTo(other.type);
if (r != 0) {
return r;
}
for (int i = cards.length; --i >= 0; ) {
int r1 = cards[i].getRank();
int r2 = other.cards[i].getRank();
if (r1 < r2) {
return -1;
} else if (r1 > r2) {
return 1;
}
}
return 0;
}
#Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append(type);
buf.append(": ");
buf.append(cards[0]);
for (int i = 1; i < 5; ++i) {
buf.append(", ");
buf.append(cards[i]);
}
return buf.toString();
}
private static int[] group(Card[] cards) {
Arrays.sort(cards);
List<List<Card>> groups = new ArrayList<>();
int val = -1; // invalid rank
List<Card> currentGroup = null;
for (Card card: cards) {
if (val == card.getRank()) {
currentGroup.add(card);
} else {
if (currentGroup != null) {
groups.add(currentGroup);
}
currentGroup = new ArrayList<>();
currentGroup.add(card);
val = card.getRank();
}
}
if (currentGroup != null) {
groups.add(currentGroup);
}
// identify groups of cards of same value
// sort groups by size and highest card
Collections.sort(groups, (List<Card> group1, List<Card> group2) -> {
int s1 = group1.size();
int s2 = group2.size();
if (s1 < s2) {
return -1;
} else if (s1 > s2) {
return 1;
} else {
return group1.get(s1-1).compareTo(group2.get(s2-1));
}
});
int[] groupSize = new int[groups.size()];
int g = 0;
int i = 0;
for (List<Card> group: groups) {
groupSize[g++] = group.size();
for (Card card: group) {
cards[i++] = card;
}
}
assert sum(groupSize) == 5;
return groupSize;
}
private static HandType identifyType(int[] groupSize, Card[] cards) {
switch (groupSize.length) {
case 2:
// can be a full house or four cards
if (groupSize[0] == 1) {
return HandType.FOUR;
} else if (groupSize[0] == 2) {
return HandType.FULL_HOUSE;
} else {
assert false;
return null;
}
case 3:
if (groupSize[0] == 1) {
// three cards or double pair
if (groupSize[1] == 1) {
return HandType.THREE;
} else {
assert groupSize[1] == 2 && groupSize[2] == 2;
return HandType.TWO_PAIRS;
}
} else {
assert false;
return null;
}
case 4:
// one pair
return HandType.PAIR;
case 5:
// all different values: check for flush
Card prev = cards[0];
boolean sameSuite = true;
boolean straight = true;
for (int i = 1; i < 5; ++i) {
Card card = cards[i];
straight &= card.getRank() == prev.getRank()+1;
sameSuite &= card.getSuite() == prev.getSuite();
}
if (sameSuite) {
if (straight) {
if (cards[4].getRank() == Card.ACE) {
return HandType.ROYAL_FLUSH;
}
return HandType.STRAIGHT_FLUSH;
} else {
return HandType.FLUSH;
}
} else {
if (straight) {
return HandType.STRAIGHT;
} else {
return HandType.SINGLE;
}
}
default:
assert false;
return null;
}
}
private static int sum(int[] groupSize) {
int sum = 0;
for (int s: groupSize) {
sum += s;
}
return sum;
}
}

How to shuffle a deck of cards using Java (trying to use hashmap, not working)?

I have a hashmap<Integer, Card> Card is a class. I have initialized the hashmap with keys from 0-51 and the values are array of Card, as follows
Card [] card = new Card[52]
for (int i=1; i<=13; i++)
for (int j=0; j<4; j++)
card[++index] = new Card( ((i*10)+j) );
and I populate the hashmap as follows:
for (int i=1; i<=13; i++)
for (int j=0; j<4; j++)
deck.put( ++key, card[++index] );
Now, what I want to do is to shuffle the values side of the hashmap, i do not want,for an example, the key[1] corresponds to card[0] and key[1] corresponds to card[1]. I want, for an exampel, the key[1] corresponds to card[38]. I want the values side to be shuffled. I tried the following:
Collections.shuffle(card,new Random()); But it seems it accepts only ArrayList and List.
HashMaps do not have a predictable order, and shuffling an unordered data structure doesn't make sense. From the Java reference docs:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
If you are using keys from 0-51, you should just add all of the cards to an ArrayList. Then you can use Collections.shuffle(arrayList)
can I shuffle an array?
Yes. Here's one way.
Integer[] t = { 1, 2, 3, 4, 5 };
Collections.shuffle(Arrays.asList(t));
System.out.println(Arrays.toString(t));
You should consider adjusting your design to include a Deck and Card class. Examples are shown below. Your "encoding" for a card has a potential flaw 10*suit + card will have suit 0 card 13 have the same value as suit 1, card 3. If you want to compare two cards to see which "wins", you should add a method to the Card class that does this.
Try this:
Deck Class
package com.example.cards;
import java.util.Arrays;
import java.util.Collections;
public class Deck {
// Class fields
// Object fields
private Integer[] deckOrder;
private int nextCard;
private Card[] cards;
public Deck() {
deckOrder = new Integer[52];
cards = new Card[52];
for (int i=0; i < deckOrder.length; i++) {
deckOrder[i] = i;
cards[i] = new Card(i/13,i % 13);
}
}
public void shuffle() {
Collections.shuffle(Arrays.asList(deckOrder));
nextCard = 0;
}
public Card deal() {
if (nextCard < deckOrder.length) {
nextCard++;
return cards[deckOrder[nextCard-1]];
} else {
return null;
}
}
}
Card Class
package com.example.cards;
public class Card {
// Class fields
public final static String[] suit = {"Spades","Hearts","Diamonds","Clubs"};
public final static String[] card = {"Ace","King","Queen","Jack","Ten","Nine"
,"Eight","Seven","Six","Five","Four"
,"Three","Two"};
// Object fields
private int suitIndex;
private int cardIndex;
public Card(int suit, int card) {
suitIndex = suit;
cardIndex = card;
}
public int getSuitIndex() { return suitIndex;}
public int getCardIndex() { return cardIndex;}
public String getSuit() { return suit[suitIndex];}
public String getCard() { return card[cardIndex];}
public int getEncodedCard() { return 100*suitIndex + cardIndex;}
}
Test driver
package com.example.cards;
public class TestShuffle {
public static void main(String[] args) {
Deck myDeck = new Deck();
for (int deal = 1; deal < 3; deal++) {
System.out.println("======================Deal " + deal);
for (int i = 0; i < 52; i++) {
Card nextCard = myDeck.deal();
System.out.println("Card " + i + ". " + nextCard.getCard()
+ " of " + nextCard.getSuit() + "(encoded "
+ nextCard.getEncodedCard() + ")");
}
myDeck.shuffle();
}
}
}
try this:
public static void main(String args[]) {
Map<String, Object> x = new HashMap<String, Object>();
x.put("x", 1); x.put("y", 2); x.put("z", 3); x.put("w", 4);
System.out.println(x);
List<Object> vs = new ArrayList<Object>(x.values());
Collections.shuffle(vs);
System.out.println(vs);
Iterator<Object> vIter = vs.iterator();
for (String k : x.keySet()) x.put(k, vIter.next());
System.out.println(x);
}
output :
{w=4, x=1, y=2, z=3}
[2, 3, 1, 4]
{w=2, x=3, y=1, z=4}
What you can do is extract your key value pairs as a List of Map.Entry and shuffle it and put your Map.Entry values in the cleared map
Set<Map.Entry<Integer,Card> cardEntrySet= deck.entrySet();
List<Map.Entry<Integer,Card> cardsEntryList = new ArrayList<>(cardEntrySet);
Collections.shuffle(cardsEntryList);
deck.clear();
for(Map.Entry<Integer,Card> entry :cardsEntryList){
deck.put(entry.getKey(),entry.getValue());
}

Card c in video poker

I'm working on a video poker assignment in java. We are given class templates that we are supposed to use in our program. I'm confused as to what Card c represents. Like in the method addCard(Card c), does that just mean it will be executed on the Card object that's currently in use? Here are the class files I've been working on so far. They are far from finished.
Player Class:
import java.util.ArrayList;
public class Player {
private ArrayList<Card> hand; // the player's cards
// you will likely need more instance variables
public Player(){
ArrayList<Card> hand = new ArrayList;
}
public void addCard(Card c){
// add the card c to the player's hand
}
public void removeCard(Card c){
// remove the card c from the player's hand
}
// you will likely need more methods here
}
Deck class:
import java.util.Random
public class Deck {
private Card[] theDeck;
private int top;
// add more instance variables if needed
public Deck(){
top = 0
Card[] theDeck = new Card[52];
for(int s = 1; s <= 4; s++)
{
for (int v = 1; v <= 13; v++)
{
for (int i = 0; i < theDeck.length; i++)
theDeck[i] = new Card(s,v);
}
public void shuffle()
{
// shuffle the deck here
Random generator = new Random();
int i;
int j;
int temp = i;
int i = generator.nextInt(51) + 1;
int j = generator.nextInt(51) + 1;
for(int k = 1; k <100; k++)
{
theDeck[i] = theDeck[j];
theDeck[j] = temp;
}
top = 0;
}
public Card deal(){
// deal the top card in the deck
if (top < 40)
{
theDeck.shuffle;
}
return theDeck[top];
top++;
} //this method should add cards to array hand? no addCard will do that.
// add more methods here if needed
//DB getter methods here?
}
Card Class:
public class Card implements Comparable<Card>{
private int suit;
private int value;
public Card(int s, int v){ //constructor of an object Card
s = suit;
v = value;
//make a card with suit s and value v
}
public int compareTo(Card c){
// use this method to compare cards so they
// may be easily sorted
}
public String toString() //to tell the user what card/s they have
{
myCard.getSuit();
myCard.getValue();
if(s == 1)
{
if(v == 11)
{
return "Jack of Clubs";
}
if(v == 12)
{
return "Queen of Clubs";
}
if(v == 13)
{
return "King of Clubs";
}
if(v == 1)
{
return "Ace of Clubs";
}
else{
return v + " of Clubs";
}
}
if(s == 2)
{
return v + "Diamonds";
}
if(s == 3)
}
return v + "Hearts";
}
if(s == 4)
}
return v + "Spades";
}
//DB method to set 1, 2, 3, and 4 to card suits
//now here create string representation for the Card
// use this method to easily print a Card object
public int getSuit()
{
return s;
}
public int getValue()
{
return v;
}
//DB right now have cards in theDeck like Card(2, 10), need Card(d, 10)
//need to convert that to a String d10
}
// add some more methods here if needed
}
In public void addCard(Card c), c is a parameter.
This means that within the body of the function addCard, you can refer to the value passed to the function by the name c. You call the function addCard with some value (e.g., theDeck[0]), and that value will be used in addCard().

Can't seem to print an arraylist full of objects/enums

I was trying to create a card game golf for fun and to practice my java skills. I'm trying to use enums for my card values and suites. Those values are held in a constructor, named Card, in the Card Class.
The problem I'm running into to is printing my arraylist Deck that holds all my individual cards. This method can be found in the DeckOfCards Class . I want to see if my program is creating a full deck of cards. Thanks in advance for the help!
DeckOfCards Class
package finalProjectGolf;
// Deck class represent a deck of playing cards.
import java.util.ArrayList;
import java.util.Collections;
public class DeckOfCards {
ArrayList<Card> deck = new ArrayList<Card>(); //array of Card objects
private int currentCard; // index of next Card to be dealt (0-51)
private static int numDecks = 1;
public int getCurrentCard() {
return currentCard;
}
public void setCurrentCard(int currentCard) {
this.currentCard = currentCard;
}
private static final int NUMBER_OF_CARDS = 52 * numDecks; //constant # of Cards
//constructor fill deck of Cards
public DeckOfCards(){
currentCard = 0; //set currentCard so first Card dealt is deck[0]
//Card Index
int c = 0;
//for each deck
for (int d = 0; d < numDecks; d++){
//for each suit
for (int s = 0; s < 4; s++){
// for each number
for (int n = 1; n <= 13; n++){
//add a new card to the deck
deck.add(new Card(CardValue.values()[n],Suit.values()[s])); //when using Enums java makes arrays automatically and you can use them by .values()
c++;
}}}//end for loop
}//end DeckOfCards constructor
//shuffle deck of Cards with one-pass algorithm
public void shuffle() {
Collections.shuffle(deck);
}
public int points(){
int value = deck.get(currentCard).getCardValue().getCardValue();
return value;
}
//deal one Card
public Card dealCard(int currentCard) {
//determine whether Cards remain to be dealt
if( currentCard < deck.size() ){
return deck.get(currentCard); //return current Card in array
}
else
return null; // return null to indicate that all Cards were dealt
}//end method dealCard
public void printDeck(){
{
currentCard = 0; //set currentCard so first Card dealt is deck[0]
//Card Index
int c = 0;
//for each deck
for (int d = 0; d < numDecks; d++){
//for each suit
for (int s = 0; s < 4; s++){
// for each number
for (int n = 1; n <= 13; n++){
//add a new card to the deck
System.out.printf(""); //when using Enums java makes arrays automatically and you can use them by .values()
c++;
}}}//end for loop
}//end DeckOfCards constructor
}
}// end class DeckOfCards
Card Class
package finalProjectGolf;
public class Card
{
private Suit suit;
private CardValue cardValue;
public Card (CardValue cardValue, Suit suit) //constructor of Card, holds Card value and it's suit
{
this.cardValue = cardValue;
this.suit = suit;
}
public Suit getSuit()
{
return suit;
}
public void setSuit(Suit suit)
{
this.suit = suit;
}
public CardValue getCardValue()
{
return cardValue;
}
public void setCardValue(CardValue cardValue)
{
this.cardValue = cardValue;
}
public String toString(){
return cardValue + " of " + suit;
}// end method toString
}
CardValue Class
package finalProjectGolf;
public enum CardValue
{
ACE(1),
TWO(2),
THREE(3),
FOUR(4),
FIVE(5),
SIX(6),
SEVEN(7),
EIGHT(8),
NINE(9),
TEN(10),
JACK(11),
QUEEN(12),
KING(13);
private int cardValue;
private CardValue (int value)
{
this.cardValue = value;
}
public int getCardValue() {
return cardValue;
}
}
Suit Class
package finalProjectGolf;
public enum Suit
{
HEARTS(1),
SPADES(2),
CLUBS(3),
DIAMONDS(4);
private int suit;
private Suit (int value)
{
this.suit = value;
}
public int getCardSuit() {
return suit;
}
}
To add to AaronB's answer, your printDeck method is in fact wrong, as you have posted it. Currently it prints the empty string 52 times. In addition, you don't need to triple for loop just to print all the items in your deck. A very simple implementation that prints each card on a new line for a single deck would be:
public void printDeck() {
for(Card card : deck) {
System.out.println( card.toString() );
}
}
You also need to override the toString method for your enum values so that they print the name you want. Have a look at https://stackoverflow.com/a/14413605/1425014 for how to do that.
Your main class is called DeckOfCards. That indicates to me that the class represents a single deck of cards. However, judging by for (int d = 0; d < numDecks; d++) and private static int numDecks = 1, it appears that you intend for DeckOfCards to represent one or more decks of cards. It may be clearer to simply uses a collection (such as ArrayList) if you need more than on DeckOfCards instead of complicating the DeckOfCards class.
Finally, you should try to make sure your comments make sense before you post your code here. The comments for your printDeck() function haven't been changed after you copy/pasted from the DeckOfCards constructor.
The problem isn't that your printDeck method doesn't work (I haven't tested it yet, but at first glance it looks reasonable), it's that you never call it. You could place it at the end of the DeckOfCards constructor, if the point is to check that it's all there correctly.
In addition, you really should refactor a bunch of your logic, most notably in the DeckOfCards class. You've got some big blocks of computation -- put that in a method. Also, instead of declaring variables in the class, you should declare them in the constructor. For example:
ArrayList<Card> deck; //array of Card objects
private int currentCard; // index of next Card to be dealt (0-51)
private static int numDecks;
//constructor fill deck of Cards
public DeckOfCards(int numDecks){
deck = new ArrayList<Card>();
currentCard = 0; //set currentCard so first Card dealt is deck[0]
this.numDecks = numDecks;
Correct me if I'm wrong though, you didn't really describe what the issue was...

Categories