2

我有一个类卡,其他卡(纸牌游戏)继承自它。卡片花色和数字存储在这样的枚举中

public static enum Suit {
    CLUBS, DIAMONDS, HEARTS, SPADES
};

public static enum Rank {
    DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
};

我的第一个问题是如何改变卡牌的顺序。在从类 Card 继承的每个单独的类(Card Game)中,因为不同的纸牌游戏对不同的纸牌赋予不同的重要性级别。

我的第二个问题是使用 Comparable Interface。

所以我有一张这样的班级卡片:

public  class Card implements Comparable<Card> {

public Suit suit;
public Rank rank;


public Card(Rank ranker, Suit suiter) {

    rank = ranker;
    suit = suiter;
}


//Other Methods for rank and suit here. 


@Override
public int compareTo(Card o) {

    int rankCom = rank.compareTo(o.rank);
    return rankCom != 0 ? rankCom : suit.compareTo(o.suit);
}

}

我最近刚被介绍到类似的接口,我不完全确定我的实现是正确的。当我想使用 collections.sort(cards_saver) 整理我的卡片时,问题就出现了。card_saver 是我存放卡片的地方。所有这些工作正常。collections.shuffle(cards_saver) 也可以正常工作。我在做 collections.sort 时遇到的问题是:

Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (List<Card>). The inferred type Card is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>

我会提出我所有的额外代码......只是这太长了。如果我没有很好地解释问题,请发表评论-我会尽力解释。

提前致谢

4

3 回答 3

4

我的第一个问题是如何改变卡牌的顺序。在从类 Card 继承的每个单独的类(Card Game)中,因为不同的纸牌游戏对不同的纸牌赋予不同的重要性级别。

你有两种方法:

  1. 由于您继承自Card,因此您可以重写compareTo以相应地表现。
  2. 可以看一下Comparator界面,方便根据上下文重新定义对象的比较规则。

至于你得到的那个错误,它真的没有意义。问题可能出在其他地方。

于 2012-05-09T00:38:59.827 回答
2

我认为对于语法错误,您必须将 Card 声明为(是的,我同意这是看起来很奇怪的语法)

public  class Card implements Comparable<? extends Card>

然后你可以在子类中覆盖。但是,我发现这常常让人感到困惑。另外,从设计的角度来看,桥牌、红心、扑克中的牌都是一样的。可以说,没有 BridgeCard 和 PokerCard 子类。有一张卡片,但有一个不同的游戏,游戏决定了你如何比较卡片。

为了更加清晰,并且,如果您相信我的设计论点,为了更好的设计,不要使用 Comparable,而是实现一堆Comparator。例如:

static Comparator<Card> LOWBALL_POKER_COMPARATOR = new Comparator<Card>() {

      @Override
      public int compare(Card o1, Card o2) {
         // Ace is LOW is lowball poker, other cards as usual
      }

};

static Comparator<Card> PINOCLE_COMPARATOR = new Comparator<Card>() {
      @Override
      public int compare(Card o1, Card o2) {
         // I haven't played pinocle in so long I forget the rules...
      }
};

请注意,Enums 可以实现 Comparator,因此您可以在 Enums 中拥有所有这些 Comparator。您正在玩的 CardGame 的特定实例/子类会在启动时为该游戏选择正确的枚举/比较器,然后离开……

于 2012-05-09T00:53:19.240 回答
0

你的代码对我来说很好。我刚刚向 Card 添加了一个 toString 方法:

import java.util.*;

class Card implements Comparable<Card> {

    static enum Suit {
        CLUBS, DIAMONDS, HEARTS, SPADES
    }

    static enum Rank {
        DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
    }

    public Suit suit;
    public Rank rank;

    public Card (Rank ranker, Suit suiter) {
        rank = ranker;
        suit = suiter;
    }

    @Override
    public int compareTo (Card o) {
        int rankCom = rank.compareTo(o.rank);
        return rankCom != 0 ? rankCom : suit.compareTo(o.suit);
    }

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

并且 - 只是为了我的方便,将 Rank 和 Suit 作为内部枚举添加到 Card,但只是为了将所有内容放在一个文件中 - 它不应该影响排序。这是测试:

public class CardTest
{
    public static void main (String args[])
    {
        List <Card> lc = new ArrayList <Card> ();
        lc.add (new Card (Card.Rank.SIX, Card.Suit.CLUBS)); 
        lc.add (new Card (Card.Rank.TEN, Card.Suit.CLUBS)); 
        lc.add (new Card (Card.Rank.SIX, Card.Suit.HEARTS)); 
        lc.add (new Card (Card.Rank.ACE, Card.Suit.HEARTS)); 

        System.out.println (lc);
        Collections.sort (lc);
        System.out.println (lc);
    }
}

输出:

[CLUBS  SIX, CLUBS  TEN, HEARTS SIX, HEARTS ACE]
[CLUBS  SIX, HEARTS SIX, CLUBS  TEN, HEARTS ACE]

您的代码将是:

        lc.add (new Card (Rank.TEN, Suit.CLUBS)); 

反而。

如果您有不同的卡片顺序,创建一个新的卡片类可能是最简单的事情。排除扑克、桥牌、罗米、二十一点等之间的相似之处可能是过度设计。

于 2012-05-09T00:50:33.557 回答