【问题标题】:Java Blackjack OOPJava 二十一点 OOP
【发布时间】:2016-11-09 19:01:09
【问题描述】:

我正在尝试通过创建二十一点游戏来发挥 Java 中 OOP 的最大潜力。到目前为止,我有 5 个 java 文件。

西装.java

enum Suit {

/*
 * Initialize suit values
 */
    HEARTS,
    SPADES,
    CLUBS,
    DIAMONDS;
}

Rank.java

enum Rank {

    /*
     * Initialize rank and card value
     */

    TWO(2),
    THREE(3), 
    FOUR(4), 
    FIVE(5), 
    SIX(6),
    SEVEN(7), 
    EIGHT(8), 
    NINE(9), 
    TEN(10), 
    JACK(10), 
    QUEEN(10),
    KING(10), 
    ACE(11);


    // Hold card value
    private int cardValue;

    /*
     * Constructor set card value
     * @param cardValue value of card
     */
    private Rank(int cardValue) {
        this.cardValue = cardValue;
    }

    /*
     * This method obtains the card value
     * @return This returns the value of card
     */
    public int getCardValue() {
        return cardValue;
    }
}

Card.java

public class Card {

    private Suit suit;
    private Rank rank;


    public Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank getCardValue() {
        return rank;
    }

    public Suit getSuitValue() {
        return suit;
    }
}

deck.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;


public class Deck {

    private ArrayList deck;

    public Deck() {

        this.deck = new ArrayList();

        for(Suit suit : Suit.values()) {
            for(Rank rank: Rank.values()) {
                Card card = new Card(rank, suit);
                this.deck.add(card);
            }
        }

        Collections.shuffle(deck);
    }

    public ArrayList getDeck() {
        return deck;
    }
}

Game.java

import java.util.ArrayList;
import java.util.Iterator;

public class Game {

    public static void main(String[] args) {

        Deck deck = new Deck();

        for(int i=0; i<deck.getDeck().size(); i++) {

            System.out.println( ((Card)   deck.getDeck().get(i)).getCardValue() + " of " 
            + ((Card) deck.getDeck().get(i)).getSuitValue() );
        }
    }
}

到目前为止,我的设计有意义吗?另外,我如何调用 (Rank.java) -> int getCardValue() 而不是 (Card.java) -> Rank getCardValue()?我需要做一些多态性吗?延长?我想要 int 值而不是 text 值。

谢谢!

【问题讨论】:

  • 这可能不是本网站的合适问题。话虽如此,您将如何处理 ACE 等级 1 和 11 的潜在双重价值?
  • 是的,这个问题确实更好的地方是codereview.SE.com
  • 至于获得排名,只需使用getRank() 并在返回的对象上调用getValue()....或者您为这些方法提供的任何名称。
  • 使用泛型:ArrayList&lt;Card&gt; 在你的班级Deck,而不是raw type ArrayList

标签: java oop enums blackjack


【解决方案1】:

要回答您的直接问题,您需要做的就是简单地链接方法:

Card myCard = new Card(Rank.TWO, Suit.HEARTS);
int value = myCard.getCardValue().getCardValue();

第一个getCardValue() 调用返回一个Rank 对象,而下一个getCardValue() 得到的是rank 的值。但这让我很困惑,两个具有相同名称的方法返回不同的类型。我自己,我会将 Card 的 getCardValue() 重命名为更直接和合乎逻辑的 getRank() 并将 Rank 的 getCardValue() 重命名为更简单的 getValue()。然后代码看起来更合乎逻辑:

int value = myCard.getRank().getValue();

至于你的另一个问题,“设计好吗”,这对于这个网站来说太宽泛了,但我认为你使用继承很好,你不想过度使用继承并坚持组合正如你正在做的那样。我还要说你需要考虑 ACE 有两个可能的值,1 和 11。

例如,可能是这样的:

public enum Rank {

    TWO(2, 0, false), 
    THREE(3, 0, false), 
    FOUR(4, 0, false), 
    FIVE(5, 0, false), 
    SIX(6, 0, false), 
    SEVEN(7, 0, false), 
    EIGHT(8, 0, false), 
    NINE(9, 0, false), 
    TEN(10, 0, false), 
    JACK(10, 0, false), 
    QUEEN(10, 0, false), 
    KING(10, 0, false), 
    ACE(11, 1, true);

    private int value;
    private int value2;
    private boolean twoValues;

    private Rank(int value, int value2, boolean twoValues) {
        this.value = value;
        this.value2 = value2;
        this.twoValues = twoValues;
    }

    public int getValue() {
        return value;
    }

    public int getValue2() {
        // TODO: consider throwing a custom exception if twoValues is false
        return value2;
    }

    public boolean hasTwoValues() {
        return twoValues;
    }
}

【讨论】:

  • 谢谢。我也有两次 getCardValue() 。我只是将 Rank 版本更改为 getRank()。
【解决方案2】:

只是提出一些替代方案:我可能会以不同的方式模拟排名的价值。由于ace 并没有真正的价值。 Hand 有一个值,但即使它实际上也有一个“最佳值”,可能会将 ace 计为 11 或 1。

所以我可能会删除排名的价值。并介绍一个Hand

public class Hand {
    private Hand(Collection<Card> cards) {
        ...
    }

    private int calculateBestValue() {
        ...
    }
}

我也不会公开价值计算。 Hand 可以“呈现”自己,因此它也可以说明您是否具有“软”值。

我也认为Deck 不应该有getDeck() 方法。这违反了封装。相反,它应该是一个名为:nextCard() 的方法。这会给你从牌组顶部的下一张牌。它可能还需要一个isEmpty() 方法,它返回牌组是否有牌。

【讨论】:

    猜你喜欢
    • 2012-06-29
    • 2014-10-27
    • 2012-10-17
    • 2017-04-05
    • 2012-04-25
    • 2013-10-07
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多