2016-09-15 65 views
-1

是的,这是一个家庭作业,但我想学习如何编写更多面向对象的代码。我需要为每个卡有不同的值,所以当我运行compareTo方法时,我不仅能够比较卡的数字值,还能比较卡的套装排名。举个例子,ACE的值为0,13,26和39.我创建了一个卡片类,当我通过deckOfCard类运行它时,所有东西都在工作。我只是想更好地写入卡片方法,所以没有太多的代码。我知道必须有一个更好的方法来做这件事,而不是在嵌套的if/else语句上有一堆。这是我的卡片类。任何帮助将不胜感激。设置值到一副扑克牌中的不同卡片

public class Card{ 
private int number; 
private String suit; 
private char value; 
private final int MAX_CARDS = 52; 

/** 
method: Card(int number) 
Purpose: (Constructor)Creates a new Card based on the number 

@1param number of card to assign suit and value 
@return 
*/ 
public Card(int number) 
{ 
    //Assigning Values to the card 
    if(number == 0 || number == 13 || number == 26 || number == 39) 
    { 
    value = 'A'; 
    } 
    else if(number == 10 || number == 23 || number == 36 || number == 49) 
    { 
    value = 'J'; 
    } 
    else if(number == 11 || number == 24 || number == 37 || number == 50) 
    { 
    value = 'Q'; 
    } 
    else if(number == 12 || number == 25 || number == 38 || number == 51) 
    { 
    value = 'K'; 
    } 
    else if(number == 1 || number == 14 || number == 27 || number == 40) 
    { 
    value = '2'; 
    } 
    else if(number == 2 || number == 15 || number == 28 || number == 41) 
    { 
    value = '3'; 
    } 
    else if(number == 3 || number == 16 || number == 29 || number == 42) 
    { 
    value = '4'; 
    } 
    else if(number == 4 || number == 17 || number == 30 || number == 43) 
    { 
    value = '5'; 
    } 
    else if(number == 5 || number == 18 || number == 31 || number == 44) 
    { 
    value = '6'; 
    } 
    else if(number == 6|| number == 19 || number == 32 || number == 45) 
    { 
    value = '7'; 
    } 
    else if(number == 7 || number == 20 || number == 33 || number == 46) 
    { 
    value = '8'; 
    } 
    else if(number == 8 || number == 21 || number == 34 || number == 47) 
    { 
    value = '9'; 
    } 
    else if(number == 9 || number == 22 || number == 35 || number == 48) 
    { 
    value = 'T'; 
    } 
    //Assigning Suit 
    // Hearts > Spades > Diamonds > Clubs 
    if(number>=0 && number<=12) 
    { 
    suit = "Clubs"; 
    } 
    else if(number>=13 && number<=25) 
    { 
    suit = "Diamonds"; 
    } 
    else if(number>=26 && number<=38) 
    { 
    suit = "Spades"; 
    } 
    else 
    { 
    suit = "Hearts"; 
    } 

} 
/** 
method: getValue() 
Purpose: (Getter)returns value 

@param 
@return value 
*/ 
public char getValue() 
{ 

    return value; 
} 
/** 
method: getNumber() 
Purpose: (Getter)returns number 

@param 
@return number 
*/ 
public int getNumber() 
{ 
    return number; 
}     

/** 
method: getSuit(int number) 
Purpose: returns suit based on number value 

@param number of card to assign suit 
@return suit 
*/ 
public String getSuit() 
{    

    return suit;    
} 
public String toString() 
{ 
    return value + " of " + suit; 
} 
/** 
method: compareTo(Card aCard) 
Purpose: Return an integer comparison of two cards 

@param aCard reference to the card being compared 
@return integer difference between two cards 
*/ 
public int compareTo(Card aCard) 
{ 
    int cardSuitValueA = -1; 
    int cardSuitValueB = -1; 
    int cardsPerSuit = 13; 
    if(this.getNumber() % cardsPerSuit - aCard.getNumber() % cardsPerSuit !=  0) 
    { 
    return this.getNumber() % cardsPerSuit - aCard.getNumber() % cardsPerSuit; 
    } 
    else 
    { 
    if (this.getSuit().equalsIgnoreCase("Hearts")) 
    { 
     cardSuitValueA = 3; 
    } 
    else if (this.getSuit().equalsIgnoreCase("Spades")) 
    { 
     cardSuitValueA = 2; 
    } 
    else if (this.getSuit().equalsIgnoreCase("Diamonds")) 
    { 
     cardSuitValueA = 1; 
    }   
    else if (this.getSuit().equalsIgnoreCase("Clubs")) 
    { 
     cardSuitValueA = 0; 
    } 
    if (aCard.getSuit().equalsIgnoreCase("Hearts")) 
    { 
     cardSuitValueB = 3; 
    } 
    else if (aCard.getSuit().equalsIgnoreCase("Spades")) 
    { 
     cardSuitValueB = 2; 
    } 
    else if (aCard.getSuit().equalsIgnoreCase("Diamonds")) 
    { 
     cardSuitValueB = 1; 
    }   
    else if (aCard.getSuit().equalsIgnoreCase("Clubs")) 
    { 
     cardSuitValueB = 0; 
    } 
    return cardSuitValueA - cardSuitValueB; 
    }   
} 

} 
+0

一件事,你一定要考虑的是与'enum'更换'String'。使用字符串变量进行逻辑(比较)通常是一个坏主意,因为它使代码变得混乱,而且效率也很低。更不用说错别字很难找到,因为它们仍然是正确的字符串 – UnholySheep

+1

由于您要求一般性建议,所以此问题将更适合http://codereview.stackexchange.com/ –

+0

我完全同意后阅读关于枚举的一些文档,我发现它比编码更容易和更清晰。我不能用这个项目做到这一点,并试图找出更简单的方法。 –

回答

0

也许这样的事情(我也只排名,而不是西装,但你明白了吧,你可以做西服相同或让它像你现在所拥有的):

private static Map<Integer, Character> map = new HashMap<Integer, Character>(); 
static{ 
    map.put(0, 'A'); 
    map.put(10, 'J'); 
    map.put(11, 'Q'); 
    map.put(12, 'K'); 
    ... 
} 

public Card(int number){ 
    value = map.get(number%13); 
} 

这样你的compareTo方法可以大大减少。如果您对地图不熟悉,您也可以将这些值放在普通数组中,而不是地图(索引0将为'A',索引10将为'J'等)。

0

你可以使用模运算符,使其更简单

public Card(int number) 
{ 
    //Assigning Values to the card 
    if((number % 13) == 0) 
    { 
    value = 'A'; 
    } 
    else if((number % 13) == 10) 
    { 
    value = 'J'; 
    } 
    else if((number % 13) == 11) 
    { 
    value = 'Q'; 
    } 
    else if((number % 13) == 12) 
    { 
    value = 'K'; 
    } 
    else if((number % 13) == 1) 
    { 
    value = '2'; 
    } 

或保持一个数组,并使用(number % 13)索引到它。 (number % 13)是余当你把number由13

public Card(int number) 
{ 
    //Assigning Values to the card 
    char[] ranks = {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' }; 
    value = ranks[number % 13]; 

    char[] suits = {'S', 'H', 'D', 'C' }; 
    suit = suits[number/13]; 

} 
+0

我喜欢这一点,但我仍然需要相同的if/else语句正确 –

+0

难道你不能用if-else替换switch-case吗? (这也意味着你只执行一次计算) – UnholySheep

+0

我曾经跟别人谈过这样做,但他有52个开关语句,我虽然很荒谬。 –

1

可以使用enum秒。这例如,显著压缩你compareTo

public class Card implements Comparable<Card> { 
    private final int number; 
    private final Rank rank; 
    private final Suit suit; 

    private static final int CARDS_PER_SUIT = 13; 

    private Card(Suit suit, Rank rank, int number) { 
     this.suit = suit; 
     this.rank = rank; 
     this.number = number; 
    } 

    public Card(Suit suit, Rank rank) { 
     this(suit, rank, suit.ordinal() * CARDS_PER_SUIT + rank.ordinal()); 
    } 

    public Card(int number) { 
     this(Suit.ofNumber(number), Rank.ofNumber(number), number); 
    } 

    //... Boilerplate methods 

    private static final Comparator<Card> defaultComparator 
     = Comparator.comparing(Card::getRank).thenComparing(Card::getSuit); 

    @Override 
    public int compareTo(Card aCard) { 
     return defaultComparator.compare(this, aCard); 
    } 

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

     public static Suit ofNumber(int number) { 
      return values()[number/CARDS_PER_SUIT]; 
     } 
    } 

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

     public static Rank ofNumber(int number) { 
      return values()[number % CARDS_PER_SUIT]; 
     } 
    } 

} 
+0

好的,所以我明白用'enum'你可以创建你自己的特殊变量类型。从你提供的内容中我可以看出你是如何做到的。现在我的问题在于你的'suit.ordinal()'声明的'oridinal'部分是什么。我以前没有见过。 –

+0

没关系,我刚刚在oracle网站上找到了关于ordinal()意味着什么的答案。 –

+0

@ChadHoye它是由编译器生成的方法。这是记录[这里](https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html#ordinal--)。它基本上返回枚举值的索引。 –