0

I'm in CS2 for my college program and I've been tasked with creating code for a PokerCard class which extends off of a Card class that carries a bunch of methods which it overrides. In this particular instance, I am overriding the toString method for testing and am in the middle of writing a bunch of if statements. Is it possible to create a for loop that can loop the creation of my code? I tried inserting i's in place of ordinals for enums but am I stuck with this ugly code here? Thanks in advance!

/**
 * An child of the Card class intended to Override the toString of the card
 * class. The toString will output integer form followed by a suit symbol.
 * 
 * @author Steven Lee
 */
// Implement PokerCard as an interface with Comparable
public class PokerCard extends Card {
    /**
     * Child constructor that copies the constructor of the parent Card. Create
     * constructor.
     * 
     * @param suit
     * @param rank
     */
    public PokerCard(Suit suit, Rank rank) {
        super(suit, rank);
    }

    /**
     * TODO Create compareTo Override here. comapareTo should be checking for card
     * rank differences and sorting them from lowest rank to highest (2 to Ace).
     */

    /**
     * TODO Override toString from parent Card. This should print in the following
     * format: "[Initial][Suit]. Initial is either an int or capitalized first
     * letter of the rank. Suit will be output with unicode.
     */
    @Override
    public String toString() {
        // Check for rank value. If J-A.
        String letter = null;
        String symbol = null;
        if (PokerCard.this.getRank().equals(Rank.ACE)) {
            letter = "A";
        }
        if (PokerCard.this.getRank().equals(Rank.KING)) {
            letter = "K";
        }
        if (PokerCard.this.getRank().equals(Rank.QUEEN)) {
            letter = "Q";
        }
        if (PokerCard.this.getRank().equals(Rank.JACK)) {
            letter = "J";
        }
        if (PokerCard.this.getRank().equals(Rank.JACK)) {
            letter = "J";
        }
        if (PokerCard.this.getRank().equals(Rank.TEN)) {
            letter = "10";
        }
        if (PokerCard.this.getRank().equals(Rank.NINE)) {
            letter = "9";
        }
        if (PokerCard.this.getRank().equals(Rank.EIGHT)) {
            letter = "8";
        }
        if (PokerCard.this.getRank().equals(Rank.SEVEN)) {
            letter = "7";
        }
        if (PokerCard.this.getRank().equals(Rank.SIX)) {
            letter = "6";
        }
        if (PokerCard.this.getRank().equals(Rank.FIVE)) {
            letter = "5";
        }
        if (PokerCard.this.getRank().equals(Rank.FOUR)) {
            letter = "4";
        }
        if (PokerCard.this.getRank().equals(Rank.THREE)) {
            letter = "3";
        }
        if (PokerCard.this.getRank().equals(Rank.TWO)) {
            letter = "2";
        }
        if (PokerCard.this.getSuit().equals(Suit.SPADES)) {
            symbol = "\u2660";
        }
        if (PokerCard.this.getSuit().equals(Suit.HEARTS)) {
            symbol = "\u2665";
        }
        if (PokerCard.this.getSuit().equals(Suit.DIAMONDS)) {
            symbol = "\u2666";
        }
        if (PokerCard.this.getSuit().equals(Suit.CLUBS)) {
            symbol = "\u2663";
        }
        return letter + symbol;
    }
}

I'm hoping to streamline the if statement creation process. Or if there is a better way to arrange this toString, I'd greatly appreciate that as well. thank you in advance. (Note that as far as the exercise goes, there is no need to add the red colored suit variants)

Abra
  • 19,142
  • 7
  • 29
  • 41
Leeky
  • 1
  • Modify the `Rank` and `Suit` enums to also return rank and suit symbols. Then you can get the symbols through the `Card` instance. – Gilbert Le Blanc Mar 05 '23 at 03:36
  • Theoretically possible, but this is not the best solution to your problem. I can't provide perfect example, as I don't write java. You don't need an if statement for each card type. You could store values as pairs in an array and then lookup the correct value to return when the toString method is called. – ilsloaoycd Mar 05 '23 at 04:31
  • `String[] cards = [[Rank.SIX, "6"], etc]; letter = (/*lookup correct association from cards array using*/ PokerCard.this.getSuit())` – ilsloaoycd Mar 05 '23 at 04:40

2 Answers2

2

I propose modifying the enums – since an enum is essentially a class. Refer to Enum Types in Oracle's Java tutorials.

In the below code, I add a String member to both Rank and Suit and also override the toString method of each enum. I also added a getValue method that ensures that the Rank enum returns the points value of the Card. Refer to How can a Java enum start with 1?

package basetest;

public class Card {
    protected Rank rank;
    protected Suit suit;

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

    public static void main(String[] args) {
        System.out.println(new PokerCard(Rank.ACE, Suit.SPADES));
    }
}

class PokerCard extends Card {

    public PokerCard(Rank rank, Suit suit) {
        super(rank, suit);
    }

    public String toString() {
        return rank.toString() + suit.toString();
    }
}

enum Rank {
    TWO("2"),
    THREE("3"),
    FOUR("4"),
    FIVE("5"),
    SIX("6"),
    SEVEN("7"),
    EIGHT("8"),
    NINE("9"),
    TEN("10"),
    JACK("J"),
    QUEEN("Q"),
    KING("K"),
    ACE("A");

    private final String letter;

    private Rank(String letter) {
        this.letter = letter;
    }

    public int getValue() {
        return ordinal() + 2;
    }

    public String toString() {
        return letter;
    }
}

enum Suit {
    CLUBS("\u2663"),
    DIAMONDS("\u2666"),
    HEARTS("\u2665"),
    SPADES("\u2660");

    private final String symbol;

    private Suit(String symbol) {
        this.symbol = symbol;
    }

    public String toString() {
        return symbol;
    }
}

Here is the output I get when I run the above code:

A♠
Abra
  • 19,142
  • 7
  • 29
  • 41
0
String letter = "";
String symbol = "";
Rank rank = PokerCard.this.getRank();
Suit suit = PokerCard.this.getSuit();

if (rank.ordinal() >= 8 && rank.ordinal() <= 12) {
letter = Character.toString((char) ('A' + rank. Ordinal() - 8));
} else if (rank. Ordinal() >= 0 && rank.ordinal() <= 6) {
letter = Integer.toString(rank. Ordinal() + 2);
} else if (rank == Rank.TEN) {
letter = "10";
}

swrank. Ordinal{
case SPADES:
    symbol = "\u2660";
    break;
case HEARTS:
    symbol = "\u2665";
    break;
case DIAMONDS:
    symbol = "\u2666";
    break;
case CLUBS:
    symbol = "\u2663";
    break;
}

 return letter + symbol;

we use the ordinal value of the Rank enum to determine the letter value. We check if the ordinal value is between 8 and 12 (inclusive) for the face cards (A, K, Q, J), and between 0 and 6 (inclusive) for the number cards (2-9). For the rank value of 10, we use a separate if statement to assign the value "10" to the letter variable.

We also use a switch statement to determine the symbol value based on the Suit enum.enter code here