Natecat
Natecat

Reputation: 2172

Blackjack program returning cards as null?

Main Class:

public class Blackjack {

static Deck D;
static Hand P;
public static void main(String[] args) {
    init();
}

private static void init() {
    D=new Deck();
    P=new Hand(D);
    startGame();
}

private static void startGame() {
    System.out.print("Your cards are: "+P.H.get(0)+", "+P.H.get(1));
}

}

Hand Class:

import java.util.ArrayList;
import java.util.Random;


public class Hand {
ArrayList<String> H;
Random R;
public Hand(Deck D){
    R=new Random();
    H=new ArrayList<String>();
    int C=R.nextInt(D.getP().length);
    H.add(D.getP()[C]);
    D.removeFromDeck(C);
    int E=R.nextInt(D.getP().length);
    H.add(D.getP()[E]);
    D.removeFromDeck(E);
}

}

Deck Class

public class Deck {
String[] P;
public Deck(){
    P=new String[52];
    String Suit="Default";
    int C=0;
    for(int A=1;A<=4;A++){
        switch(A){
        case 1:
            Suit="Hearts";
            break;
        case 2:
            Suit="Diamonds";
            break;
        case 3:
            Suit="Clubs";
            break;
        case 4:
            Suit="Spades";
            break;
        }
        for(int B=1;B<=13;B++){
            if(B>10){
                switch(B){
                case 11: P[C]="Joker of "+Suit; 
                break;
                case 12: P[C]="Queen of "+Suit;
                break;
                case 13: P[C]="King of "+Suit;
                break;
                }
            }else{
                P[C]=B+" of "+Suit;
            }
        }
    }
}
public void setP(String[] p) {
    P = p;
}
public String[] getP() {
    return P;
}
public void removeFromDeck(int C){
    System.arraycopy(P, C + 1, P, C,
            P.length - C - 1);
}

}

When I compile and run this code, it prints that my 2 cards are null, null. I have looked through the code and can't seem to find my error. Maybe you can? TY for any help you give me.

Edit: It is now returning spades only, could someone please help?

Upvotes: 1

Views: 586

Answers (3)

Spoike
Spoike

Reputation: 121772

I'm puzzled as to why you haven't encapsulated the Card class yet as it would make instantiation of cards easier. Furthermore you can always abstract suit into its own class or enum.

Anyhow, I might be doing too much of the design work for you but here are some things to get you started:

public enum Suit {
    Spade,
    Heart,
    Diamond,
    Club;

    public static Suit getSuit(int suit) {
        switch (suit) {
            case 3: 
                return Suit.Spade;
            case 2:
                return Suit.Heart;
            case 1:
                return Suit.Diamond;
            case 0:
            default:
                return Suit.Club;
        }
    }
}

And here is a simple Card class that uses this suit.

public class Card {

    private Suit suit;
    private int value;

    public Card(Suit suit, int value) {
        this.suit = suit;
        this.value = value;
    }

    public Card(int suit, int value) {
        this(Suit.getSuit(suit), value);
    }

    public int getValue() { return value; }
    public Suit getSuit() { return suit; }

}

Creating the deck is simple. Here is a simple factory to get you started:

public class DeckFactory {

    public static List<Card> BuildDeck() {
        List<Card> cards = new ArrayList<Card>();

        for (int value = 1; value <= 13; ++value) {
            for (int suit = 0; suit < 4; ++suit) {
                cards.add(new Card(value, suit));
            }
        }

        return cards;
    }

}

I leave the actual implementation of putting it into a Deck or Hand class for yourself. In your Card class you can override the toString() method to return a better string representation of the Card object.

// in Card.java
@override
public String toString() {

   String output = "";

   switch(this.value) {
       1: 
           output += "Ace ";
           break;
       11: 
           output += "Jack ";
           break;
       12: 
           output += "Queen ";
           break;
       13: 
           output += "King ";
           break;
       default:
           output += this.value;
           break;
   }

   output += " of ";

   output += this.suit.toString();
       // returns the name of the enum

   return output;

}

Hope this helps out.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500465

Both your loops have conditions the wrong way round:

for(int A=1;A>=4;A++)

   ...
   for(int B=1;B>=13;B++)

Neither of these will execute any iterations. They should be:

for(int A=1;A<=4;A++)

   ...
   for(int B=1;B<=13;B++)

Additionally, you're not allocating enough size:

P=new String[51];

There are 52 cards in a back, not 51.

EDIT: As noted in comments, you'll always get spades with the code as posted, because your switch statement to select the suit doesn't have any breaks in. I would have expected this to result in a compile-time warning. You really should pay attention to warnings. You can add break statements like this:

switch(A) {
    case 1:
        S = "Hearts";
        break;
    case 2:
        S = "Diamonds";
        break;
    case 3:
        S = "Clubs";
        break;
    case 4:
        S = "Spades";
        break;
}

Finally, I would strongly advise you to use more meaningful variable names, preferrably following Java naming conventions. (There are actually various other changes I'd make to your code, but start off with those.)

Upvotes: 5

npinti
npinti

Reputation: 52185

At a first glance the issue seems here: for(int A=1;A>=4;A++){ and here for(int B=1;B>=13;B++){. These loops will never execute because in your first loop, at the first iteration A will be 1, hence being less than 4, meaning it breaks your condition for the first loop and the same applies for the second loop. Replacing the > with < should yield you something.

Upvotes: 1

Related Questions