[CareerCup] 8.1 Implement Blackjack 實現21點紙牌

Grandyang發表於2015-09-04

 

8.1 Design the data structures for a generic deck of cards. Explain how you would subclass the data structures to implement blackjack.

 

這道題讓我們設計一個21點紙牌遊戲的資料結構,用物件導向的思想來設計。那麼既然21點是一種特定的紙牌遊戲,它可以是從普通紙牌的基礎上派生出來的。所以我們先實現最基本的紙牌類Card,裡面包括值和花色,還有一些基本的判斷或標記可用性的函式。然後就是基本的牌堆類Deck,可以用來加入牌,洗牌,發牌以及算剩餘牌數。還需要一個當前手牌類Hand,可以計算當前分數,可以加牌等。然後就是它們的派生類21點紙牌類BlackJackCard,包括計算值,計算最大最小值,判斷是不是Ace等等,然後就是21點手牌類BlackjackHand,計算當前得分,判斷是否爆了,是否是21點等等。以下程式碼為書上程式碼,有些函式體寫實現,所以暫時無法用具體執行。

 

// C++ defination
enum Suit {Club, Diamond, Heart, Spade};

template<class T>
class Deck {
public:
    void setDeckOfCards(vector<T> deckOfCards) {}; // ... 
    void shuffle() {}; // ... 
    int remainingCards() {
        return _cards.size() - _dealtIndex;
    }
    vector<T> dealHead(int number) {}; // ... 
    T dealCard() {}; // ... 
private:
    vector<T> _cards;
    int _dealtIndex = 0;
};

class Card {
public:
    Card(int c, Suit s): _faceValue(c), _suit(s) {};
    virtual int value() = 0;
    Suit suit() { return _suit; };
    bool isAvailable() { return _available; };
    void markUnavailable() { _available = false; };
    void markAvailable() { _available = true; };
protected:
    int _faceValue;
    Suit _suit;
private:
    bool _available = true;
};

template<class T>
class Hand {
public:
    int score() {
        int score = 0;
        for (T card : cards) {
            score += card.value();
        }
        return score;
    }
    void addCard(T card) {
        cards.add(card);
    }
protected:
    vector<T> cards;
};

class BlackJackCard: public Card {
public:
    BlackJackCard(int c, Suit s): Card(c,s) {};
    int value() {
        if (isAce()) return 1;
        else if (_faceValue >= 11 && _faceValue <= 13) return 10;
        else return _faceValue;
    }
    int minValue() {
        if (isAce()) return 1;
        else return value();
    }
    int maxValue() {
        if (isAce()) return 11;
        else return value();
    }
    bool isAce() {
        return _faceValue == 1;
    }
    bool isFaceCard() {
        return _faceValue >= 11 && _faceValue <= 13;
    }
};

class BlackjackHand: public Hand<BlackJackCard> {
public:
    int score() {
        vector<int> scores = possibleScores();
        int maxUnder = INT_MIN, minOver = INT_MAX;
        for (auto a : scores) {
            if (a > 21 && a < minOver) {
                minOver = a;
            } else if (a <= 21 && a > maxUnder) {
                maxUnder = a;
            }
        }
        return maxUnder == INT_MIN ? minOver : maxUnder;
    }
    bool busted() { return score() > 21; };
    bool is21() { return score() == 21; };
    bool isBlackJack() {}; // ...
private:
    vector<int> possibleScores() {}; // ...
};

 

相關文章