I am attempting to create a deck and apply a suite to each one, for example:
cardValue[0][1] and convert it into cardValue[Spade][1]
but I don't understand how to convert it. What I have currently:
int cardValues[][];
for(int a = 0; a <= 3; a++)
{
for(int b = 0; b <= 12; b++)
{
cardValues[][] += cardValues[a][b];
if(cardValues[a][b] == cardValues[a][0])
{
cardValues[a][b] = 5;
}
else if(cardValues[a][b] > cardValues[a][0] || cardValues[a][b] < cardValues[a][10])
{
cardValues[a][b] = 1;
}
else if(cardValues[a][b] == cardValues[a][10])
{
cardValues[a][b] = 2;
}
else if(cardValues[a][b] == cardValues[a][11])
{
cardValues[a][b] = 3;
}
else if(cardValues[a][b] == cardValues[a][12])
{
cardValues[a][b] = 4;
}
}
}
I don't understand how to convert the 0, 1, 2, and 3 into spades, diamonds, clubs, hearts.
I would do something like that:
Suit.java
public enum Suit {
SPADES, DIAMONDS, CLUBS, HEARTS
}
Card.java
public class Card {
private Suit suit;
private String value;
public Card(Suit suit, String value) {
this.suit = suit;
this.value = value;
}
public Suit getSuit() {
return suit;
}
public void setSuit(Suit suit) {
this.suit = suit;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Main.java
public class Main {
public static void main(String[] args) {
String[] values = new String[]{"K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2", "A"};
Card[] deck = new Card[52];
int i = 0;
for (Suit suit : Suit.values()) {
for (String value : values) {
deck[i++] = new Card(suit, value);
}
}
for (Card card : deck) {
System.out.println(card.getValue() + " of " + card.getSuit());
}
}
}
Related
So I am building up to a card game but, but I am having some trouble building the deck of cards and OOP in general so I was wondering if I could get some help. This is what I have so far.
public class Card {
String[] rank = {"Ace", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "Jack", "Queen", "King"};
String suit;
int value;
String color;
public Card(String suit, int value) {
this.suit = suit;
this.value = value;
if (suit.equals("Hearts") || suit.equals("Diamonds")) {
color = "red";
} else {
color = "black";
}
}
public int getValue() {
return value;
}
public String getColor() {
return color;
}
public String getSuit() {
return suit;
}
public String getName() {
name = rank[(value - 1)];
return name;
}
public String toString() {
return name + " of " + suit;
}
}
The class for my deck of cards (so far) is as follows:
public class Deck {
String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
static String[] cards = new String[52];
public Deck() {
int index = 0;
for (int i = 0; i < 4; i++) {
// For each value of card with this suit.
for (int j = 1; j <= 13; j++) {
Card card = new Card(suits[i], j);
cards[index] += card;
index += 1;
}
}
}
public static void all() {
for (int i = 0; i < cards.length; i++) {
System.out.println(cards[i]);
}
}
}
So my question was when I print out the cards, I get something like
nullnull of Hearts
nullnull of Hearts
nullnull of Hearts
nullnull of Hearts....
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds... etc.
Why am I getting these nulls? What am I doing wrong? Also, any other tips to improve my code would be greatly appreciated.
Your problem is the following line of code from the constructor of class Deck.
cards[index] += card;
You need to remove the +.
An array of objects in java is always initialized such that every element is null. Hence you are appending a card to null.
If you would step through your code with a debugger, you would have discovered that. All good IDEs have a debugger. You should learn to use it.
Note that the code in your question does not compile but I figured out how to fix it since the problems are minor.
For the sake of completeness. Here is your code with my fixes. Compare it to your code.
Class Card
public class Card {
String[] rank = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
String suit;
int value;
String color;
public Card(String suit, int value) {
this.suit = suit;
this.value = value;
if (suit.equals("Hearts") || suit.equals("Diamonds")) {
color = "red";
}
else {
color = "black";
}
}
public int getValue() {
return value;
}
public String getColor() {
return color;
}
public String getSuit() {
return suit;
}
public String getName() {
String name = rank[(value - 1)];
return name;
}
public String toString() {
return getName() + " of " + suit;
}
}
Class Deck
(Note that I added a main() method just for testing purposes.)
public class Deck {
String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
Card[] cards = new Card[52];
public Deck() {
int index = 0;
for (int i = 0; i < 4; i++) {
// For each value of card with this suit.
for (int j = 1; j <= 13; j++) {
Card card = new Card(suits[i], j);
cards[index] = card;
index += 1;
}
}
}
public void all() {
for(int i = 0; i < cards.length; i++) {
System.out.println(cards[i]);
}
}
public static void main(String[] args) {
new Deck().all();
}
}
Your example does not look complete, as I don't see name field in Card class defined. But what I see is that name is initialized in getName methods. I guess you don't initialize it.
Either use getName in toString:
public String toString(){
return getName() + " of " + suit;
}
or initialize name in the constructor: name = rank[(value - 1)]
Prefer initialization in the constructor, otherwise if you refer to name in some other place you can get the same issue.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have to create 3 class (Card, Deck and Tester) to play a game of card. The rules are easy, just compare two cards randomly from the deck and whichever one is higher is the winner. It runs for the entire deck.
Here's my card class (I exclude my comments)
public class Card {
private int value;
private String suit;
public Card(){
value =1;
suit = "clubs";
}
public Card(int n, String s) {
n = value;
s = suit;
}
public int getValue() {
return value;
}
public void setValue(int n) {
if ((n >0) && (n<14)) {
n = value;
}
else {
return;
}
}
public String getSuit() {
return suit; // return the string
}
public void setSuit(String s) {
if ((s.equals("clubs") || (s.equals("hearts") || (s.equals("diamonds") || (s.equals("spades")))))){
s = suit;
}
else {
return;
}
}
public int rank() {
int rank=0;
int suitVal=0;
if (suit.equals("clubs")) {
suitVal =1;
}
else if(suit.equals("diamonds")) {
suitVal =2;
}
else if(suit.equals("hearts")) {
suitVal =3;
}
else if(suit.equals("spades")) {
suitVal =4;
}
rank= (4*(value-1)) + suitVal;
return rank;
}
}
Deck class:
import java.util.ArrayList;
public class Deck {
int[] value= {1,2,3,4,5,6,7,8,9,10,11,12,13};
String[] suit= {"clubs", "diamonds", "hearts", "spades"};
public ArrayList<Card> card = new ArrayList<Card>();
public Deck() { // make default constructor
for (int a=0; a< value.length; a++) {
for (int b=0; b< suit.length ; b++){
card.add(new Card(value[a], suit[b]));
}
}
}
public Card drawCard() {
int number = (int) Math.random()* (card.size());
Card temp = card.get(number);
card.remove(number);
return temp;
}
Tester:
public class Tester {
public static void main(String[] args) {
Deck deck1 = new Deck();
Card x = deck1.drawCard();
Card y = deck1.drawCard();
int point1=0;
int point2=0;
int player=x.rank();
int comp=y.rank();
for (int i=0; i<52; i++) {
if (player > comp) {
point1++;
}
else {
point2++;
}
}
if (point1 > point2) {
System.out.println("Player is the winner");
}
if (point1 < point2) {
System.out.println("Computer is the winner");
}
}
When I run it it says "Null pointer Exception" and point at line 42 of Card class and line 14 of Tester class. Please help
In the card class,the assignment in parmeterized constructor is wrong, you have the parameters as n and s and this value you should assign to value and suit. But you are doing other way,
public Card(int n, String s) {
n = value;
s = suit;
}
Instead of that, you should assign the values of the parameter to value and suit, something like this.
public Card(int n, String s) {
value = n;
suit = s;
}
This is the reason the value and suit is default all the time, you never changed it.
hello and welcome to SO #Elvin.
As mentioned in the comments the NPE is telling you where the problem occurs.
Your "suits" in if (suit.equals("clubs")) is null.
The problem is in your card constructor method:
public Card(int n, String s) {
n = value;
s = suit;
}
you have it the oposite way, it should be because your attributes are value and suit, so you should "store" the new values in them:
public Card(int n, String s) {
value = n;
suit = s;
}
You seem to be new, try to understand always the message of the error and of course, debug ;)
I am trying to make a basic outline for a card game, I have the deck created, a method created for dealing a random card but I am having difficulty for adding the card into the actual hand. The issue is in the Game class with the getCard() method. I do not know the correct way to do this, since my idea did not work.
Class to create the deck:
import java.util.Random;
public class Deck<E> {
//create a new linked list for Deck
LinkedPositionalList deck = new LinkedPositionalList();
public Deck(){
for (int i = 0; i < 4; i++){
for(int j = 2; j< 14; j++){
Card card = new Card(i,j);
deck.addLast(card); //add to linked list
}
}
}
public Card card(){
Random rand = new Random();
int position = rand.nextInt(52);//create random number 0-52
int counter = 0;
Iterator<Card> iter = this.deck.iterator();
while(counter <= position){
Card card = iter.next();
if(counter == position){
iter.remove();
return card;
}
counter++;
}
return null;
}
}
Class to create the card:
public class Card<E> {
public final static int CLUBS = 0,
SPADES = 1,
DIAMONDS = 2,
HEARTS = 3;
private final static String [] suitNames = {"CLUBS", "SPADES", "DIAMONDS", "HEARTS"};
// Special cards
private int JACK_VALUE = 11;
private int QUEEN_VALUE = 12;
private int KING_VALUE = 13;
private int ACE_VALUE = 14;
// The card
private int suit = 0; // Suit of the card
private int value = 2; // Value of the card
public int getSuit() {
return this.suit;
}
public int getValue() {
return this.value;
}
public Card(int suit, int value ){
this.suit = suit;
this.value = value;
}
public String suitToString() {
return suitNames[ suit ];
}
public String valueToString() {
if (value == ACE_VALUE) {
return "ACE";
} else if (value == JACK_VALUE) {
return "JACK";
} else if (value == QUEEN_VALUE) {
return "QUEEN";
} else if (value == KING_VALUE) {
return "KING";
} else if ( value > 0 ) {
return String.valueOf(value);
}
return "";
}
public String shortValueToString() {
if (value == ACE_VALUE) {
return " A";
} else if (value == JACK_VALUE) {
return " J";
} else if (value == QUEEN_VALUE) {
return " Q";
} else if (value == KING_VALUE) {
return " K";
} else if ( value > 0 ) {
return String.format("%2d",value);
}
return "";
}
public String toString() {
return valueToString() + " of " + suitToString();
}
public String toShortString() {
return shortValueToString() + suitToString().substring(0,1);
}
public boolean equalTo(Card c ) {
if ( c.getSuit() != this.getSuit()) return false;
if ( c.getValue() != this.getValue()) return false;
return true;
}
}
Class to create the hand:
public class CardHand<E> {
LinkedPositionalList<E> hand = new LinkedPositionalList();
//TODO: create method to order hand
}
Class to initialize the game:
public class Game{
int players;
int maxCardsInHand;
int decks;
CardHand[] hand;
Card card;
Deck deck;
//constructor
public Game(int player, int max, int numDecks){
players = player;
maxCardsInHand = max;
decks = numDecks;
this.hand = new CardHand[player];
for(int index = 0; index < hand.length; index++){
this.hand[index] = new CardHand();
}
}
public void getCard(){
System.out.println("You got this far...");
card = deck.card();
for(int index = 0; index < hand.length; index++){ //to add to each players hands
hand[index] = card; //issues with this part
}
//TODO: ordered correctly by suit AND value
}
Given that the call iter.remove(); works, your deck gets smaller and smaller each time you call the card() method. Yet you assume you can iterate thru a full deck:
rand.nextInt(52);
Instead, iterate only over the cards you have left:
rand.nextInt(this.deck.size());
If there is no size() or length() method for the list object, decrease a counter each time card() is called:
rand.nextInt(cardsInDeck++);
Im having trouble converting the r[rank] to String. Eclipse keeps saying it needs to be resolved to an array. Also having trouble with Cards[13*i + j] = new Card(i, j); it just keeps saying cannot be resolved to a variable. Heres my code...
public class Card {
private String suit;
private String rank;
private static String[] s = { "hearts", "spades", "diamonds", "clubs" };
private static String[] r = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
public Card(int suit, int deck){
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 13; j++){
Cards[13*i + j] = new Card(i, j);
}
}
}
public Card(String r, String s, String suit){
for(int rank = 0; rank < r.length(); rank+=1){
if( rank.equals(r[rank]) ){
this.rank = r+1;
}
}
this.suit = suit;
}
public String getSuit(){
return suit;
}
public void setSuit(String a, String suit) {
this.suit = suit;
}
public String getRank(){
return rank;
}
public void setRank( String s, String rank){
this.rank= rank;
}
public String toString(){
return String.valueOf(this.getRank()) + String.valueOf(this.getSuit().charAt(0));
}
}
public class Deck {
private Card[] deck;
private int inDeck;
private final int SIZE_OF_DECK = 52;
private int currentCard;
public Deck(){
deck = new Card[deck];
}
private void init(){
}
public void shuffle(int num){
int i,j,k;
for (k = 0; k < num; k++)
{
i = (int) (SIZE_OF_DECK * Math.random()*100);
j = (int) (SIZE_OF_DECK * Math.random()*100);
Card tmp = deck[i];
deck[i] = deck[j];
deck[j] = tmp;
}
currentCard = 0;
}
public Card getCard(){
if (currentCard<SIZE_OF_DECK)
{
return deck[currentCard++];
}
else
{
System.out.print("out of cards error");
return null;
}
}
public int totalCards(){
return SIZE_OF_DECK ;}
}
You never initialize your card array... try something along the lines of this before you create each individual object with your loops.
Card[] cards = new Card[52];
public enum Suit
{
CLUBS,
HEARTS,
SPADES,
DIAMONDS
}
public enum Value
{
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING,
ACE
}
Card.java
public class Card {
private Suit suit;
private Value value;
public Card(Suit theSuit, Value theValue)
{
suit = theSuit;
value = theValue;
}
public String toString()
{
return value + " of " + suit;
}
public Value getValue()
{
return value;
}
public Suit getSuit()
{
return suit;
}
public boolean equals(Card other)
{
if (value.ordinal() == other.value.ordinal()
|| suit.ordinal() == other.suit.ordinal())
{
return true;
}
else {
return false;
}
}
}
CardPile.java
public class CardPile
{
public Card[] cards;
private int numCards;
public CardPile()
{
this.cards = new Card[52];
this.numCards = 0;
// The problem is here, when I try to iterate through the enums and the
// array to populate my cards[] of 52 objects Card it populates it with
// 52 Card which are all ACE of DIAMONDS, it looks like the triple loops
// populates 52 times the two last elements of my enum, but I can't
// figure out how to fix that! Thanks in advance!
for (Suit s : Suit.values())
{
for (Value v : Value.values())
{
for (int π = 0; π < cards.length; π++)
{
cards[π] = new Card(s, v);
}
}
}
}
public boolean isEmpty()
{
for (int i = 0; i < cards.length; i++)
{
if (cards[i] != null)
{
return false;
}
}
return true;
}
public int getNumCards()
{
return numCards;
}
}
The problem is here:
for (int π = 0; π < cards.length; π++) {
cards[π] = new Card(s, v);
}
You're using the same s and v variables to create your Card instance and assign it to all the elements in the cards array, replacing every value on every (s, v) pair combination.
Change the code in order to fill it using just the first 2 for-loops:
int count = 0;
for (Suit s : Suit.values()) {
for (Value v : Value.values()) {
if (count < cards.length) {
cards[count++] = new Card(s, v);
}
}
}
By the way, you should not use names as π for variables and make sure to indent your code.
For every suite and value you iterate over all the 52 cards and set them to be that suit and value. As the last suit/value pair is DIAMOND and ACE, that's what all the cards end up as in the end.
If you get rid of the loop using π, and instead just do:
int counter = 0;
for (Suit s : Suit.values())
{
for (Value v : Value.values())
{
cards[counter++] = new Card(s, v);
}
}
Then I think that should work.