[CC150v5] 8.1 Design a Generic Deck of Cards - Shuatiblog.com
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.
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/
https://xmruibi.gitbooks.io/interview-preparation-notes/content/OOD/DesignExamples/DeckOfCard.html
http://math.hws.edu/eck/cs124/javanotes6/c5/s4.html
http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/10/deck-of-cards.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
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); } };};- enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。
- 定义 enum 类型时候,如果是简单类型 (No more constructor),那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。
- 由于 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=sidebarhttp://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 );
}
}
|
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

