%----------------------------------------------------------------------- % DeckOfCards module % written by Phil Edmonds and Jeremy Sills, Jun 19,1996 % % This module stores and manipulates a deck of cards and the cards % themselves. % Data Structure: A deck is represented as an array of cards of type % cardType. A card is a record of two elements, the suit % ("S", "H", "D", or "C") and the value ("A", "1" - "10", "J", "Q", "K"). % cardType is exported for use in other functions. % % Imports: it requires the Graphics module % % Exports: % cardType - the type for a card % Init - initialize the deck into conventional order % Shuffle - shuffle the deck into random order % DealCard - deal the top card of the deck % DisplayCard - display the given card on the screen at the given % coordinates (NOTE: if the colours don't work on your % computer, feel free to change them) % % HOW TO USE IT % 0. DO NOT CHANGE THE CONTENTS OF THIS MODULE % 1. Save this module in a separate file called "deck.t" % 2. Import it (import DeckOfCards in "deck.t") in every module and % main program that requires it % 3. Call DeckOfCards.Init() to initialize the deck before using any other % operations. %------------------------------------------------------------------------ unit module DeckOfCards import Graphics in "graphics.t" export cardType, Init, Shuffle, DealCard, DisplayCard const DECK_SIZE := 52 type cardType : record suit : string (1) % "S", "H", "D", or "C" value : string (2) % "A", "2" - "10", "J", "Q", "K" end record var shuffled : boolean const initialDeck : array 1 .. DECK_SIZE of cardType := init ( init ("S", "A"), init ("S", "2"), init ("S", "3"), init ("S", "4"), init ("S", "5"), init ("S", "6"), init ("S", "7"), init ("S", "8"), init ("S", "9"), init ("S", "10"), init ("S", "J"), init ("S", "Q"), init ("S", "K"), init ("H", "A"), init ("H", "2"), init ("H", "3"), init ("H", "4"), init ("H", "5"), init ("H", "6"), init ("H", "7"), init ("H", "8"), init ("H", "9"), init ("H", "10"), init ("H", "J"), init ("H", "Q"), init ("H", "K"), init ("D", "A"), init ("D", "2"), init ("D", "3"), init ("D", "4"), init ("D", "5"), init ("D", "6"), init ("D", "7"), init ("D", "8"), init ("D", "9"), init ("D", "10"), init ("D", "J"), init ("D", "Q"), init ("D", "K"), init ("C", "A"), init ("C", "2"), init ("C", "3"), init ("C", "4"), init ("C", "5"), init ("C", "6"), init ("C", "7"), init ("C", "8"), init ("C", "9"), init ("C", "10"), init ("C", "J"), init ("C", "Q"), init ("C", "K")) var deck : array 1 .. DECK_SIZE of cardType var remaining : int %--------------------------------------- % PRIVATE SUBPROGRAMS % % print the value and symbol for a card % proc displayCardValue (card : cardType) if card.suit = "S" then put card.value, chr(6) .. elsif card.suit = "H" then put card.value, chr(3) .. elsif card.suit = "D" then put card.value, chr(4) .. elsif card.suit = "C" then put card.value, chr(5) .. end if end displayCardValue %--------------------------------------- % PUBLIC OPERATIONS %--------------------------------------- proc Init () deck := initialDeck remaining := DECK_SIZE shuffled := false end Init %--------------------------------------- % simply resets the randome number generator (actual shuffling % is never done) % proc Shuffle () randomize shuffled := true end Shuffle %--------------------------------------- % pulls a random card out of the deck and replaces it with the last % card in the deck % function DealCard () : cardType pre remaining > 0 var cardNumber : int var card : cardType if shuffled then % choose a random card only if they are shuffled randint (cardNumber, 1, remaining) else % otherwise, take them in order cardNumber := remaining end if card := deck (cardNumber) deck (cardNumber) := deck (remaining) remaining -= 1 result card end DealCard %---------------------------------------- % Displays a card at the given location. % The location is defined by (x,y)-coordinates (defined by the % Graphics module) of the top-left corner of the card. % % The scale determines the size of the card relative to the screen. const SCALE := 10 % scale factor, bigger value means smaller cards % Draw a card on the screen procedure DisplayCard (card : cardType, where : Graphics.coord) const cardwidth : int := maxx div SCALE const cardheight : int := cardwidth * 3 div 2 var foreCol : int var backCol : int := 14 % yellow colourback (backCol) % background of card drawfillbox (where.x, where.y, where.x + cardwidth, where.y - cardheight, backCol) % colour if card.suit = "S" or card.suit = "C" then foreCol := 7 % black else foreCol := 4 % red end if colour (foreCol) % outline drawbox (where.x, where.y, where.x + cardwidth, where.y - cardheight, foreCol) drawbox (where.x+1, where.y-1, where.x + cardwidth-1, where.y - cardheight+1, foreCol) % draw the symbol (magic numbers used for positioning !) locatexy (where.x + 10, where.y - 12) displayCardValue (card) locatexy (where.x + cardwidth - 26, where.y - cardheight + 16) displayCardValue (card) colour (7) % back to back colourback (0) % back to white end DisplayCard end DeckOfCards