I'm trying to initialize a new instance of the ArrayList defined in my playingCard.java file:
import java.util.ArrayList;
public class PlayingCard
{
public enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten,
Jack, Queen, King, Ace}
public enum Suit { Spades, Diamonds, Hearts, Clubs }
private final Value value;
private final Suit suit;
/**
* Constructs a card with specified initial value and suit
* #param value
* #param suit
*/
public PlayingCard(Value value, Suit suit)
{
this.value = value;
this.suit = suit;
}
/**
* Retrieves the value of a card
* #return value
*/
public Value getValue()
{
return value;
}
/**
* Retrieves the suit of the card
* #return suit
*/
public Suit getSuit()
{
return suit;
}
/**
* Custom toString
*#return value and suit as a string.
*/
#Override
public String toString()
{
return "PlayingCard[value=" + value + ", suit=" + suit + "]";
}
/**
* Format method to print out the value and suit of a card.
* #return value and suit as a string.
*/
public String format()
{
return value + " of " + suit + ", ";
}
/*private static final List<PlayingCard> deck = new ArrayList<PlayingCard>();
// Initialize deck
static
{
for (Suit suit : Suit.values())
{
for (Value value : Value.values())
{
deck.add(new PlayingCard(value, suit));
}
}
}*/
}
If the last 12 or so lines aren't commented out, there is no problem with the code. However I want to initialize the deck in a separate test driver and receive 2 errors when copying the code over.
The test driver currently looks like this:
import java.util.ArrayList;
public class PlayingCardTester
{
public static void main (String[] args)
{
static List<PlayingCard> deck =
new ArrayList<PlayingCard>();
// Initialize deck
static
{
//for ea PlayingCard.Suit suit in PlayingCard.Suit.values()
for (PlayingCard.Suit suit : PlayingCard.Suit.values())
{
for (PlayingCard.Value value : PlayingCard.Value.values())
{
deck.add(new PlayingCard(value, suit));
}
}
}
}
}
I have an error on line 14 of the test driver
static List<PlayingCard> deck = new ArrayList<PlayingCard>();
saying it's an illegal start of expression. I've tried using different keywords in front of the statement and the error stays the same.
The second error is the last bracket which just says "null".
I am new to using enums, so it could be something very simple which I've over looked...
You don't need static declaration in static method.
List<PlayingCard> deck = new ArrayList<PlayingCard>();
Also there is no need of Static Block since you are already in static context.
References:
Static Initialization Blocks
In PlayingCardTester You should define
static List<PlayingCard> deck =
outside of the main method: one line above "public static void main"
Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.
Link
You can not put static variable or block inside method. Both should be outside of main method.
public class PlayingCardTester
{
static List<PlayingCard> deck = new ArrayList<PlayingCard>();
// Initialize deck
static
{
//for ea PlayingCard.Suit suit in PlayingCard.Suit.values()
for (PlayingCard.Suit suit : PlayingCard.Suit.values())
{
for (PlayingCard.Value value : PlayingCard.Value.values())
{
deck.add(new PlayingCard(value, suit));
}
}
}
public static void main (String[] args)
{
...
}
}
Related
I do not get how to put the Card class into the Deck. Would you please explain how I can fix this?
Here are the instructions:
You need to rewrite the constructor so that all 52 cards of a normal card deck are assigned to the cards array. Keep in mind that card information needs to be stored inside the Deck class and is not passed by parameter. Additionally, you need to re-define the toString method for the Deck class so that it can be used to display the attribute values in a convenient manner. Make sure to take advantage of the toString method that already exists in the Card class.
(You also need to add a shuffle method, which is called from the constructor. The shuffle method is a private helper method in the Deck class. For this version you need to shuffle the deck by swapping the cards. Generate two random numbers in the [0..51] number range that will represent the indexes of the cards array and swap the cards. Make 1000 swaps and then display the cards. Use Math.random to generate random numbers.) <-This is a part of the instructions, but I don't think it matters in this situation because I what I want to know is how to do put the Card class in to the Deck.(but i still put it in just in case)
public class Lab11bvst
{
public static void main(String[] args)
{
Deck deck = new Deck();
System.out.println(deck);
}
}
class Deck
{
private Card[] cards;
private int size;
private String[ ] suits = {"Clubs","Diamonds","Hearts","Spades"};
public Deck()
{
size = 52;
cards = new Card[size];
}
private shuffle(){
}
}
the Card class:
public class Card
{
private String suit;
private String rank;
private int value;
public Card(String s, String r, int v)
{
suit = s;
rank = r;
value = v;
}
public String getSuit() { return suit; }
public String getRank() { return rank; }
public int getValue() { return value; }
public void setSuit(String s) { suit = s; }
public void setRank(String r) { rank = r; }
public void setValue(int v) { value = v; }
public String toString()
{
return "[" + suit + ", " + rank + ", " + value + "]";
}
public boolean matches(Card otherCard)
{
return otherCard.getSuit().equals(this.suit)
&& otherCard.getRank().equals(this.rank)
&& otherCard.getValue() == this.value;
}
}
"rewrite the constructor so that all 52 cards of a normal card deck are assigned to the cards array"
Right now, the constructor is setting the size of the deck to 52 cards, and then it initializes an array to hold 52 elements. You'll need to populate the cards array by creating cards for all 52 cards normally found in a deck. The constructor of your Card class helps you do this.
For example, you could start by adding an Ace of Diamonds and adding it to the cards array:
Card aceD = new Card("Diamonds", "Ace", 1);
cards[0] = aceD;
and then add all 52 cards to your cards array.
//** The code below is broken up into 2 classes and 2 Enums respectively: Card, Deck, Suit and Rank.
I'm having confusion on intertwining a for loop and toString method as asked in the instructions:
Create a toString() method in the Deck class, using another for loop to print all the Cards in the array by calling the toString() method on each card. This method “asks” the Card to print its rank and suit by only calling toString() on the Card object. There should be no reference to Rank or Suit anywhere in this method. Let Card's toString() method do the work (Delegation).
public class Card {
public static void main(String[] args) {
Card myCard = new Card();
System.out.println(myCard.toString());
System.out.println(new Card(Rank.KING, Suit.CLUBS));
}
public Rank rank;
public Suit suit;
public Rank getRank() {
return rank;
}
private void setRank(Rank rank) {
this.rank = rank;
}
public Suit getSuit() {
return suit;
}
private void setSuit(Suit suit) {
this.suit = suit;
}
// Constructor assigning attributes to rank and suit
public Card(Rank rank, Suit suit) {
setRank(rank);
setSuit(suit);
}
public Card() {
this(Rank.ACE, Suit.SPADES);
}
#Override
public String toString() {
// TODO Auto-generated method stub
String result= rank.toString() + " of " + suit.toString();
return result; }
}
public enum Suit {
NONE, CLUBS, HEARTS, SPADES, DIAMONDS
}
public enum Rank {
JOKER, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN,
KING, ACE
}
public class Deck {
public void main(String[] args) {
int[] DeckArray = new int[54];
int count = 2;
System.out.println(count);
for (count = 0; count <= 54; count++)
{
System.out.println(DeckArray);
}
}
public Card cards[];
public void DeckOfCards() {
this.cards = new Card[52];
Card myCard = new Card();
for (int i = 0; i < 0; i++) {
Card card = new Card(Rank.ACE, Suit.CLUBS);
if (Rank.JOKER != null) {
System.out.println("JOKER");
} else {
System.out.println(myCard);
}
}
for (int i = 0; i < 52; i++) {
String Deck = Arrays.toString(DeckArray)
}
}
}
Let me answer this is Psudo-code so that I won't do your homework for you :)
class Deck {
...
public String toString() {
for every item in this.cards {
currentItem.toString() // prints
}
}
}
Best of luck! Once you get the hang of it programming can be really fun.
Since the original code shows some confusion over how to define the condition that ends the for-loop, you may prefer to use this idiom instead:
for ( Card c : cards ) {
// do your work here
}
You can use the Java 8 Streams API, too, although in this case it feels unnecessarily complex:for-
Arrays.asList(cards).stream().forEach(c -> System.out.println(c.toString()));
I am creating a deck of poker cards (52 cards). I want to be able to print it out for example:
2 of Club, 3 of Club......
2 of Diamond, 3 of Diamond....
Queen of Diamond, King of Diamond
and so on for the 52 cards.
I am able to do this now but having problem when it comes to the face cards which are the Jack, Queen, King and Ace. Currently I am using numbers to represent them. so instead of printing Jack of Clubs, it shows as 11 of Clubs which is wrong. I tried to store the face cards in an enum and tried to loop them but can't really get around to do it.
Can I get some advice on how I could get my face cards in instead of representing them as numbers. I have attached my main method and the class below. Thanks for help.
//Card Class
import java.util.Objects;
public class Card {
public enum Suits{
CLUBS, DIAMONDS, HEARTS, SPADES;
}
public enum Faces{
JACK, QUEEN, KING, ACE;
}
private int rank;
private String suit;
public Card(int rank, String suit){
this.rank = rank;
this.suit = suit;
}
public int getRank(){
return rank;
}
public String getSuit(){
return suit;
}
public String format(){
return String.format("%d of %s, ", getRank(), getSuit());
}
}
//Main method
public class CardTester {
public static void main(String[] args) {
Card[] cards = new Card[52];
int i = 0;
for (Card.Suits suit : Card.Suits.values()) {
for (int y = 2; y < 15; y++) {
cards[i] = new Card(y, suit.name());
i++;
}
}
for(Card p : cards){
System.out.print(p.format() + " ");
}
}
}
Change your format() method to:
public String format(){
if (getRank() < 11) {
return String.format("%d of %s, ", getRank(), getSuit());
}
else {
Faces face = Faces.values()[getRank() - 11];
return String.format("%s of %s, ", face, getSuit());
}
}
Alternatively, here's a better implementation for Card:
import java.util.Objects;
public class Card {
public enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES;
}
public enum Rank {
TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
JACK, QUEEN, KING, ACE;
}
private final Suit suit;
private final Rank rank;
public Card(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
public Suit getSuit(){
return suit;
}
public Rank getRank(){
return rank;
}
#Override
public String toString() {
return rank + " of " + suit;
}
#Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + Objects.hashCode(this.suit);
hash = 97 * hash + Objects.hashCode(this.rank);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Card other = (Card) obj;
if (this.suit != other.suit) {
return false;
}
if (this.rank != other.rank) {
return false;
}
return true;
}
}
You can use it like this:
import java.util.ArrayList;
import java.util.List;
public class CardTester {
public static void main(String[] args) {
List<Card> cardList = new ArrayList<>();
Card lastCard = new Card(Card.Suit.SPADES, Card.Rank.ACE);
for (Card.Suit suit : Card.Suit.values()) {
for (Card.Rank rank : Card.Rank.values()) {
Card card = new Card(suit, rank);
cardList.add(card);
if (!card.equals(lastCard)) {
System.out.print(card + ", ");
}
else {
System.out.print(card);
}
}
}
// use cardList
}
}
Your modelling of cards is flawed, and your problem highlights this. Rank is not numeric and should not be an 'int'. You might want to use an enum for the rank.
You might be tempted to give your rank an integer value, but this is probably not a good idea. The value is generally defined by the game you are playing, and not by the deck of cards. For example in poker a king is ranked higher than a jack, but in blackjack they are ranked the same.
May be source code shown below will help you:
public enum Faces
{
JACK( 1, "Jack" ), QUEEN( 2, "Queen" ), KING( 3, "King" ), ACE( 4, "Ace" );
public int GetNumber()
{
return m_number;
}
public String GetName()
{
return m_name;
}
private Faces( int number_, String name_ )
{
m_number = number_;
m_name = name_;
}
private int m_number;
private String m_name;
}
you may delete the enum Faces you already have and add the following method to class Card:
public String getFace(int rank){
String result = "";
switch (rank){
case 11: result = "Jack"; break;
case 12: result = "QUEEN"; break;
case 13: result = "KING"; break;
case 14: result = "ACE"; break;
default:{
result = Integer.toString(rank);
break;
}
}
return result;
}
and modify your format() method to look like this:
public String format(){
return String.format("%s of %s, ", getFace(getRank()), getSuit());
}
This will do the job ;-)
A card consists of RANK and SUIT. Common poker software convention is to represent cards as SUIT+RANK Strings, as in 3c for 3 of clubs and Kd for king of diamonds. (see pokerstove or most hand history producers and consumers)
You need to expand the concept of RANK beyond faces. I've been using the Steve Brecher poker eval library, and his RANK class looks like this:
A simple lookup of the string "23456789TJQKA" converts between the enum and the RANK. There is a similar SUIT enum and a pretty reasonable Comparable class that combines the two.
public static enum Rank {
TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE;
/**
* #return the character in {#link #RANK_CHARS} denoting this rank.
*/
public char toChar() {
return RANK_CHARS.charAt(this.ordinal());
}
/**
* #param c
* a character present in {#link #RANK_CHARS} (case
* insensitive)
* #return the Rank denoted by character.
* #throws IllegalArgumentException
* if c not in {#link #RANK_CHARS}
*/
public static Rank fromChar(char c) {
int i = RANK_CHARS.indexOf(Character.toUpperCase(c));
if (i >= 0)
return Rank.values()[i];
throw new IllegalArgumentException("'" + c + "'");
}
/**
* #return the pip value of this Rank, ranging from 2 for a
* <code>TWO</code> (deuce) to 14 for an <code>ACE</code>.
*/
public int pipValue() {
return this.ordinal() + 2;
}
public static final String RANK_CHARS = "23456789TJQKA";
}
You can find his old but still perfectly serviceable libraries here: http://www.brecware.com/Software/software.html or http://pokersource.sourceforge.net/
U can try this solution which uses enum. First of all you need to create two enums. One for suits and the other for cards.
The enum for suits is:
public enum suits
{
club, diamond,heart,spades
}
The enum for cards is:
public enum cards
{
two(2), three(3), four(4), five(5), six(6), seven(7), eight(8),nine(9),
ten(10), jack(11), queen(12), king(13),ace(14);
int number;
private cards(int number)
{
this.number=number;
}
public int getNumber()
{
return this.number;
}
}
THen in your main class you can loop through both the enums to get your result as follows:
public class Javaclass
{
public static void main(String[] args)
{
int count=2;
for(suits suit:suits.values())
{
for(cards card: cards.values())
{
if(count<=10)
System.out.println(card.getNumber()+" of "+suit);
else
System.out.println(card+" of "+suit);
count++;
}
count=2;
System.out.println("");
}
}
}
Hope this helps.
I'm new to java and I'm becoming overwhelmed by the assignment my professor gave us because I don't really understand how to use the classes and methods that he predesignated for the assignment.
What do I need to provide in the method main in order to use the method:
public static void printHand(Card[] hand)
where Card is a the name of a separate class? If anyone could give me a quick explanation of this question, I would be very grateful.
This is the Card class if it is any help for answering the question:
public class Card {
// Constants for representing the suits
public final static int CLUBS = 0;
public final static int HEARTS = 1;
public final static int SPADES = 2;
public final static int DIAMONDS = 3;
// Constants for representing values of
// ace, jack, queen, and king.
public final static int ACE = 1;
public final static int JACK = 11;
public final static int QUEEN = 12;
public final static int KING = 13;
// Final will keep them from being changed
// after cards are constructed.
private final int value;
private final int suit;
/**
* Constructs a card with a specified suit and value.
*
* #param value
* the value of the card. 2 through 10 are used to specify the
* cards with those corresponding values, and constants exist for
* specifying ace, jack, queen, and king
* #param suit
* the suit of the card. Use one of Card.CLUBS, Card.Hearts,
* Card.SPADES, or Card.DIAMONDS
*/
public Card(int value, int suit) {
if (value < ACE || value > KING) {
throw new IllegalArgumentException("Illegal card value: " + value);
}
if (suit < CLUBS || suit > DIAMONDS) {
throw new IllegalArgumentException("Illegal card suit: " + suit);
}
this.value = value;
this.suit = suit;
}
/**
* Constructs a new card with the same value and suit as the original.
* #param original the card to be copied
*/
public Card(Card original) {
this(original.value, original.suit);
}
/**
* Gets this card's suit.
*
* #return the suit of this card
*/
public int getSuit() {
return suit;
}
/**
* Gets this card's value
*
* #return the value of this card
*/
public int getValue() {
return value;
}
/**
* Gets a letter representing the suit
*
* #return a single letter, either "C", "H", "S", or "D", representing
* clubs, hearts, spades, and diamonds respectively
*/
private String getSuitString() {
return "" + "CHSD".charAt(suit);
}
/**
* Gets a one- or two-character string representing the value
*
* #return either "2" through "10" or "A", "J", "Q", or "K"
*/
private String getValueString() {
return "A 2 3 4 5 6 7 8 9 10J Q K ".substring(2 * (value - 1), 2 * value).trim();
}
/**
* Returns whether two cards have the same suit and value
*
* #param other
* the other object to be compared
* #return true if the other object is a card with the same suit and value
* as this card
*/
public boolean equals(Object other) {
if (!(other instanceof Card))
return false;
if (this == other) {
return true;
}
Card that = (Card) other;
return this.suit == that.suit && this.value == that.value;
}
/**
* Returns a String representation of this card, by combining its value and
* suit (see getValueString() and getSuitString)
*
* #return a 2- or 3-character representation of this card (such as "JD" for
* the jack of diamonds, or "10H" for the 10 of hearts
*/
public String toString() {
return getValueString() + getSuitString();
}
}
You use the toString method in the Card class wich returns a String
System.out.println(card.toString);
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Card[] myHand = new Card[3];
//King of Spades
myHand[0] = new Card(Card.KING, Card.SPADES);
//Ace of spades
myHand[1] = new Card(Card.ACE, Card.SPADES);
//two of hearts
myHand[2] = new Card(2, Card.HEARTS);
printHand(myHand);
}
public static void printHand(Card[] hand) {
System.out.println("The hand concists of the following cards");
for(Card card : hand) {
System.out.println(card.toString());
}
}
}
First you have to create an array of Cards (Card[]) in the main method or any static method will do, because only static methods can be called in other static methods.
Then you can pass that array of cards to the printHand() method, which in-turn, should print out each card that was added to the array of cards. Make sure to populate your array of cards with instances of the Card object.
public static void printHand(Card[] hand) {
for (Card card : hand) {
System.out.println(card);
}
}
public static void main(String[] args) {
Card[] cards = {
new Card(Card.ACE, Card.HEARTS),
new Card(Card.KING, Card.HEARTS),
new Card(Card.QUEEN, Card.HEARTS),
new Card(Card.JACK, Card.HEARTS),
new Card(Card.QUEEN, Card.SPADES)
};
printHand(cards);
}
Output:
AH
KH
QH
JH
QS
So, in my java class, we were given these card and deck classes, which will be used for a card game later on. Here is the card code:
public class Card {
// public constants:
public static final int ACE = 1;
public static final int DEUCE = 2;
public static final int TWO = 2;
public static final int THREE = 3;
public static final int FOUR = 4;
public static final int FIVE = 5;
public static final int SIX = 6;
public static final int SEVEN = 7;
public static final int EIGHT = 8;
public static final int NINE = 9;
public static final int TEN = 10;
public static final int JACK = 11;
public static final int KNAVE = 11;
public static final int QUEEN = 12;
public static final int KING = 13;
public static final int SPADES = 1;
public static final int HEARTS = 2;
public static final int DIAMONDS = 3;
public static final int CLUBS = 4;
// private instance data;
private int rank;
private int suit;
// public constructor:
public Card ( int rank, int suit ) {
if ( rank < Card.ACE | rank > Card.KING | suit < Card.SPADES | suit > Card.CLUBS ) {
throw new IllegalArgumentException();
} else {
this.rank = rank;
this.suit = suit;
}
}
/** Returns this card's suit. */
public int getSuit() {
return this.suit;
}
/** Returns this card's rank. */
public int getRank() {
return this.rank;
}
/** Returns a stringy version of this card. */
public String toString() {
// Replace the next instruction with your code:
throw new UnsupportedOperationException();
}
}
And here is deck class code:
public class Deck {
// private instance data;
private Card[] cards;
// public constructor:
public Deck() {
this.cards = new Card[52];
int i = 0;
for ( int suit = Card.SPADES; suit <= Card.CLUBS; suit++ ) {
for ( int rank = Card.ACE; rank <= Card.KING; rank++ ) {
this.cards[i] = new Card(rank,suit);
i++;
}
}
}
/** Returns a copy of the card at the specified index in this deck. */
public Card cardAt(int index) {
if ( index < 0 | index > 51 ) {
throw new IllegalArgumentException();
} else {
return new Card( this.cards[index].getRank(),this.cards[index].getSuit() );
}
}
/** Shuffles this deck. */
public void shuffle() {
// Replace the next instruction with your code:
throw new UnsupportedOperationException();
}
/** Returns a stringy version of this deck. */
public String toString() {
// Replace the next instruction with your code:
throw new UnsupportedOperationException();
}
}
My issue is that I am stuck on the toString method for both classes and the shuffle method for the deck class. Any help?
The shuffle can be implemented as follows
/** Shuffles this deck. */
public void shuffle() {
// Shuffle the elements in the array
Collections.shuffle(Arrays.asList(cards));
}
The toString simply builds a string and returns it. This can be anything you want to describe your class. Here is what I would do.
for deck
/** Returns a stringy version of this deck. */
public String toString() {
String output="Current Deck:\n";
for (int i=0; i <cards.length ; i++){
output+= cardAt(i).toString();
}
return output;
}
as for card, I'd change a few things. You assign a bunch of ints to represent the card, I would personally use an enum if you don't care about the values. This way cards that have values other than a number, ie a jack vs a 10, will be represented by their name, rather than some number. Who really ever says "i have a 12 of clubs". I'd change my stuff to this.
public enum Rank{ACE,TWO,THREE ....SO ON}
public enum Suit {HEARTS,CLUBS,SPADES,DIAMONDS}
you'd then change all of your get methods, but the real advantage comes in the fact you don't need a long switch statement to deduce the card NAME from the enum values. you can implement toString like this.
//change rank and suit type from int to the Enums
Rank rank;
Suit suit;
/*modify all your getters*/
/** Returns a stringy version of this deck. */
public String toString() {
//enum will be printed out!
return rank+" of " + suit +"\n";
}