jweaver
jweaver

Reputation: 11

Formatted toString()

I am beginner using the toString() method to return a formatted String. I am printing a deck of cards where each column is the different suit. Does anyone have any ideas? Here is the code I have:

public class DeckOfCards {
  public static void main(String[] args) {
    int[] deck = new int[52];
    //String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
    String[] suits = {"Clubs","Diamonds","Hearts","Spades"};
    //String[] ranks = {"Ace","King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"};
    String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King","Ace"};


    // Initialize cards 
        for (int i = 0; i < deck.length; i++) {
            deck[i] = i;
        }

        // Shuffle the cards
        for (int i = 0; i < deck.length; i++) {
            int index = (int)(Math.random() * deck.length);
            int temp = deck[i];
            deck[i] = deck[index];
            deck[index] = temp;
        }

        // Display the all the cards
        for (int i = 0; i < 52; i++) {
            String suit = suits[deck[i] / 13];
            String rank = ranks[deck[i] % 13];
            System.out.println( rank + " of " + suit);
        }


        System.out.println("------------------------------");

        for(int i=0;i<deck.length;i++){
            for(int j=i;j<deck.length;j++){
                if(deck[j]==51-i){
                    int temp = deck[i];
                    deck[i] = deck[j];
                    deck[j] = temp;
                }
            }
        }

        // Display the all the cards
        for (int i = 0; i < 52; i++) {
            String suit = suits[deck[i] / 13];
            String rank = ranks[deck[i] % 13];
            System.out.printf( rank + " of " + suit + "\t");
        }

    }
  }

The main area I believe will be in the toString() is here:

// Display the all the cards
        for (int i = 0; i < 52; i++) {
            String suit = suits[deck[i] / 13];
            String rank = ranks[deck[i] % 13];
            System.out.println( rank + " of " + suit);
        }

How would I use this in the toString() method and also instantiate an object that can print this toString() method? Thank you for your time. So that it displays in order in a game of bridge I was thinking of an output like this:

Ace of Spades     Ace of Hearts     Ace of Diamonds     Ace of Clubs
...
// And so on until it reaches two of clubs

Do any of these ways print it like such without one being extra spaced or if not what could be modified in the toString() to have it come out like that? Thank you for your time, again.

Upvotes: 1

Views: 1045

Answers (4)

Hienz
Hienz

Reputation: 718

Here is a sample code for making a Card and a Deck class too and printing out the whole deck.

class Deck {
    ArrayList<Card> cards = new ArrayList<Card>();
    public Deck() {
        for(int i=0; i < 52; i++ ) {
            cards.add(new Card());
        }
    }

    @Override
    public String toString() {
        String response = "";
        for(int i=0; i<52; i++)
        {
            response = response + "\n" + i+1 + ". Card: " + cards.get(i).toString() ;
        }
        return response;
    }
}

class Card {

    private String suit;
    private String rank;

    @Override
    public String toString() {
        return "It's a " + suit + " " + rank;
    }

    public Card() {
        Random r = new Random();
        int rRank = r.nextInt(12);
        switch(rRank) {
            case 0: {
                this.rank = "Jack";
                break;
            }
            case 1: {
                this.rank = "Queen";
                break;
            }
            case 11: {
                this.rank = "King";
                break;
            }
            case 12: {
                this.rank = "Ace";
                break;
            }
            default: {
                this.rank = rRank + ""; //Don't blame me for it. :D
                break;
            }
        }
        int suit = r.nextInt(3);
        switch(suit) {
            case 0: {
                this.suit = "Club";
                break;
            }
            case 1: {
                this.suit = "Diamond";
                break;
            }
            case 2: {
                this.suit = "Heart";
                break;
            }
            case 3: {
                this.suit = "Spade";
                break;
            }
        }

    }

}


public class Stackoverflow {

    public static void main(String[] args) {
        Deck deck = new Deck();
        System.out.println(deck.toString());
    }

}

Upvotes: 0

David Conrad
David Conrad

Reputation: 16399

Your shuffle is similar to, but not quite, a Fisher-Yates shuffle, and will not give you an even distribution of all the permutations of the cards. (Java comes with the Fisher-Yates shuffle in the java.util.Collections class. You can use Collections.shuffle(list) to shuffle a list of objects into random order.

Once you get the suit and rank of each card you can put them into a list:

    List<Card> cards = new ArrayList<>();

    for (int i = 0; i < 52; i++) {
        String suit = suits[deck[i] / 13];
        String rank = ranks[deck[i] % 13];
        cards.add(new Card(suit, rank));
    }

(You will need to import these classes from java.util at the top of your file.)

import java.util.ArrayList;
import java.util.List;

Create a Card class with a toString method:

public class Card {
    private final String suit;
    private final String rank;

    public Card(String suit, String rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public String getRank() {
        return rank;
    }

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

I have included a few things that you don't strictly need. The fields don't have to be final, but it can be useful later on to have objects that are immutable. Once you create a Queen of Diamonds, it doesn't need to ever turn into another card. A good rule of thumb is, don't make objects mutable unless they really need to be. (A mutable card would have fields that weren't final and would have setters for the fields, not just getters.) I also provided getters for the fields, even though we're not using them here yet. And I included the @Override annotation on the toString method, which isn't strictly necessary, but if you include it when you intend to override a method, the compile will warn you if you didn't, which could happen if I accidentally wrote tostring instead of toString.

Now that we have our cards, we can ask them to print themselves out using their toString method:

for (Card card : cards) {
    System.out.println(card);
}

One last note. In your code, you weren't using System.out.printf correctly. If you wanted to use something like that in your toString method, there is a related method in String, String.format, and its use would look like this:

    @Override
    public String toString() {
        return String.format("%s of %s", rank, suit);
    }

Or, when you print the cards, you could use it like this (%n produces a newline):

for (Card card : cards) {
    System.out.printf("Your card is the %s%n", card);
}

Upvotes: 0

user7717495
user7717495

Reputation:

if you want to instance a object, this is my solution:

Card.java

/*-***************************************************************************
 * Copyright (C) 2017  Miguel Fernandez Fernandez
 *
 * This is free software, licensed under the GNU General Public License v3. 
 * See http://www.gnu.org/licenses/gpl.html for more information.
 ****************************************************************************/

public class Card {

    String suit;
    String rank;

    public Card(String suit, String rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public void setSuit(String suit) {
        this.suit = suit;
    }

    public String getRank() {
        return rank;
    }

    public void setRank(String rank) {
        this.rank = rank;
    }

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

Main.java

/*-***************************************************************************
 * Copyright (C) 2017  Miguel Fernandez Fernandez
 *
 * This is free software, licensed under the GNU General Public License v3. 
 * See http://www.gnu.org/licenses/gpl.html for more information.
 ****************************************************************************/

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        List<Card> deck = new ArrayList<Card>(52);
        String[] suits = { "Clubs", "Diamonds", "Hearts", "Spades" };
        String[] ranks = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace" };

        // Initialize cards
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 13; j++) {
                deck.add(new Card(suits[i], ranks[j]));
            }
        }

        System.out.println("Cards: \n");

        // Print cards
        for (Card c : deck) {
            System.out.println(c.toString());
        }

        System.out.println("\n\nRandom cards...\n\n");

        // Shuffle the cards
        Collections.shuffle(deck);
        System.out.println("Cards: \n");

        // Display the all the cards
        for (Card c : deck) {
            System.out.println(c.toString());
        }
    }
}

Thank you! :)

Upvotes: 1

forJ
forJ

Reputation: 4627

You must create a new class of Cards and have a overriden string class

so like below

public class Cards {

    private int numb;
    private int suite;

    public Cards(int suite, int numb) {
        this.numb = numb;
        this.suite = suite;
    }

    public int getNumb() {

        if (numb == 0){
            return 11;
        }

        if (numb >= 9 && numb <=12){
            return 10;
        }

        return numb + 1;
    }

    @Override
    public String toString() {

        String arbNumb = null;
        String arbSuite = null;

        switch (suite){

        case 0:
            arbSuite = "Heart";
            break;

        case 1:
            arbSuite = "Diamond";
            break;

        case 2:
            arbSuite = "Spades";
            break;

        case 3:
            arbSuite = "Clubs";
            break;

        }

        switch (numb){

        case 0:
            arbNumb = "Ace";
            break;

        case 10:
            arbNumb = "Jack";
            break;

        case 11:
            arbNumb = "Queen";
            break;

        case 12:
            arbNumb = "King";
            break;

        }

        if (numb > 0 && numb < 10){
            arbNumb = String.valueOf(numb+1);
        }

        return arbNumb + " of " + arbSuite;
    }

}

What it means is that when you instantiate the class Cards, numbers will be converted to the corresponding strings when you call yourInstanceOfClass.toString. You can do it for both suite and number.

The numbers that I have assigned is just how I would do it but you can change them to your preference of course.

The getNumb() class is just there to reflect the shift of numbers that I have made.

Upvotes: 1

Related Questions