Saturday, July 25, 2015

[CC150v5] 8.1 Design a Generic Deck of Cards - Shuatiblog.com



[CC150v5] 8.1 Design a Generic Deck of Cards - Shuatiblog.com
Design a Generic Deck of Cards

在职刷题 + System Design + 面试准备的路上
ow to design Black Jack?
主题从player角度出发,core object有hand, board, deck, suit等,use cases有Initialization, Play, Checkout, Shuffle(喜欢考算法)。
https://tianrunhe.wordpress.com/2012/03/18/design-the-data-structure-of-a-deck-of-cards/
The structure is clear here: a deck contains four suits and a suit contains 13 card. Each card has a numerical value from 1 to 13. If you think about a card game, different games differ from ways of dealing cards and putting cards back in. So we can have a set of abstract methods inside the class ‘Deck’ to allow sub-class implements its own way of dealing.


enum Suit {
    HEART, DIAMOND, SPADES, CLUBS;
}

class Deck<T extends Card> {
    List<Card> deck;

    public void shuffle() {
    };
}

abstract class Card {
    boolean available;
    Suit suit;
    int num; //???

    public boolean isAvailable() {
        return available;
    };
}

class Hand<T extends Card> {
    List<Card> cards;

    public int score() {
        int score = 0;
        for (Card c : cards) {
            score += c.num;
        }
        return score;
    }

    public void addCard(T card) {
        cards.add(card);
    }
}

// Now use the above generic Data Structure to make a
// Blackjack Game
class Blackjack extends Hand<BlackJackCard> {
}

class BlackJackCard extends Card {
}

https://epicfei.wordpress.com/2013/08/10/7-1-design-the-data-structures-for-a-generic-deck-of-cards-explain-how-you-would-sub-class-it-to-implement-particular-card-games/
namespace SUIT
{
    enum Enum
    {
        SPADE,
        HEART,
        CLUB,
        DIAMOND
    };
};
class Card
{
private:
    SUIT::Enum s;
    int v;
     
public:
    virtual SUIT::Enum suit() const
    {
        return s;
    };
     
    virtual int val() const
    {
        return v;
    };
     
    Card(int val, SUIT::Enum suit):s(suit), v(val){};
};
/*
Just remember and practise the paradigm of inheritance
*/
class BlackJackCard : public Card
{
public:
    virtual int val()
    {
        int v = Card::val();
        if (v < 10) return v;
        return 10;
    }
     
    BlackJackCard(int val, SUIT::Enum suit):Card(val, suit){};
};
class player
{
private:
    int id;
    int bet;
    set<int> points;
    vector<BlackJackCard *> bjcs;
    bool addPoint(set<int>& points, BlackJackCard* card)
    {
        if (points.empty())
        {
            points.insert(card->val());
            if (card->val() == 1)
                points.insert(11);
        }
        else
        {
            /*
            set elements are ALWAYS CONST, they can't be modified once inserted.
            */
            set<int> tmp;
            for (set<int>::iterator it = points.begin(); it != points.end(); ++ it)
            {
                tmp.insert(*it + card->val());
                if (card->val() == 1)
                    tmp.insert(*it + 11);
            }
            points = tmp;
        }
    }
      
    void getPoints()
    {
        cout << "You All Possible Points : " << endl;
        for (set<int>::iterator it = points.begin(); it != points.end(); ++ it)
        {
            cout << *it << endl;
        }
    };
     
    int getMinPoints()
    {
        /*
        set is implemented by commonly BST, so eles are in order!!!
        learn to use lower_bound() and upper_bound()
         
        "they allow the direct iteration on subsets based on their order."
        which gives us another option to find min. preferable
        */
         
        //return *(points.lower_bound(0));
        return *(points.begin());
    };
     
    void printCards()
    {
        cout << "You Cards : " << endl;
        for (vector<BlackJackCard *>::iterator it = bjcs.begin(); it != bjcs.end(); ++ it)
        {
            cout << (*it)->val() << endl;
        }
         
    }
public:
    player(int i, int j):id(i),bet(j)
    {
        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));
        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));
        addPoint(points, bjcs[0]);
        addPoint(points, bjcs[1]);
    };
     
    void getAnotherCard()
    {
        for (set<int>::iterator it = points.begin(); it != points.end(); ++ it)
        {
            /*
            predefined strategy for the player
            */
            if (*it <= 21 && 21 - *it <= 4)
            {
                printCards();
                getPoints();
                cout << "Stand" << endl;
                exit(1);
            }
        }
        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));
        addPoint(points, bjcs.back());
        if (getMinPoints() > 21)
        {
            printCards();
            getPoints();
            cout << "Busted" << endl;
            exit(2);
        }
    };
};
https://xmruibi.gitbooks.io/interview-preparation-notes/content/OOD/DesignExamples/DeckOfCard.html
  1. enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。
  2. 定义 enum 类型时候,如果是简单类型 (No more constructor),那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。
  3. 由于 enum 类型的值实际上是通过运行期构造出对象来表示的,所以在 cluster 环境下,每个虚拟机都会构造出一个同义的枚举对象。因而在做比较操作时候就需要注意,如果直接通过使用等号 ( ‘ == ’ ) 操作符,这些看似一样的枚举值一定不相等,因为这不是同一个对象实例。
class Card {
    // Define the Suit by Enum type
    public enum Suit {
        CLUBS(1), SPADE(2), HEART(3), DIAMOND(4);
        int value;
        private Suit(int val) {
            this.value = val;
        }
    }

    // Card has suit and value, only two kind of data need to store
    int val;
    Suit suit;


    public Card(int value, Suit suit) {
        this.val = value;
        this.suit = suit;
    }

    public int getVal(){
        return this.val;
    }

    public Suit getSuit(){
        return this.suit;
    }
}

BlackJack

  • Face cards (kings, queens, and jacks) are counted as ten points.
  • Ace can be counted as 1 point or 11 points
  • Other cards with value less than ten should be counted as what it values.
class BlackJack extends Card{
    public BlackJack(int val, Suit suit) {
        super(val, suit);
    }

    @Override
    public int getVal(){
        int value = super.getVal();
        if(value < 10)
            return value;
        else if(value == 1)
            return 11;
        return 10;
    }

    public boolean isAce(){
        return super.getVal() == 1;
    }
}
http://fenghaolw.blogspot.com/2014/01/cc150-chapter-8-object-oriented-design.html?view=sidebar
http://math.hws.edu/eck/cs124/javanotes6/c5/s4.html

http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/10/deck-of-cards.html

       public class DeckOfCards
       {
          public static final int NCARDS = 52;
        
          private Card[] deckOfCards;         // Contains all 52 cards
          private int currentCard;            // deal THIS card in deck           
        
          public DeckOfCards( )    // Constructor
          {
         deckOfCards = new Card[ NCARDS ];
        
         int i = 0;
        
         for ( int suit = Card.SPADE; suit <= Card.DIAMOND; suit++ )
            for ( int rank = 1; rank <= 13; rank++ )
         deckOfCards[i++] = new Card(suit, rank);
        
         currentCard = 0;
          }
        
          /* ---------------------------------
         shuffle(n): shuffle the deck
         --------------------------------- */
          public void shuffle(int n)
          {
         int i, j, k;
        
         for ( k = 0; k < n; k++ )
         {
             i = (int) ( NCARDS * Math.random() );  // Pick 2 random cards
             j = (int) ( NCARDS * Math.random() );  // in the deck
        
             /* ---------------------------------
         swap these randomly picked cards
         --------------------------------- */
             Card tmp = deckOfCards[i];
             deckOfCards[i] = deckOfCards[j];
             deckOfCards[j] = tmp;;
         }
        
         currentCard = 0;   // Reset current card to deal
          }
          /* -------------------------------------------
         deal(): deal deckOfCards[currentCard] out
         ------------------------------------------- */
          public Card deal()
          {
         if ( currentCard < NCARDS )
         {
            return ( deckOfCards[ currentCard++ ] );
         }
         else
         {
            System.out.println("Out of cards error");
            return ( null );  // Error;
         }
          }
        
          public String toString()
          {
         String s = "";
         int k;
        
         k = 0;
         for ( int i = 0; i < 4; i++ )
         {
            for ( int j = 1; j <= 13; j++ )
         s += (deckOfCards[k++] + " ");
        
            s += "\n";
         }
         return ( s );
          }
       }
    
http://math.hws.edu/javanotes/c5/s4.html
Card, Hand, Deck

https://www.nowtoshare.com/zh/Article/Index/70566


Read full article from [CC150v5] 8.1 Design a Generic Deck of Cards - Shuatiblog.com

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts