【问题标题】:Highest value card found in deck在甲板上找到的最高价值的卡
【发布时间】:2016-04-14 23:29:04
【问题描述】:

在一个 Java 程序中,我试图返回一副牌中价值最高的卡片。

钻石是价值最低的西装。然后是梅花,然后是红桃,最后是黑桃的价值最高。如您所见,我有一段代码在 findLargest 方法中简单地写着largest =。我不知道用这个方法的其余部分去哪里。

public class Card {

    private int number;
    private String suit;

    /*
     * Randomly creates a card numbered 1 to 13 (ace = 1!) and labelled "Hearts","Clubs","Diamonds" or "Spades".
     */
    public Card() {
        double randomNum = Math.random() * 4.0;
        if (randomNum < 1.0)
            suit = "Hearts";
        else if (randomNum < 2.0)
            suit = "Clubs";
        else if (randomNum < 3.0)
            suit = "Diamonds";
        else
            suit = "Spades";
        randomNum = Math.random() * 13.0;
        number = (int) randomNum + 1;
    }
    /*
     * Creates a card with specified number and suit
     */
    public Card (int n, String s) {
        number = n;
        suit = s;
    }

    public int getNumber() {
        return number;
    }

    public String getSuit () {
        return suit;
    }


    public String cardString() {
        // System.out.println(number + " " + suit);
        String stringNum = "";
        switch (number) {
        case 1:
                stringNum = "Ace";
                break;
            case 2:
                stringNum = "Two";
                break;
            case 3:
                stringNum = "Three";
                break;
            case 4:
                stringNum = "Four";
                break;
            case 5:
                stringNum = "Five";
                break;
            case 6:
                stringNum = "Six";
                break;
            case 7:
                stringNum = "Seven";
                break;
            case 8:
                stringNum = "Eight";
                break;
            case 9:
                stringNum = "Nine";
                break;
            case 10:
                stringNum = "Ten";
                break;
            case 11:
                stringNum = "Jack";
                break;
            case 12:
                stringNum = "Queen";
                break;
            case 13:
                stringNum = "King";
                break;
            default:
                System.out.println("Error in Card - illegal number");
            }
            return stringNum + " of " + suit;
        }
    }


public class PackCards {

    private ArrayList<Card> pack;

    /*
     * Create a random pack of size n
     */
    public PackCards(int n) {
        Card c;
        pack = new ArrayList<Card>();
        for (int i = 1; i <= n; i++) {
            c = new Card();
            pack.add(c);
        }
    }

    public void printPack() {
        for (Card c : pack) {
            System.out.println(c.cardString());
        }
    }


    public Card findLargest() {

        if ( c.getNumber() > largest.getNumber() ) 
            largest = 
                else if (c.getNumber() == largest.getNumber() ) {
                    if (largest.getSuit().equals("Diamonds"))
                largest = largest.getNumber; 
                }
                else if (c.getNumber() == largest.getNumber() ) {
                    if (largest.getSuit().equals("Clubs"))
                        largest = largest.getNumber;
                }
                else if (c.getNumber() == largest.getNumber() ) {
                    if (largest.getSuit().equals("Hearts"))
                        largest = largest.getNumber;
                }

                else return;


    }

【问题讨论】:

    标签: java


    【解决方案1】:

    我会简化代码,以便更容易看到您想要实现的目标。在 Java 8 中你可以做到。

    import java.util.Random;
    
    public class Card  {
        enum Suit {
            // must be in increasing order.
            Spades, Diamonds, Clubs, Hearts
        }
    
        static final Suit[] SUITS = Suit.values();
    
        private final int number;
        private final Suit suit;
    
        /*
         * Randomly creates a card numbered 1 to 13 (ace = 1!) and labelled "Hearts","Clubs","Diamonds" or "Spades".
         */
        public Card() {
            Random rand = new Random();
            suit = SUITS[rand.nextInt(SUITS.length)];
            number = rand.nextInt(13) + 1;
        }
    
        public int getNumber() {
            return number;
        }
    
        public Suit getSuit() {
            return suit;
        }
    
        static final String[] NAMES = ",Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King".split(",");
    
        public String cardString() {
            assert number > 1 && number < NAMES.length;
            return NAMES[number] + " of " + suit;
        }
    }
    

    这也简化了你的包

    public class PackOfCards {
        private final List<Card> cards;
    
        public PackOfCards(int size) {
            // note duplicates are possible, i.e. ever card could be the same.
            cards = IntStream.range(0, size)
                    .mapToObj(n -> new Card())
                    .collect(Collectors.toList());
        }
    
        public Card findLargest() {
            return cards.stream().max(Comparator.comparing(Card::getNumber)
                    .thenComparing(Card::getSuit)).get();
        }
    }
    

    【讨论】:

    • 感谢您的回复!我唯一的问题是需要更改类 PackCards 作为该项目的一部分,卡类已经为我编写。你能给我一些关于如何做到这一点的线索吗?
    • @FraserSteel 为西装写一个Comparator 并在上面的代码中使用它。
    【解决方案2】:

    您可以更改 Card 类以实现 Comparable 接口。例如:

    public class Card implements Comparable<Card> {
        ....// your current implementation for the Card class
    
        public int compareTo(Card another) {
            if (this.suit.compareTo(another.suit) == 0) {
                if (this.number < another.number) {
                    return -1;
                } else if (this.number > another.number) {
                    return 1;
                } else {
                    return 0;
                }
            } else if (this.suit.compareTo("Diamonds") == 0) {
                // Diamonds being the lowest valued suit ...
                return -1;
            } else if (this.suit.compareTo("Clubs") == 0) {
                // ... then Clubs ...
                if (another.suit.compareTo("Diamonds") == 0) {
                    return 1;
                } else {
                    return -1;
                }
            } else if (this.suit.compareTo("Hearts") == 0) {
                // ... Hearts ...
                if (another.suit.compareTo("Spades") == 0) {
                    return -1;
                } else {
                    return 1;
                }
            } else {
                // ... and largest values, Spades
                return 1;
            }
        }
    }
    

    然后,您可以修改 PackCards 以将卡片存储在有序集合中。例如:

    pack = new TreeSet<Card>();
    

    这样一来,包中的卡牌是有序的,最后一张是最大的。

    如果您想保持卡片添加到列表中的顺序,您可以通过以下方式获取最大的卡片:

    largest = Collections.max(pack);
    

    【讨论】:

    • 感谢您的回复!我唯一的问题是需要更改类 PackCards 作为该项目的一部分,卡类已经为我编写。你能给我一些关于如何做到这一点的线索吗?
    • 如果您无法更改 Card 类,也许您可​​以使用子类扩展该类,并仅使用该新子类。子类可以实现 Comparable 接口。
    【解决方案3】:

    对于此类工作,您希望利用 Java 的面向对象特性并为 FaceValueSuit 使用枚举。枚举按您列出它们的顺序“自然排序”,使您的构造和字符串输出更容易:

    public class Card implements Comparable<Card> {
    
      private FaceValue faceValue;
      private Suit suit;
    
      /*
       * Randomly creates a card numbered 1 to 13 (ace = 1!)
       * labelled "Hearts","Clubs","Diamonds" or "Spades".
       */
      public Card() {
        int randomSuit = (int)Math.floor(Math.random() * 4.0); //Number between 0 and 3, inclusive.
        int randomFace = (int)Math.floor(Math.random() * 13.0);
        this.faceValue = FaceValue.values()[randomFace];
        this.suit = Suit.values()[randomSuit];
      }
    
      public Card(FaceValue value, Suit suit) {
        this.faceValue = value;
        this.suit = suit;
      }
    
      // TODO Constructor that convert ints and strings to proper enums and call previous constructor
    
      public int compareTo(Card that) {
        int comparison = this.suit.compareTo(that.suit);
        return (comparison != 0) ? comparison : this.faceValue.compareTo(that.faceValue);
      }
    
      public String cardString() {
        return this.faceValue + " of " + this.suit;
      }
    
      public enum Suit{
        DIAMOND, CLUB, HEART, SPADE;
      }
    
      public enum FaceValue {
         ACE, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;
      }  // You can modify this enum if you need to give back something more specific as the string value.
    }
    

    那么对于您的Deck,您也可以通过选择一个好的数据结构来简化事情,在本例中为TreeSet,它将自动使用您为卡片提供的compareTo 函数来对卡片进行排序。 :

    public class Deck {
      //By using a Set we eliminate duplicates
      private final TreeSet<Card> cards;
    
      public Deck(int size) {
        cards = Sets.newTreeSet(IntStream.range(0, size)
                                         .mapToObj(n -> new Card())
                                         .collect(Collectors.toList());
      }
    
      //Because this is a TreeSet, finding the largest value is trivial.
      public Card findLargest() {
        return this.cards.last();
      }
    }
    

    如果您需要为您的牌组中的卡片提供特殊字符串,您可以对FaceValue 进行以下修改:

    public enum FaceValue {
      ACE {
        public String toString() { return "Ace"; }
      }, 
      ONE {
        public String toString() { return "One"; }
      }, 
      ...  // Fill out the rest in the same manner.
      KING {
        public String toString() { return "King"; }
      }
    }
    

    请记住,在面向对象编程中,第一条规则是对象应该知道如何表现。因此,如果您发现自己正在编写一个 switch 语句,那么您很可能可以将行为推迟到对象本身。在这种情况下,您需要创建分配给给定卡片的子对象(FaceValueSuit 枚举)。卡片询问这些子部件的顺序,以及它们应如何响应toString 请求。

    【讨论】:

      猜你喜欢
      • 2016-06-28
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 2017-09-29
      • 2019-06-07
      • 2011-06-16
      相关资源
      最近更新 更多