I am currently working on a hand of cards class that uses enums that requires me to add methods that:
Add cards into the hand
Calculate the total value of all the cards currently in the hand (so if there were 3 10's in the hand then the total value would be 30)
The problem however is that I can't find out how to add up all the total while still implimenting the method within the hand class (as the task asks us to).
Any help will be greatly appreciated
Heres the code for my Suit enum
public enum Suit
{ HEARTS, CLUBS, DIAMONDS, SPADES; }
Here is the code for my Rank enum.This one has a few added methods including a getValue method
public enum Rank {
ONE(1),TWO(2),THREE(3),FOUR(4),FIVE(5), SIX (6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), KING(10), QUEEN(10),
JACK(10);
private final int cardValue;
private Rank ( int nDays) {
cardValue = nDays;
}
public int getValue() {
return cardValue;
}
}
This is the Card class that uses the Rank and Suit enums to print off the details (excuse the mess)
public class Card {
private Rank rank;
private Suit suit;
public Card (Rank theRank) {
this(theRank,Suit.HEARTS);
}
public Card (Rank theRank, Suit theSuit) {
rank = theRank;
suit = theSuit;
}
public Rank getRank( ) { return rank; }
public Suit getSuit ( ) { return suit; }
public String toString ( ) { return ( rank + " of " + suit +"\n Value of card = " + rank.getValue() ); }
}
And this is the Hand class that requires the addCard method and the totalValue method. I have done the addCard method and now need to do totalValue method)
public class Hand {
private Card theCards[ ];
private Rank rank;
private int numCards; private int totalValue;
private static final int max = 5;
public Hand ( )
{
theCards = new Card [max];
numCards = 0;
}
public void addCard( Card aCard )
{
if (numCards < max)
theCards[numCards++] = aCard;
else
{
System.out.println("Cannot add any more cards as hand is full");
}
}
public void totalValue ()
{
int handValue = 0;
for(Card C: theCards)
{
//get the rank values to appear then print them off
//Add up all values of cards and display the total
totalValue = handValue + C.getValue(); //This was just a test to see if calling up the value of card C would work
}
System.out.println("The total value of all the cards is: " + totalValue);
}
public String toString ( )
{
String s = "";
for (int i = 0; i < numCards; ++i) { s += "\n" + theCards[i];
}
return s;
}
As far as implimentation goes its just a case of creating card objects and adding them to the Hand object so I don't think I'll need to post that here. Thank you to anyone who can help me with my problem.
Card doesn't have a getValue() method but Rank does. So get the card's Rank via its getRank() method and then call getValue() on the rank returned.
The value of a Card is available through its rank field. Right now you are trying to call getValue() directly on the Card, but there's no such method (yet).
Also, you'd normally return the total value of the hand from the totalValue() method, rather than simply printing it; this allows other code to actually use the value.
I managed to figure out how to make it print without returning any nullexception errors. Basicly I simply converted the array into an arraylist as it was much more practical. Here is the final version of the Hand class.
import java.util.*;
public class Hand {
private ArrayList<Card> theCards = new ArrayList<Card >() ;
private static final int max = 5;
public void addCard( Card aCard )
{
if (theCards.size() < max)
theCards.add(aCard);
else
{
System.out.println("Cannot add any more cards as hand is ull");
}
}
public void totalValue() {
int totalValue = 0;
for (Card card : theCards) {
totalValue += card.getRank().getValue();
}
System.out
.println("The total value of all the cards is: " + totalValue);
}
public void outputAllCards ( )
{
System.out.println("Outputting all card etails\n========================");
for (Card card : theCards)
{
System.out.println(card.toString());
}
System.out.println("========================");
} }
I put in a println in order to print a message out when the totalValue method was called. I tried returning by turning the method into a string or int but this didn't work
The value is inside the rank. Does the rank object inside hand play any role (such as doubling value of the corresponding cards in the hand, you have to specify the game rules)? You just have to add up the rank values. I rewrote your code to leave out some unneccessary counters/vars. On the other side it is better to keep a list instead of an array if it can grow.
import java.util.ArrayList;
import java.util.List;
public class Hand {
private final List<Card> cards = new ArrayList<Card>();
private Rank rank;
private static final int MAX = 5;
public void addCard(Card aCard) {
if (cards.size() < MAX) {
cards.add(aCard);
} else {
System.out.println("Cannot add any more cards as hand is full");
}
}
public void totalValue() {
int totalValue = 0;
for (Card card : cards) {
totalValue += card.getRank().getValue();
}
System.out
.println("The total value of all the cards is: " + totalValue);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Card card : cards) {
sb.append('\n').append(card.toString());
}
return sb.toString();
}
}
Related
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;
}
}
First i have a class called card with this code
public class Card
{
private int value;
private String suit;
// private int value;
//private String rank;
public Card (int v, String s)
{
value=v;
suit=s;
}
public int random()
{
int randomNum = ((int)(Math.random() * 100) % 13 +1);
return randomNum;
}
public void displayCard()
{
System.out.println(value + " of " + suit);
}
}
then i have a class called deck with this code
import java.util.*;
public class Deck
{
public ArrayList<Card> card;
private ArrayList<String> suits;
private ArrayList<Card> hand;
public Deck()// time to build a deck
{
card=new ArrayList<>();
suits=new ArrayList<>();
suits.add("Hearts");
suits.add("Spades");
suits.add("Clubs");
suits.add("Diamonds");
for (int y=2; y<15; y++)
{
card.add(new Card(y,suits.get(0)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(1)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(2)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(3)));
}
}//end of public deck
public ArrayList deal()// deal method
{
hand=new ArrayList<>();
for(int x = 0; x < 5; ++x)//build 5 card hand
{
hand.add(card.get(x));
System.out.println(card.get(x));
}
return hand;
}//end of public void deal
}// end of public class deck
then i have the main
import java.util.ArrayList;
import java.util.*;
public class gamePlay
{
private static gamePlay player1;
public Deck fullDeck;
private ArrayList<Card> yourHand;
public gamePlay()
{
fullDeck=new Deck();
System.out.println("Your poker hand is a");
yourHand = fullDeck.deal();
//System.out.println(yourHand);
}
public static void main(String[] args)
{
player1 = new gamePlay();
}
}
It is printing out some crazy stuff for the value and suit of the cards in the hand
i think they are either memory locations from the arraylist or hexidecimal values i am not sure need it to print suit and rank any help is appreciated
If your classes implement a proper toString method, it will show up perfectly.
You can easily change your existing method displayCard in the Card class to a toString method. This leads to more flexibility than to let the Card print out itself by calling System.out.println in the card's method.
#Override
public String toString() {
return value + " of " + suit;
}
If you want the card to print to System.out you just do System.out.println(card);
Normal arrays can also be converted to String, using Arrays.toString(array) (if you would have a Card[] variable for example). Most implementations of Lists already implement a proper toString method so it will show you a comma-separated list of the entries.
You have to provide a toString() method in your Card class.
For example:
#Override
public String toString() {
return String.format("Card [value=%s, suit=%s]", value, suit);
}
If you don't provide that method, the default depends on the JDK implementation. Usually, it is the name of the class followed by a # and the object hash code.
I suspect that you have to iterate through the array and print each item individually. One cannot print the entire content of an array by toString() the array itself.
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...
I'm struggling to add together values that I've declared within ENUMS. I basically need to add together values of each card within a hand of cards based on rank.
I've tried a few things but not actually got anywhere. I can display the ENUM's but they have no value.
Here is my code:
Card Class
public class Card {
private Suit suit;
private Rank rank;
int totalValue;
public Card (Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
public Suit getSuit(){
return suit;
}
public void setSuit(Suit suit)
{
this.suit = suit;
}
public Rank getRank()
{
return rank;
}
public void setRank(Rank rank)
{
this.rank = rank;
}
#Override
public String toString ( ) { return ( rank + " of " + suit); }
}
Suit Class
public enum Suit {
HEARTS , SPADES , CLUBS , DIAMONDS
}
Rank Class
public enum Rank {
ACE(1),
TWO(2),
THREE(3),
FOUR(4),
FIVE(5),
SIX(6),
SEVEN(7),
EIGHT(8),
NINE(9),
TEN(10),
JACK(10),
QUEEN(10),
KING(10);
private int RankValue;
private Rank (int rValue)
{
RankValue = rValue;
}
public int getRankValue()
{
return RankValue;
}
}
Hand Class
public class Hand {
private Card theCards[ ];
private int numCards;
private int totalValue;
private static final int max = 5;
private Rank rank;
private Suit suit;
public Hand ( )
{
theCards = new Card [max];
numCards = 0;
}
public void addCard( Card aCard )
{
if (numCards < max) theCards[numCards++] = aCard;
}
public void setRank(Rank rank){
this.rank = rank;
}
public void setSuit(Suit suit){
this.suit = suit;
}
public int totalValue() {
int totalValue = 0;
for (Card card : theCards) {
totalValue += card.getRank().getRankValue();
}
return totalValue;
}
#Override
public String toString ( )
{
String s = "Rank: " + rank + "Suit: " + suit;
for (int i = 0; i < numCards; ++i) {
s += "\n" + theCards[i] + "\n" + totalValue;
}
return s;
}
}
Finally my Hand Driver with the main method
public class HandDriver {
public static void main( String[] args ){
Hand h1 = new Hand();
Card c1 = new Card(Suit.valueOf("HEARTS"),Rank.valueOf("TEN"));
Card c2 = new Card(Suit.valueOf("SPADES"),Rank.valueOf("ACE"));
Card c3 = new Card(Suit.valueOf("DIAMONDS"),Rank.valueOf("SEVEN"));
Card c4 = new Card(Suit.valueOf("HEARTS"),Rank.valueOf("NINE"));
Card c5 = new Card(Suit.valueOf("HEARTS"),Rank.valueOf("THREE"));
h1.addCard(c1);
h1.addCard(c2);
h1.addCard(c3);
h1.addCard(c4);
h1.addCard(c5);
System.out.print (h1.toString());
;
}
}
I'm basically looking for someone who is able to point me in the right direction to display the total value of all cards
In your Hand class, you are using int totalValue, which is then "shadowed" in your function totalValue(), so totalValue will be zero. Then, in toString() you are using totalValue, which is never calculated. First, remove "int" here:
public int totalValue() {
//removed "int", so you are not declaring local totalValue variable
//but using your class variable
totalValue = 0;
for (Card card : theCards) {
totalValue += card.getRank().getRankValue();
}
return totalValue;
}
Then, in your toString(), call the above function, so that totalValue is calculated, and then you can use it in your loop:
#Override
public String toString ( )
{
String s = "Rank: " + rank + "Suit: " + suit;
//call totalValue() to calculate totalValue
totalValue();
for (int i = 0; i < numCards; ++i) {
//now you can use totalValue, because it's been calculated in totalValue()
s += "\n" + theCards[i] + "\n" + totalValue;
}
return s;
}
As noticed by Holger, you can also use Suit.HEARTS instead of Suit.valueOf("HEARTS").
EDIT: As noticed by Grove, totalValue() doesn't have to be called for every card. Call it before you build your string, and then you can use totalValue variable in your for loop.
There are a few problems with your code.
I agree with "Holger" you should not be using
Suit.valueOf("HEARTS") and
Rank.valueOf("TEN")
Instead it should be
Suit.HEARTS
Rank.TEN
Then in the Card and Hand classes you should probably be calculating the value of that Card or value of that Hand as the suit and rank is added to the Card and as a Card is added to the Hand, that way when you get the total value of the Hand or want to do toString() you only need to read the value rather than calculate it every time.
In the Hand class the way you are adding a Card to the "theCards" array should be like so:
if (numCards < max) {
theCards[numCards] = aCard;
numCards++;
}
Then as I mentioned before you should probably in this if block also call another method which you will need to create to update the total value.
Finally, to calculate the total of a Card you may want to do something like,
int suitVal = suit.ordinal(); // This returns a number which is the position of the enum value
int rankVal = rank.getRankValue();
totalValue = suitVal + rankVal;
I could have just changed all your code and pasted it in here for you but that I think would not be good for learning.
Hope this helps.
First i have a class called card with this code
public class Card
{
private int value;
private String suit;
// private int value;
//private String rank;
public Card (int v, String s)
{
value=v;
suit=s;
}
public int random()
{
int randomNum = ((int)(Math.random() * 100) % 13 +1);
return randomNum;
}
public void displayCard()
{
System.out.println(value + " of " + suit);
}
}
then i have a class called deck with this code
import java.util.*;
public class Deck
{
public ArrayList<Card> card;
private ArrayList<String> suits;
private ArrayList<Card> hand;
public Deck()// time to build a deck
{
card=new ArrayList<>();
suits=new ArrayList<>();
suits.add("Hearts");
suits.add("Spades");
suits.add("Clubs");
suits.add("Diamonds");
for (int y=2; y<15; y++)
{
card.add(new Card(y,suits.get(0)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(1)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(2)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(3)));
}
}//end of public deck
public ArrayList deal()// deal method
{
hand=new ArrayList<>();
for(int x = 0; x < 5; ++x)//build 5 card hand
{
hand.add(card.get(x));
System.out.println(card.get(x));
}
return hand;
}//end of public void deal
}// end of public class deck
then i have the main
import java.util.ArrayList;
import java.util.*;
public class gamePlay
{
private static gamePlay player1;
public Deck fullDeck;
private ArrayList<Card> yourHand;
public gamePlay()
{
fullDeck=new Deck();
System.out.println("Your poker hand is a");
yourHand = fullDeck.deal();
//System.out.println(yourHand);
}
public static void main(String[] args)
{
player1 = new gamePlay();
}
}
It is printing out some crazy stuff for the value and suit of the cards in the hand
i think they are either memory locations from the arraylist or hexidecimal values i am not sure need it to print suit and rank any help is appreciated
If your classes implement a proper toString method, it will show up perfectly.
You can easily change your existing method displayCard in the Card class to a toString method. This leads to more flexibility than to let the Card print out itself by calling System.out.println in the card's method.
#Override
public String toString() {
return value + " of " + suit;
}
If you want the card to print to System.out you just do System.out.println(card);
Normal arrays can also be converted to String, using Arrays.toString(array) (if you would have a Card[] variable for example). Most implementations of Lists already implement a proper toString method so it will show you a comma-separated list of the entries.
You have to provide a toString() method in your Card class.
For example:
#Override
public String toString() {
return String.format("Card [value=%s, suit=%s]", value, suit);
}
If you don't provide that method, the default depends on the JDK implementation. Usually, it is the name of the class followed by a # and the object hash code.
I suspect that you have to iterate through the array and print each item individually. One cannot print the entire content of an array by toString() the array itself.