Ch 16. Case Study A Card Game

1 / 40
About This Presentation
Title:

Ch 16. Case Study A Card Game

Description:

... Solitaire ... Use the preprocessor to ensure that including a header file more than once ... Figure 16.2 Layout for the Solitaire Game. Table piles. Shit piles ... – PowerPoint PPT presentation

Number of Views:117
Avg rating:3.0/5.0

less

Transcript and Presenter's Notes

Title: Ch 16. Case Study A Card Game


1
Ch 16. Case Study A Card Game
  • Timothy Budd
  • Oregon State University

2
Introduction
  • Simple card game Solitaire
  • Microsoft Foundation Classes (MFC) is used for
    the graphical interface

3
The Class Card
  • Use the preprocessor to ensure that including a
    header file more than once will not cause error.
  • Names defined within a class declaration must
    always be qualified when they are used outside
    the class.
  • include "card.h"CardColors Cardcolor ()
    if (suit() Heart suit()
    Diamond) return Red return Black

4
  • ifndef CARDH // ensure only included once
  • define CARDH
  • // Playing Card Abstraction
  • class Card public enum Suits Heart, Spade,
    Diamond, Club enum Colors Red, Black //
    constructors Card (Suits sv, int rv) s(sv),
    r(rv) fup false // return attributes int
    rank () return r Suits suit() return s
    bool faceup () return fup Colors color
    () // change attributes void flip () fup !
    fup private const Suits s const int
    r bool fup
  • endif

5
Data and View Classes
  • A view class provides the tools used to view data
    values held by another class.
  • To isolate the library-specific aspects of the
    card view, the actual display methods are
    declared as pure virtual methods.

6
  • ifndef CardViewH define CardViewH include
    "card.h"// CardView -- Display a graphical
    representation of a card
  • class CardView public static const int
    Width 40 static const int Height
    70 virtual void display (Card aCard, int,
    int) 0 virtual void halfDisplay (Card
    aCard, int, int) 0 endif

7
The Game
  • Klondike
  • The cards that are not part of the tableau are
    initially all in the deck.
  • Cards in the deck are face down, and are drawn
    one by one from the deck and placed, face up, on
    the discard pile.
  • Can be moved onto either a tableau pile or a
    foundation.
  • Cards are drawn from the deck until the pile is
    empty then the game is over if no further moves
    can be made.

8
Figure 16.2 Layout for the Solitaire Game
Shit piles
Discard pile
Deck
Table piles
9
Card Piles Inheritance in Action
  • Use inheritance to factor out common behavior
    from similar behavior in similar classes.
  • Top method
  • Card CardPiletop() throw (CardPilePopError)
    if (cards.empty()) throw new
    PopError() return cards.front()

10
  • class CardPile //CardPile -- representation
    of a Pile of Cards public CardPile (int
    xl, int yl) x(xl), y(yl) class PopError
    // exception on pop from empty stack
  • // drawing cards from pile bool empty ()
    return cards.empty() Card top () throw
    (PopError) Card pop () throw (PopError)
    Card result top() cards.pop_front() return
    result
  • // virtual methods that can be
    overridden virtual bool includes (int,
    int) virtual void addCard (Card ) virtual
    void display (CardView ) virtual bool canTake
    (Card ) virtual void select ()
    protected list cards const int x //
    location of display const int y ... //
    definitions of subclasses

11
Card Piles
  • To catch the potential stack underflow, the main
    program will at some point be surrounded by a try
    clause
  • Card CardPiletop() throw (CardPilePopError)
    if (cards.empty()) throw new
    PopError() return cards.front()

12
Card Piles
  • includes Determines if the coordinates given as
    arguments are contained within the boundaries of
    the pile.
  • canTake Tells whether a pile can take a specific
    card.
  • addCard Adds a card to the card list. It is
    redefined in the discard pile class to ensure
    that the card is face up.

13
Card Piles
  • display Displays the card deck. The default
    method merely displays the topmost card of the
    pile, but is overridden in the tableau class to
    display a column of cards. Only the topmostand
    bottommost face-up cards are displayed.
  • select Performs an action in response to a mouse
    click. It is invoked when the user selects a pile
    by clicking the mouse in the portion of the
    playing field covered by the pile.

14
Methods and Interface
15
The Default Card Pile
  • bool CardPileincludes (int tx, int ty) //
    default behavior is point within bounds of
    card? return x CardViewWidth y CardViewHeightvoid CardPileaddCard
    (Card aCard) // default behavior push card
    on front of stack cards.push_front(aCard)

16
The Default Card Pile
  • void CardPiledisplay (CardView cv) //
    default behavior print topmost card if
    (empty()) cv.display(0, x, y) else cv.displa
    y(top(), x, y)bool CardPilecanTake (Card
    ) // default behavior just say no return
    falsevoid CardPileselect () // default
    behavior do nothing

17
The Suit Piles
  • Class SuitPile represents the pile of cards at
    the top of the playing surface, the pile being
    built up in suit from ace to king.
  • The interface for this class
  • class SuitPile public CardPile
    public SuitPile (int xl, int yl) CardPile(xl,
    yl) bool canTake (Card )

18
The Suit Piles
  • bool SuitPilecanTake (Card aCard) // can
    take ace if empty if (empty()) return
    aCard-rank() 1
  • // otherwise must be next card in suit Card
    topCard top() return (aCard-suit()
    topCard-suit()) (aCard-rank() 1
    topCard-rank())

19
The Deck Pile
  • The DeckPile maintains the deck from which new
    cards are drawn.
  • class DeckPile public CardPile
    public DeckPile (int, int, Card ) void
    select ()

20
The Deck Pile
  • DeckPileDeckPile (int xl, int yl, Card orig
    ) CardPile(xl, yl) for (int i 0 i 52 i) Card theCard origi if
    (theCard-faceup()) theCard-flip() addCard(
    theCard)

21
The Deck Pile
  • include "Game.h" // include description of
    game manager extern Game gameManagervoid
    DeckPileselect () // move topmost card to
    discard stack if (empty()) return gameManager
    .discardPile()-addCard (top()) pop()

22
Figure 16.4 Definition of Application Class
  • include "CardPile.h"class Game // Game --
    Game Manager public // constructor,
    initialization and Destructor void init
    () Game () // access to the piles CardPile
    deckPile () return piles0 CardPile
    discardPile () return piles1 CardPile
    suitPile (int i) return piles2i CardPile
    tableau (int i) return piles6i //
    handling actions void repaint(CardView ) void
    mouseDown (int, int) private CardPile
    piles13

23
The Discard Pile
  • class DiscardPile public CardPile
    public DiscardPile (int xl, int yl)
    CardPile(xl, yl) void addCard (Card
    ) void select ()

24
The Discard Pile
  • void DiscardPileselect () if
    (empty()) return Card topCard top() for
    (int i 0 i (i)-canTake(topCard)) gameManager.suitPil
    e(i)-addCard(topCard) pop() return
    for (int i 0 i (gameManager.tableau(i)-canTake(topCard))
    gameManager.tableau(i)-addCard(topCard) pop(
    ) return

25
The Discard Pile
  • The C does not use the pseudo-code variable
    super, instead, uses qualified name.
  • void DiscardPileaddCard (Card aCard) if
    (! aCard-faceup()) aCard-flip() CardPilead
    dCard(aCard)

26
The Table Piles
  • The most complex of the subclasses of CardPile is
    that used to hold a tableau, or table pile.
  • The interface for this class redefines nearly all
    of the virtual methods defined in ClassPile
  • class TablePile public CardPile
    public TablePile (int xl, int yl, int
    p) bool canTake (Card aCard) bool includes
    (int tx, int ty) void display (CardView
    cv) void select ()

27
The Table Piles
  • TablePileTablePile(int xv, int yv, int p)
    CardPile(xv, yv) // copy right number of cards
    into deck for (int i 0 i aCard gameManager.deckPile()-top() if
    (aCard-faceup()) aCard-flip() addCard(aCar
    d) gameManager.deckPile()-pop() // flip
    topmost card top()-flip()

28
The Table Piles
  • bool TablePilecanTake (Card aCard) if
    (empty()) return aCard-rank() 12 Card
    topCard top() return (aCard-color() !
    topCard-color()) (aCard-rank()
    topCard-rank() - 1)
  • bool TablePileincludes (int tx, int
    ty) return x CardViewWidth y

29
  • void TablePileselect () // if empty, do
    nothing if (empty()) return // if face down,
    then flip Card topCard top() if (!
    topCard-faceup()) topCard-flip() return
    // else see if any pile can take card for
    (int i 0 i (i)-canTake(topCard)) gameManager.suitPile(i
    )-addCard(pop()) return for (int i
    0 i canTa
    ke(topCard)) gameManager.tableau(i)-addCard(
    pop()) return

30
The Table Piles
  • void TablePiledisplay (CardView cv) if
    (empty()) CardPiledisplay(cv) else int
    lx x int ly y listiterator
    cptr cards.end() listiterator
    front cards.begin() for (--cptr cptr !
    front --cptr) cv.halfDisplay(cptr, lx,
    ly) ly CardViewHeight/2 cv.display
    (front, lx, ly)

31
Playing the Polymorphic Game
  • Initialize card piles and shuffle deck
  • void Gameinit () // first, create a deck and
    randomize itint j 0for (int i 1 i i) originalDeckj new
    Card(CardDiamond, i) originalDeckj new
    Card(CardSpade, i) originalDeckj new
    Card(CardHeart, i) originalDeckj new
    Card(CardClub, i)randomInteger swapper //
    declare the random function objectrandom_shuffle(
    originalDeck, originalDeck52, swapper)
  • // continue in back

32
Playing the Polymorphic Game
  • Variable piles by all card piles used in drawing
    and other operations.
  • // then initialize each of the deck
    pilespiles0 new DeckPile(335, 5,
    originalDeck) piles1 new DiscardPile(268,
    5)j 2for (int i 0 i pilesj new SuitPile(15 60 i,
    5)for (int i 0 i new TablePile(5 55 i, 80, i1)

33
Playing the Polymorphic Game
  • class randomInteger public unsigned int
    operator () (unsigned int max) unsigned int
    rval rand() return rval max
  • GameGame() // free up all the old card
    values for (int i 0 i originalDecki

34
Playing the Polymorphic Game
  • void Gamerepaint(CardView cv) // simply
    repaint each of the card decks for (int i 0 i
    display(cv)
  • void GamemouseDown(int x, int y) for (int i
    0 i includes(x, y))
    pilesi-select() return

35
The Graphical User Interface
  • Isolate the graphical interface from the rest of
    a program.
  • class MFCardView public CardView
    public // constructor saves drawing
    context MFCardView (CPaintDC idc) dc(idc)
    // implement the interface void display
    (Card aCard, int, int) void halfDisplay (Card
    aCard, int, int)private CPaintDC dc //
    drawing context void paintCard(Card aCard,
    int, int)

36
The Graphical User Interface
  • void MFCardViewdisplay (Card aCard, int x,
    int y) dc.Rectangle (x, y, x Width, y
    Height) paintCard(aCard, x, y)void
    MFCardViewhalfDisplay (Card aCard, int x, int
    y) dc.Rectangle (x, y, x Width, y Height/
    2) paintCard (aCard, x, y)

37
  • void MFCardViewpaintCard (Card aCard, int x,
    int y) char buffer80if (aCard 0)
    strcpy(buffer,"mt") // mt
    empty dc.SetTextColor(RGB(0,255, 0)) //
    green dc.TextOut(x5, y5, buffer,
    strlen(buffer)) else if (aCard-faceup())
    char suitCard switch (aCard-suit())
    case CardHeart suitCard 'H'
    break switch (aCard-rank())
    case 1 sprintf(buffer,"A c", suitCard)
    break
  • default
  • sprintf(buffer, "d c", aCard-rank(),
    suitCard) break if (aCard-color()
    CardRed) dc.SetTextColor(RGB(255, 0, 0)) //
    red else dc.SetTextColor(RGB(0, 0, 0)) //
    black dc.TextOut(x5, y5, buffer,
    strlen(buffer)) else strcpy(buffer,
    "back") dc.SetTextColor(RGB(255, 255,
    0)) // yellow dc.TextOut(x5, y5,
    buffer, strlen(buffer))

38
The Graphical User Interface
  • class SolitareMainWindow public CFrameWnd
    public SolitareMainWindow() Create(NULL,
    "Solitare Game") afx_msg void
    OnPaint() afx_msg void OnLButtonDown (UINT
    flag, CPoint loc) DECLARE_MESSAGE_MAP()

39
The Graphical User Interface
  • void SolitareMainWindowOnPaint() CPaintDC
    dc(this) MFCardView cv(dc) gameManager.repain
    t(cv)void SolitareMainWindowOnLButtonDown(U
    INT flag, CPoint loc) try gameManager.mouse
    Down(loc.x, loc.y) catch (CardPilePopError
    e) // do nothing on error InvalidateRect(N
    ULL)

40
The Graphical User Interface
  • class SolitareApplication public CWinApp
    public BOOL InitInstance()SolitareAppli
    cation theAppBOOL SolitareApplicationInitInst
    ance() gameManager.init() m_pMainWnd new
    SolitareMainWindow() m_pMainWnd-ShowWindow
    (m_nCmdShow) m_pMainWnd-UpdateWindow()
Write a Comment
User Comments (0)