toString method of a class - java

I have a card class that looks like this:
public class Card
{
//instance variables
private String faceValue; //the face value of the card
private String suit; //the suit of the card
String[] ranks = {"Ace", "2", "3", "4", "5", "6","7", "8", "9", "10", "Jack", "Queen", "King"};
String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
/**
* Constructor
*/
public Card()
{
for (int i = 0; i < 13; i++)
{
for (int j = 0; j < 4; j++)
{
faceValue = ranks[i];
suit = suits[j];
}
}
}
//getters
/**
* Getter for faceValue.
*/
public String getFaceValue()
{
return faceValue;
}
/**
* Getter for suit.
*/
public String getSuit()
{
return suit;
}
//end of getters
//methods
/**
* This method returns a String representation of a Card object.
*
* #param none
* #return String
*/
public String toString()
{
return "Dealed a card: " + faceValue + " of " + suit;
}
}
And another Deck class that uses the Card class to create an array:
public class Deck
{
//instance variables
private Card[] deck;
/**
* Constructor for objects of class Deck
*/
public Deck()
{
deck = new Card[52];
}
/**
* String representation.
*/
public String toString()
{
return "Dealed a card: " + deck.getFaceValue() + " of " + deck.getSuit();
}
}
My toString method is giving me the error "cannot find symbol - method getFaceValue()". Same for getSuit(). Any ideas why?

deck is an array of Card[] deck. Hence, you can't call the method getFaceValue() nor getSuit() on it, because those 2 methods are part of the Card class and NOT of the array of Cards.

here some possible solutions to your problem as suggested:
public String toString()
{
return Arrays.toString(deck);
}
or for loop through the entire deck
public String toString()
{
String deckInStringForm = "[ ";
for(int indexOfCard = 0; indexOfCard < deck.length; indexOfCard++)
{
deckInStringForm += deck[indexOfCard] + " ";
}
deckInStringForm += "]";
return deckInStringForm;
}
or change/add a function to take an index like so
public String toString(int index)
{
return "Card " + index + ": " + deck[index].toString();
}

Related

Getting null with OOP Deck of Cards Java

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.

Java Printing Out a Deck of Cards with an ArrayList and Nested For Loops

I need to print out a deck of 52 unique cards using an ArrayList and a nested for loop. I've done this just using arrays, but I can't wrap my head around using an ArrayList instead. Any help is appreciated, thank you.
Instance Variables:
public final String[] SUITS = {"Hearts", "Diamonds", "Spades", "Clubs"};
public final String[] DESCRIPTIONS = {"Ace", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen",
"King"};
private ArrayList<Card> deck;
Method to add my deck to the ArrayList:
public void loadDeck1()
{
deck = new ArrayList<Card>();
for(int i = 0; i < DESCRIPTIONS.length; i++)
{
for(int j =0; j < SUITS.length; j++)
{
**deck.add(new Card(DESCRIPTIONS[i], SUITS[j]));
// BlueJ Error: actual and formal argument lists differ in length**
}
}
}
Method to Print Deck:
public void printDeck()
{
for(Card c : deck)
{
System.out.println(c.getSuit() + " of " + c.getDescription());
}
}
edit: Sorry, here's my card class!
public class Card
{
private String suit;
private String description;
/**
* Constructor for objects of class Card
*/
public Card()
{
suit = null;
description = null;
}
/**
* Accessors
*/
/**
* #return the suit of the card
*/
public String getSuit()
{
return this.suit;
}
/**
* #return the description of the card
*/
public String getDescription()
{
return this.description;
}
/**
* Mutators
*/
/**
* #param the suit of the card
*/
public void setSuit(String suit)
{
this.suit = suit;
}
/**
* #param the description of the card
*/
public void setDescription(String description)
{
this.description = description;
}
}
You need to add a constructor which takes two string(suit , description) and create an Card object for Card Class because you will use the constructor in deck.add(new Card(DESCRIPTIONS[i], SUITS[j])); statement.If you dont add this constructor,you can change description or suit variable of card object by setMethods.
public Card(String s , String d)
{
suit = s;
description = d;
}
If you want to use ArrayList instead of arrays for instance variables.
public ArrayList<String> SUITS = add("Hearts");
ArrayList<String> SUITS = add("Diamonds");
ArrayList<String> SUITS = add("Spades");
ArrayList<String> SUITS = add("Clubs");
public ArrayList<String> DESCRIPTIONS = add("Ace");/...
//and add elements of descriptions arrayList
You can also pass an ArrayList a normal for loop instead of for each loop.
Needed to change some part of codes:
for(int i = 0; i < DESCRIPTIONS.size(); i++)
{
for(int j =0; j < SUITS.size(); j++)
{
**deck.add(new Card(DESCRIPTIONS.get(i), SUITS.get(j)));
}
}

Trying to write a program to deal 5 random cards to a hand for poker [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Using the ThinkJava textbook Chapter 14 (objects of objects) and code supplied as a place to start. I am overwhelmed and lost with where to start and what would work. Below is all of the code I am working with. "Hand" is currently an extension of "card collection".
"Write an original Java program to implement the basic structure of a poker game. The program should create a deck of 52 playing cards, create at least 2 empty hands, and deal 5 random cards to each hand. One way to randomize the deal is to shuffle the deck first. The program should show the hands by either printing them on the console or drawing them with the card table code."
Given code that defines the card collection:
import java.util.ArrayList;
import java.util.Random;
/**
* A collection of playing cards.
*/
public class CardCollection {
private String label;
private ArrayList<Card> cards;
/**
* Constructs an empty collection.
*/
public CardCollection(String label) {
this.label = label;
this.cards = new ArrayList<Card>();
}
/**
* Returns the label of the card collection.
*/
public String getLabel() {
return label;
}
/**
* Adds the given card to the collection.
*/
public void addCard(Card card) {
cards.add(card);
}
/**
* Removes and returns the card with the given index.
*/
public Card popCard(int i) {
return cards.remove(i);
}
/**
* Removes and returns the last card.
*/
public Card popCard() {
int i = size() - 1;
return popCard(i);
}
/**
* Returns the number of cards.
*/
public int size() {
return cards.size();
}
/**
* True if the collection is empty, false otherwise.
*/
public boolean empty() {
return cards.size() == 0;
}
/**
* Moves n cards from this collection to the given collection.
*/
public void deal(CardCollection that, int n) {
for (int i = 0; i < n; i++) {
Card card = popCard();
that.addCard(card);
}
}
/**
* Moves all remaining cards to the given collection.
*/
public void dealAll(CardCollection that) {
int n = size();
deal(that, n);
}
/**
* Returns the card with the given index.
*/
public Card getCard(int i) {
return cards.get(i);
}
/**
* Returns the last card.
*/
public Card last() {
int i = size() - 1;
return cards.get(i);
}
/**
* Swaps the cards at indexes i and j.
*/
public void swapCards(int i, int j) {
Card temp = cards.get(i);
cards.set(i, cards.get(j));
cards.set(j, temp);
}
/**
* Randomly permute the cards.
*/
public void shuffle() {
Random random = new Random();
for (int i = size() - 1; i > 0; i--) {
int j = random.nextInt(i);
swapCards(i, j);
}
}
/**
* Returns a string representation of the card collection.
*/
public String toString() {
return label + ": " + cards.toString();
}
}
Code that I have modified a little to build the hand of cards
/**
* A hand of playing cards.
*/
public class Hand extends CardCollection {
/**
* Constructs an empty hand.
*/
public Hand(String label) {
super(label);
}
/**
* Prints the label and cards.
*/
public void display() {
System.out.println(getLabel() + ": ");
for (int i = 0; i < size(); i++) {
System.out.println(getCard(i));
}
System.out.println();
}
public static void main()
{
Hand h = new Hand("one");
Card c = new Card(13,3); //(rank, suit)
h.addCard(c);
System.out.println(h);
}
}
Defines what a card is
/**
* A standard playing card.
*/
public class Card {
public static final String[] RANKS = {
null, "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"};
public static final String[] SUITS = {
"Clubs", "Diamonds", "Hearts", "Spades"};
private final int rank;
private final int suit;
/**
* Constructs a card of the given rank and suit.
*/
public Card(int rank, int suit) {
this.rank = rank;
this.suit = suit;
}
/**
* Returns a negative integer if this card comes before
* the given card, zero if the two cards are equal, or
* a positive integer if this card comes after the card.
*/
public int compareTo(Card that) {
if (this.suit < that.suit) {
return -1;
}
if (this.suit > that.suit) {
return 1;
}
if (this.rank < that.rank) {
return -1;
}
if (this.rank > that.rank) {
return 1;
}
return 0;
}
/**
* Returns true if the given card has the same
* rank AND same suit; otherwise returns false.
*/
public boolean equals(Card that) {
return this.rank == that.rank
&& this.suit == that.suit;
}
/**
* Gets the card's rank.
*/
public int getRank() {
return this.rank;
}
/**
* Gets the card's suit.
*/
public int getSuit() {
return this.suit;
}
/**
* Returns the card's index in a sorted deck of 52 cards.
*/
public int position() {
return this.suit * 13 + this.rank - 1;
}
/**
* Returns a string representation of the card.
*/
public String toString() {
return RANKS[this.rank] + " of " + SUITS[this.suit];
}
}
The deck to work from
import java.util.Arrays;
import java.util.Random;
/**
* A deck of playing cards (of fixed size).
*/
public class Deck {
private Card[] cards;
/**
* Constructs a standard deck of 52 cards.
*/
public Deck() {
this.cards = new Card[52];
int index = 0;
for (int suit = 0; suit <= 3; suit++) {
for (int rank = 1; rank <= 13; rank++) {
this.cards[index] = new Card(rank, suit);
index++;
}
}
}
/**
* Constructs a deck of n cards (null).
*/
public Deck(int n) {
this.cards = new Card[n];
}
/**
* Gets the internal cards array.
*/
public Card[] getCards() {
return this.cards;
}
/**
* Displays each of the cards in the deck.
*/
public void print() {
for (int i = 0; i < this.cards.length; i++) {
System.out.println(this.cards[i]);
}
}
/**
* Returns a string representation of the deck.
*/
public String toString() {
return Arrays.toString(this.cards);
}
/**
* Chooses a random number between low and high, including both.
*/
public int randomInt(int low, int high) {
return 0;
}
/**
* Swaps the cards at indexes i and j.
*/
public void swapCards(int i, int j) {
}
/**
* Randomly permutes the array of cards.
*/
public void shuffle() {
}
/**
* Finds the index of the lowest card
* between low and high inclusive.
*/
public int indexLowest(int low, int high) {
return 0;
}
/**
* Sorts the cards (in place) using selection sort.
*/
public void selectionSort() {
}
/**
* Returns a subset of the cards in the deck.
*/
public Deck subdeck(int low, int high) {
Deck sub = new Deck(high - low + 1);
for (int i = 0; i < sub.cards.length; i++) {
sub.cards[i] = this.cards[low + i];
}
return sub;
}
/**
* Combines two previously sorted subdecks.
*/
public static Deck merge(Deck d1, Deck d2) {
return null;
}
/**
* Returns a sorted copy of the deck using merge sort.
*/
public Deck mergeSort() {
return this;
}
/**
* Reorders the cards (in place) using insertion sort.
*/
public void insertionSort() {
}
}
first your void main needs to create the deck and not the card
public static void main()
{
Hand h = new Hand("one");
Deck D = new Deck();
h.addCard(c);
System.out.println(h);
}
then you have to build your functions to shuffle and deal cards
inside deck there's an array called Cards, you have to permute that array
you'll need somethink like this
public void shuffle()
{
//code to shuffle your deck
}
Finally to deal card should deal the top card of your deck, and then remove the card from the deck
int dealcardindex = 0;
public card Dealcard()
{
Card DealedCard = this.Cards[dealcardindex];
dealcardindex++;
return DealedCard ;
}
finally you'll have something like this on your void main
public static void main()
{
Hand h1 = new Hand("one");
Hand h2 = new Hand("two");
Deck D = new Deck();
Deck.Shuffle();
h1.addCard(Deck.Dealcard());
h1.addCard(Deck.Dealcard());
h1.addCard(Deck.Dealcard());
h1.addCard(Deck.Dealcard());
h1.addCard(Deck.Dealcard());
h2.addCard(Deck.Dealcard());
h2.addCard(Deck.Dealcard());
h2.addCard(Deck.Dealcard());
h2.addCard(Deck.Dealcard());
h2.addCard(Deck.Dealcard());
System.out.println(h);
}

How to print different primitive values from an object [duplicate]

This question already has answers here:
How to make toString method within object?
(4 answers)
Closed 7 years ago.
import java.util.ArrayList;
public class Card {
int number;
String suit;
public Card(int number, String suit) {
this.number = number;
this.suit = suit;
}
public static void main(String[] args) {
String[] suit = {
"Clubs",
"Diamonds",
"Spades",
"Hearts"
};
String[] high = {
"Jack",
"Queen",
"King"
};
ArrayList<Card> deckOfCards = new ArrayList<Card>(52);
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 13; i++) {
deckOfCards.add(new Card (i+1, suit[j]));
}
}
#Override
public String toString(Card card) {
this.suit = suit;
this.number = number;
String type;
if (number < 10) {
type = Integer.toString(number);
}
else {
type = high[i-number];
}
return suit + " of " + type;
}
}
}
So I have the object called card and I want to print the suit (the string) and the number on it (the int) with the method at the bottom but I'm not 100% sure how to do it. Needless to say, the part at the bottom doesn't compile or work
Thanks
This should go inside your Card class:
#Override
public String toString() {
return String.valueOf(this.number) + " of " + this.suit;
}
Call the function like this:
currentCard.toString();
or print it out to the console like this:
System.out.println(currentCard.toString());
toString method doesn't take any arguments and should be inside your card object. It's a string representation of the object. The values are set by the constructor.
Place the suit and high array in your card class at the top with the other variables, so your code looks like this:
int number;
String cardSuit; //renamed this variable because you have an array with the same name
String[] suit = {
"Clubs",
"Diamonds",
"Spades",
"Hearts"
};
String[] high = {
"Jack",
"Queen",
"King"
};
#Override
public String toString()
{
String type;
if (number < 10) {
type = Integer.toString(number);
}
else {
type = high[i-number];
}
return "Suit " + this.suit + " and Number " + this.type;
}
Side Note: It's a good idea to make your variables private and use getters/setters to set and access them. Also, override equals as well. If you're using eclipse it can generate it for you automatically.

Problems on poker game and comparator?

I am trying to create a poker game in which I create the deck in the Card class, and use a comparator to sort the deck in alphabetical order. I'm having trouble with what to put in the comparator, and in my dealer class, (this is where I create the deck, shuffle, as well as calling the comparator). When my CompareCards does compile, my Dealer class will give me the error of:
Dealer.java:24: error: incompatible types: void cannot be converted to String
String s = Collections.sort(deck);
^
Note: Dealer.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
I know that when doing the sort, you have to include the Comparator name, but in this case it doesn't work either way. Here is my card class:
import java.util.*;
public class Card{
String suit = null;
String value = null;
String rank = null;
public static final String[] SUIT = {"C", "D", "H", "S" };
public static final String[] RANK = {"A","2","3","4","5","6","7","8","9","T","J","Q","K"};
public Card(int i, int j){
suit = RANK [i];
rank = SUIT [j];
value = rank + suit;
}
public String getSuit(){
return suit;
}
public String getRank(){
return rank;
}
public String toString(){
return(value);
}
}
Here is my Comparator and CompareCards class:
public interface Comparator <Card>{
public int compare(Card o1, Card o2);
}
public class CompareCards implements Comparator<Card>{
public int compare(Card c1, Card c2){
int x = 0;
int y = 0;
int dx = c1.getRank() - c2.getRank();
if(dx == 0){
x = c1.getRank()-c2.getRank();
}
else{
y = c1.getSuit() - c2.getSuit();
}
return x;
}
And here is the dealer class:
import java.util.*;
public class Dealer{
public static void main(String[]args){
// creating deck
List<Card> deck= new ArrayList<Card>();
// calling Card
for(int i = 0; i < 13 ; i++){
for(int j = 0; j < 4 ; j++){
// String s = RANK[i] +SUIT[j];
deck.add(new Card(i, j));
}
}
finding21(deck);
}
public static void finding21 (List deck){
String s = Collections.sort(deck);
System.out.println("Sorted deck: " + s);
// After I sort the deck I am supposed to do a binary search
// for the queen of hearts
/* Collections.shuffle(deck);
System.out.println("Shuffled deck: " + deck);
String HQ = Collections.binarySearch(deck, "HQ");
System.out.print(HQ);
System.out.println(queenH);*/
}
}
Collections.sort does an in-place sort and does not return a value.
That's why the compiler says you can't convert a void to a String.
The void type is used for functions with no return value.
Just use:
Collections.sort(deck);
If you want to print the sorted deck after, you can use:
System.out.println("Sorted deck: " + deck);

Categories