简体   繁体   中英

Modify a .java file to change constants to enums

I'm trying to finish this homework but it has been a little bit challenging so far, I'm quite new at java:

1). I have to create enums to replace the named constants for rank and suit in Card.java.

2).Make the changes necessary in Deck.java and DisplayDeck.java so they will work with the new Card.java.

This is my code so far for my three classes: Card.java, Deck.java and DisplayDeck.java

Original Card.java

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

// Kinds of suits
public final static int DIAMONDS = 1;
public final static int CLUBS    = 2;
public final static int HEARTS   = 3;
public final static int SPADES   = 4;

// Kinds of ranks
public final static int ACE   = 1;
public final static int DEUCE = 2;
public final static int THREE = 3;
public final static int FOUR  = 4;
public final static int FIVE  = 5;
public final static int SIX   = 6;
public final static int SEVEN = 7;
public final static int EIGHT = 8;
public final static int NINE  = 9;
public final static int TEN   = 10;
public final static int JACK  = 11;
public final static int QUEEN = 12;
public final static int KING  = 13;

public Card(int rank, int suit) {
    assert isValidRank(rank);
    assert isValidSuit(suit);
    this.rank = rank;
    this.suit = suit;
}

public int getSuit() {
    return suit;
}

public int getRank() {
    return rank;
}

public static boolean isValidRank(int rank) {
    return ACE <= rank && rank <= KING;
}

public static boolean isValidSuit(int suit) {
    return DIAMONDS <= suit && suit <= SPADES;
}

public static String rankToString(int rank) {
    switch (rank) {
    case ACE:
        return "Ace";
    case DEUCE:
        return "Deuce";
    case THREE:
        return "Three";
    case FOUR:
        return "Four";
    case FIVE:
        return "Five";
    case SIX:
        return "Six";
    case SEVEN:
        return "Seven";
    case EIGHT:
        return "Eight";
    case NINE:
        return "Nine";
    case TEN:
        return "Ten";
    case JACK:
        return "Jack";
    case QUEEN:
        return "Queen";
    case KING:
        return "King";
    default:
        //Handle an illegal argument.  There are generally two
        //ways to handle invalid arguments, throwing an exception
        //(see the section on Handling Exceptions) or return null
        return null;
    }    
}

public static String suitToString(int suit) {
    switch (suit) {
    case DIAMONDS:
        return "Diamonds";
    case CLUBS:
        return "Clubs";
    case HEARTS:
        return "Hearts";
    case SPADES:
        return "Spades";
    default:
        return null;
    }    
}

public static void main(String[] args) {

    // must run program with -ea flag (java -ea ..) to
    // use assert statements
    assert rankToString(ACE) == "Ace";
    assert rankToString(DEUCE) == "Deuce";
    assert rankToString(THREE) == "Three";
    assert rankToString(FOUR) == "Four";
    assert rankToString(FIVE) == "Five";
    assert rankToString(SIX) == "Six";
    assert rankToString(SEVEN) == "Seven";
    assert rankToString(EIGHT) == "Eight";
    assert rankToString(NINE) == "Nine";
    assert rankToString(TEN) == "Ten";
    assert rankToString(JACK) == "Jack";
    assert rankToString(QUEEN) == "Queen";
    assert rankToString(KING) == "King";

    assert suitToString(DIAMONDS) == "Diamonds";
    assert suitToString(CLUBS) == "Clubs";
    assert suitToString(HEARTS) == "Hearts";
    assert suitToString(SPADES) == "Spades";

}


}

My modified Card.java so far:

public class Card {

   public enum Suit
   {
      DIAMONDS(1), 
      CLUBS(2), 
      HEARTS(3), 
      SPADES(4);

      private final int suit;

      private Suit(int suit)
      {
         this.suit = suit;
      }

      public int getSuit()
      {
         return suit;
      }
   } //end enum suit

   public enum Rank
   {
      ACE(1),
      DEUCE(2),
      THREE(3),
      FOUR(4),
      FIVE(5),
      SIX(6),
      SEVEN(7),
      EIGHT(8),
      NINE(9),
      TEN(10),
      JACK(11),
      QUEEN(12),
      KING(13);

      private final int rank;

      private Rank(int rank)
      {
         this.rank = rank;
      }

      public int getRank()
      {
         return rank;
      }
   }//end enum rank


    public static String rankToString(Rank rank) {
        switch (rank) {
        case ACE:
            return "Ace";
        case DEUCE:
            return "Deuce";
        case THREE:
            return "Three";
        case FOUR:
            return "Four";
        case FIVE:
            return "Five";
        case SIX:
            return "Six";
        case SEVEN:
            return "Seven";
        case EIGHT:
            return "Eight";
        case NINE:
            return "Nine";
        case TEN:
            return "Ten";
        case JACK:
            return "Jack";
        case QUEEN:
            return "Queen";
        case KING:
            return "King";
        default:
            //Handle an illegal argument.  There are generally two
            //ways to handle invalid arguments, throwing an exception
            //(see the section on Handling Exceptions) or return null
            return null;
        }    
    }

    public static String suitToString(Suit suit) {
        switch (suit) {
        case DIAMONDS:
            return "Diamonds";
        case CLUBS:
            return "Clubs";
        case HEARTS:
            return "Hearts";
        case SPADES:
            return "Spades";
        default:
            return null;
        }    
    }

    }//end class

And this are the original Deck.java and DisplayDeck.java:

Original Deck.java

import java.util.*;

public class Deck {

    public static int numSuits = 4;
    public static int numRanks = 13;
    public static int numCards = numSuits * numRanks;

    private Card[][] cards;

    public Deck() {
        cards = new Card[numSuits][numRanks];
        for (int suit = Card.DIAMONDS; suit <= Card.SPADES; suit++) {
            for (int rank = Card.ACE; rank <= Card.KING; rank++) {
                cards[suit-1][rank-1] = new Card(rank, suit);
            }
        }
    }

    public Card getCard(int suit, int rank) {
        return cards[suit-1][rank-1];
    }
}

Modified Deck.java:

import java.util.*;

public class Deck {

    public static int numSuits = 4;
    public static int numRanks = 13;
    public static int numCards = numSuits * numRanks;

    private Card[][] cards;

    public Deck() {
        cards = new Card[numSuits][numRanks];
        for (Card.Suit suit : Card.Suit.values()) {
            for (Card.Rank rank : Card.Rank.values()) {
               // I dont know how to change this to work with Card.java
                cards[suit-1][rank-1] = new Card(rank, suit);
            }
        }
    }

    public Card getCard(int suit, int rank) {
        return cards[suit-1][rank-1];
    }
}

and DisplayDeck.java

import java.util.*;

public class DisplayDeck {
    public static void main(String[] args) {
        Deck deck = new Deck();
        /// how can i modify this code to work with both Card.java and Deck.java?
        for (int suit = Card.DIAMONDS; suit <= Card.SPADES; suit++) {
            for (int rank = Card.ACE; rank <= Card.KING; rank++) {
                Card card = deck.getCard(suit, rank);
                System.out.format("%s of %s%n",
                    card.rankToString(card.getRank()),
                    card.suitToString(card.getSuit()));
            }
        }
    }
}

I update my code on what I got so far.

Get rid of all your int representations for rank and suit. You can replace loops like this:

for (int suit = Card.DIAMONDS; suit <= Card.SPADES; suit++) { ...

with an enhanced for loop :

for (Suit suit : Card.Suit.values()) { ...

Replace mappings from int to String with EnumMap<Suit,String> or EnumMap<Rank,String> as appropriate. Methods for checking whether an int value is valid can be disposed of, as a non-null enum is guaranteed to be a legal value.

EDIT (in response to comment): You can define your deck as simply an array of Card objects:

public class Deck {
    private List<Card> cards;

    public Deck() {
        cards = new ArrayList<>();
        for (Card.Suit suit : Card.Suit.values()) {
            for (Card.Rank rank : Card.Rank.values()) {
                cards.add(new Card(suit, rank));
            }
        }
    }
}

With this, you can use the Collections utility class to trivially implement shuffling:

public class Deck {
    . . . // as above
    public void shuffle() {
        Collections.shuffle(cards);
    }
}

Since every enum type comes with a built-in compareTo() method that tells you the relative order of two enum values (of the same type). You can build on this to make the Card class implement Comparable<Card> . (This is left as an exercise for the reader :-)). Then you can trivially sort the deck back into its "brand new" order or even sort hands drawn randomly from the deck.

I see that you are currently retrieving a card by suit and rank. That's a weird way to access cards in a deck, especially since you just turn around and use the Card object to retrieve its suit and rank. But if you really need that kind of retrieval, you can expand the Deck definition to include internally an EnumMap<Suit, EnumMap<Rank, Card>> to allow you to quickly retrieve a card that way. (Yes, each card would then be stored in two distinct data structures inside the Deck object.) A better approach, in my view, is to add a method to retrieve a card by offset into the deck (and another method to tell you the deck size):

public class Deck {
    . . .
    public Card getCard(int index) {
        return cards.get(index);
    }
    public int cardCount() {
        return cards.size();
    }
}

To be fancier, you can define a method that returns an iterator over all the cards:

public class Deck {
    . . .
    public Iterator<Card> iterator() {
        return cards.iterator();
    }
}

Even fancier yet, you could declare Deck to implement Iterable<Card> . Then you can print the deck contents very simply:

Deck deck = new Deck();
for (Card card : deck) {
    // print the card
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM