OOP BlackJack Game (Creating Deck)

2019-02-26 13:11发布

I am attempting to create an OOP friendly Java BlackJack game to progress my knowledge.

I've hit a wall and I just don't know enough to see the problem. Was wondering if anyone could point out my problems.

Additionally, after googling relevant topics about this I've found people time and time again saying using enums would be more beneficial, as a beginner would this be advised? Or should I stick with String arrays for the time being.

Thank you.

my code:

public class BlackJack{

BlackJack() {
    Deck deck =  new Deck();
    deck.createDeck();
    System.out.println(deck.deckList);
}

public static void main(String[] args) {

    new BlackJack();


   }
}


public class Card{

private String valueCard;
private String suitCard;

public Card(String value, String suit) {
    this.valueCard = value;
    this.suitCard = suit;
}

public String getValue() {
    return valueCard;
}
public String getSuit() {
    return suitCard;
  }
}

import java.util.ArrayList;


public class Deck {

ArrayList<Card> deckList = new ArrayList<Card>();

String[] value = {"Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
        "Jack", "Queen", "King", "Ace"};
String[] suit = {"Hearts", "Clubs", "Spades", "Diamonds"};


Deck() {

    deckList = new ArrayList<Card>();

}

public void createDeck() {
    for (int i = 0; i < value.length; i++) {
        for (int x = 0; x < suit.length; x++) {
            Card card = new Card(value[i], suit[x]);
            deckList.add(card);

          }
      }
  }
}

edit: at the moment my out-put from my println is: [Card@addbf1, Card@42e816, Card@9304b1, ... etc] What does this mean?

Thank you for your time.

EDIT: Anyone who also needs an answer to this in the future:

added:

    @Override
public String toString(){
    return valueCard + " of " + suitCard;
}
 }  

to my Card class and then used it in the Deck class:

import java.util.ArrayList;


public class Deck {

ArrayList<Card> deckList = new ArrayList<Card>();

String[] value = {"Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
        "Jack", "Queen", "King", "Ace"};
String[] suit = {"Hearts", "Clubs", "Spades", "Diamonds"};


Deck() {

    deckList = new ArrayList<Card>();

}

public void createDeck() {
    for (int i = 0; i < value.length; i++) {
        for (int x = 0; x < suit.length; x++) {
            Card card = new Card(value[i], suit[x]);
            deckList.add(card);
            card.toString();
        }
    }
}
}

ENUM: public class CardEnum {

public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
    SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }

public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }


}


public class Card{

private CardEnum.Rank rank;
private CardEnum.Suit suit;

public Card(CardEnum.Rank rank, CardEnum.Suit suit) {
    this.rank = rank;
    this.suit = suit;
}

public Rank getRank() {
    return rank;
}
public Suit getSuit() {
    return suit;
}

@Override
public String toString(){
    return rank + " of " + suit;
}
}

1条回答
再贱就再见
2楼-- · 2019-02-26 13:44

Based on your edit, I see that your code is printing out the default value returned by Object's toString() method, which is the name of the current object's class and the object's hashCode. To correct this and to have your Strings make sense, you must give each of your classes a public String toString() method override. The Card class should have a toString() method that returns a String that describes the suit and value of the current card, and the Deck class should iterate through each Card and call the card's toString().

Something like:

@Override
public String toString() {
  return /* code in here to get the contents of the fields held by the Card object */
}

Edit regarding:

I'm just about to delv into enum's I was just curious as I am looking at: docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html But I have two separate classes: Card & Deck. Do I have to copy both sets of enums into both classes for this to work? So I have Card{ enum declaration, private final's, card(Value value, Suit suit) {} then in the deck class will I have to copy the list of enums there again? Bit confused how my deck and card class will be using the enums. Thanks for your patience with a noobie!

No, the enums in that example behave as if they were declared public static -- so they do not need a Card instance to access and are available outside of the Card class. You just have to qualify them to use them. i.e., Card.Rank.FOUR to access Rank's FOUR instance. So in sum, you do not have to re-declare the enums anywhere. I personally think that it is cleaner to have each of the enums in their own file, in the same package as the Card class, but not in the same file.

Edit 2 You state:

OK I've created public class CardEnum { public enum RANK {//ranks} public enum Suit { //suits} how do I get it to interact with my Card class?

You would give Card two private fields, one of CardEnum.Rank type (note that the enum name should not be all cap) and one of CardEnum.Suit type. Then you would assign these values in Card's constructor. I would make this class "immutable", meaning once you've set the Rank and the Suit for a Card, it should never be allowed to change. So I'd give each of these fields a getter method but I wouldn't give it a setter method.

So

public class Card {
  private CardEnum.Suit suit;
  private CardEdum.Rank rank;

  public Card(CardEnum.Suit suit, CardEnum.Rank rank) {
     this..... etc...
  }

  // getter methods here, but no setter methods

  // ....

Edit 3

one last issue with my get methods: public Rank getRank() { return rank; } gives the error: "rank cannot be resolved" I have editted my main post with my current code to make it easy to read.

You have embedded your Rank enum inside of a CardEnum class and so you have to qualify Rank and Suit with the CardEnum class name. Thus you would do:

public CardEnum.Rank getRank() {
   return rank;
}

One suggestion to get rid of all the extra verbiage -- just get rid of CardEnum altogether, and instead put each enum in its own file, a Rank.java file and a Suit.java file. i.e.

// this guy goes in the Suit.java file
public enum Suit {
   CLUBS, DIAMONDS, HEARTS, SPADES
}

Then when you refer to Suit, you don't need to call it CardEnum.Suit.

查看更多
登录 后发表回答