Assigning int value to string

前提是你 提交于 2019-12-12 18:25:08

问题


I'm designing a Black Jack program. My issue is that, I use a switch case to generate a random card. But when it comes time to compare the value of the cards....lets say if(pCard1 + pCard2 > 21) it's not allowing me to compare them because they are strings. However, they need to be strings because I have to be able to assign String "Queen" but I also need "Queen" to have an int value of 10. I'm not sure how to go about this.

Here's what I have so far. I'm not including my entire code because its a couple hundreds of lines long. Only including the blackjack section.

System.out.println("---------------------Black Jack--------------------------");
    System.out.println("Welcome to BlackJack!");
    System.out.println("Available balance is $"+balance);
    System.out.print("How much would you like to bet on this hand?: ");
    int bet = input.nextInt();
    balance -= bet;
    System.out.println("You just bet $"+bet+"......Dealing cards!");
    System.out.println("----------------------------------------------------------");

    String pCard1 = dealCard();
    String pCard2 = dealCard();

    System.out.println("Your hand is a "+pCard1+" and "+pCard2);
    System.out.print("Would you like to Hit or Stand? :");
    String hOs = input.next();

    if(hOs.equals("Hit")) {
        String pCard3 = dealCard();
        if(pCard1 + pCard2 + pCard3);
    }
    }
}
public static String dealCard() {
    int value = (int)(Math.random() * 13);
    String returnString = "";
    switch ( value ) {
        case 1:   returnString = "Ace"; break;
        case 2:   returnString = "2"; break;
        case 3:   returnString = "3"; break;
        case 4:   returnString = "4"; break;
        case 5:   returnString = "5"; break;
        case 6:   returnString = "6"; break;
        case 7:   returnString = "7"; break;
        case 8:   returnString = "8"; break;
        case 9:   returnString = "9"; break;
        case 10:  returnString = "10"; break;
        case 11:  returnString = "Jack"; break;
        case 12:  returnString = "Queen"; break;
        case 13:  returnString = "King"; break;
    }
    return returnString;
  }
}    

回答1:


I think enums are the best way to address this kind of issue.

If we define enums for Suit and Pips like so

enum Suit {
    Hearts, Diamonds, Clubs, Spades;
}

enum Pips {
    Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King;
}

And if we define a class Card:

class Card {
    Suit suit;
    Pips pips;

    public Card(Suit suit, Pips pips) {
        this.suit = suit;
        this.pips = pips;
    }

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

Card uses toString() to convert Suit and Pips to strings, while a zero-index numeric value can be obtained using ordinal():

    Card card = new Card(Suit.Spades, Pips.Ace);
    System.out.println("Card: " + card);
    System.out.println("Numeric suit: " + card.suit.ordinal());
    System.out.println("Numeric pips: " + card.pips.ordinal());

This simple implementation has a couple of limitations. First, the name of the suit or pips can only ever be a string version of the enum name. What if you wanted all your enums in UPPER CASE as is good style? The second problem is that the ordinal is always zero-indexed. What if you need some other id system for the pips?

In this case we add maps to each enum to hold these mappings. Unfortunately we can't use inheritance to share code between enums and so the boiler plate gets a little wordy.

enum Suit {
    HEARTS(1, "Hearts"), //
    DIAMONDS(2, "Diamonds"), //
    CLUBS(3, "Clubs"), //
    SPADES(4, "Spades");

    private static Map<String, Suit> nameToEnum = new HashMap<>();
    private static Map<Integer, Suit> idToEnum = new HashMap<>();

    static {
        for (Suit suit : Suit.values()) {
            nameToEnum.put(suit.getName(), suit);
            idToEnum.put(suit.getId(), suit);
        }
    }

    private int id;
    private String name;

    private Suit(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public static Suit fromName(String name) {
        return nameToEnum.get(name);
    }

    public static Suit fromId(int id) {
        return idToEnum.get(id);
    }
}

enum Pips {
    ACE(1, 1, "Ace"), //
    TWO(2, 2, "Two"), //
    THREE(3, 3, "Three"), //
    FOUR(4, 4, "Four"), //
    FIVE(5, 5, "Five"), //
    SIX(6, 6, "Six"), //
    SEVEN(7, 7, "Seven"), //
    EIGHT(8, 8, "Eight"), //
    NINE(9, 9, "Nine"), //
    TEN(10, 10, "Ten"), //
    JACK(11, 10, "Jack"), //
    QUEEN(12, 10, "Queen"), //
    KING(13, 10, "King");

    private static Map<String, Pips> nameToEnum = new HashMap<>();
    private static Map<Integer, Pips> idToEnum = new HashMap<>();

    static {
        for (Pips pips : Pips.values()) {
            nameToEnum.put(pips.getName(), pips);
            idToEnum.put(pips.getId(), pips);
        }
    }

    private int id;
    private int value;
    private String name;

    private Pips(int id, int value, String name) {
        this.id = id;
        this.value = value;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public int getValue() {
        return value;
    }

    public String getName() {
        return name;
    }

    public static Pips fromName(String name) {
        return nameToEnum.get(name);
    }

    public static Pips fromId(int id) {
        return idToEnum.get(id);
    }

}

With these new enums, we modify Card.toString() to use the new getName() methods:

    return pips.getName() + " of " + suit.getName();

And now when we work with Cards we can use any of the ID or the name or the enum and convert freely between them:

    Card card = new Card(Suit.SPADES, Pips.ACE);
    System.out.println("Card: " + card);
    System.out.println("Numeric suit: " + card.suit.getId());
    System.out.println("Numeric pips: " + card.pips.getId());
    System.out.println("Suit by ID: " + Suit.fromId(3).getName());
    System.out.println("Pips by Name: " + Pips.fromName("Ace").getName());
    System.out.println("Pips value by Name: " + Pips.fromName("King").getValue());



回答2:


I recommend using Enum, so you can compare the cards easily. your desired enum class would be:

public enum Cards {
    ace (1),
    two (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 code;

    Cards(int code){
        this.code = code;
    }
    public Integer value(){
        return code;
    }

    public static Cards getRelatedEnum(Integer code){
        if(code == null)
            return null;

        switch (code){
            case 1: return ace;
            case 2: return two;
            case 3: return three;
            case 4: return four;
            case 5: return five;
            case 6: return six;
            case 7: return seven;
            case 8: return eight;
            case 9: return nine;
            case 10: return ten;
            case 11: return jack;
            case 12: return queen;
            case 13: return king;
            default: return null;
        }
    }

    public static String toString(Cards card){
        if(card == null)
            return "";
        switch (card){
            case ace: return "ace";
            case two: return "2";
            case three: return "3";
            case four: return "4";
            case five: return "5";
            case six: return "6";
            case seven: return "7";
            case eight: return "8";
            case nine: return "9";
            case ten: return "10";
            case jack: return "jack";
            case queen: return "queen";
            case king: return "king";
            default: return null;
        }
    }

}

then you can change your dealCard() method to:

public static Cards dealCard() {
    int value = (int)(Math.random() * 13);
    return Cards.getRelatedEnum(value);
}  

to compare card values use something like:

public static void main(String[] args){
    System.out.println("---------------------Black Jack--------------------------");
    System.out.println("Welcome to BlackJack!");
    System.out.println("Available balance is $"+balance);
    System.out.print("How much would you like to bet on this hand?: ");
    int bet = input.nextInt();
    balance -= bet;
    System.out.println("You just bet $"+bet+"......Dealing cards!");
    System.out.println("-------------------------------------------");

    Cards pCard1 = dealCard();
    Cards pCard2 = dealCard();

    System.out.println("Your hand is a "+pCard1.toString() +" and "+pCard2.toSring());
    System.out.print("Would you like to Hit or Stand? :");
    String hOs = input.next();

    if(hOs.equals("Hit")) {
        Cards pCard3 = dealCard();
        if(pCard1.value() + pCard2.value() > pCard3.value());
    }
}



回答3:


Ten, Jack, Queen, and King are all different ranks but share the same value of 10. Since they all have the same value, you need more than just a card's value to determine it's rank. Admittedly, you could represent Jack's value as 11, Queen as 12, etc and then code your methods to recognize any value over 10 as 10, but this is bad coding practice.

Instead, you should encode both the rank and the value in each card (Additionally, you may want to include suit; although that may not matter for blackjack).

Rather than represent your card as a string, I recommend making a Card class that has a String rank and an integer value. Additionally, this would be a good opportunity to explore enums in Java as others have commented.



来源:https://stackoverflow.com/questions/49714583/assigning-int-value-to-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!