Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Blackjack where
- import Cards
- import RunGame
- import Test.QuickCheck hiding (shuffle)
- -- A1 -------------------------
- hand2 = [Card (Numeric 2) Hearts, Card Jack Spades]
- sizeSteps = [ size hand2
- , size (Card (Numeric 2) Hearts : (Card Jack Spades : []))
- , 1 + size (Card Jack Spades : [])
- , 1 + 1 + size ([])
- , 1 + 1 + 0
- , 2
- ]
- --Example Cards/Hands
- a1crd = Card King Hearts
- a2crd = Card (Numeric 4) Diamonds
- a3crd = Card (Numeric 10) Spades
- a4crd = Card Ace Spades
- ahand = [a1crd,a2crd,a3crd]
- ahand2 = [a4crd]
- ahand3 = [a4crd,a4crd]
- -- A2 -------------------------
- --Display all cards in a given hand
- display :: Hand -> String
- display hand = unlines(
- map cardToString hand
- )
- --Returns a pretty format for a given card
- cardToString :: Card -> String
- cardToString (Card rank suit) = (rankToString rank)++" of "++(show suit)
- --Gets readable string of rank
- rankToString :: Rank -> String
- rankToString (Numeric n) = show n
- rankToString r = show r
- --PROPTEST: Makes sure the output is valid (elem = "does arg2 contain arg1?"
- prop_rankToString :: Rank -> Bool
- prop_rankToString rank = elem (rankToString rank)
- ["2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace"]
- -- A3 -------------------------
- --Gets the rank value as an Int
- rankValue :: Rank -> Int
- rankValue Ace = 11
- rankValue rank
- |elem rank [Jack,Queen,King] = 10
- |otherwise = read (rankToString rank)
- --PROPTEST: test all cases for rankValue
- prop_rankValue :: Rank -> Bool
- prop_rankValue rank
- |rank==(Numeric 2) = rankCalc == 2
- |rank==(Numeric 3) = rankCalc == 3
- |rank==(Numeric 4) = rankCalc == 4
- |rank==(Numeric 5) = rankCalc == 5
- |rank==(Numeric 6) = rankCalc == 6
- |rank==(Numeric 7) = rankCalc == 7
- |rank==(Numeric 8) = rankCalc == 8
- |rank==(Numeric 9) = rankCalc == 9
- |elem rank [Jack,Queen,King,(Numeric 10)] = rankCalc == 10
- |rank==Ace = rankCalc == 11
- where rankCalc = rankValue rank
- --Gets the value of a card, ignoring special cases for ace
- cardValue :: Card -> Int
- cardValue card = rankValue (rank card)
- isAce :: Card -> Bool
- isAce card = (rank card) == Ace
- numberOfAces :: [Card] -> Int
- numberOfAces cards = length (filter isAce cards)
- --Get the Int value of hand
- value :: Hand -> Int
- value cards
- |val <= 21 = val
- --if val exceeds 21, value of each ace is 1
- |otherwise = val - 10 * numberOfAces cards
- --val = value of all cards assuming ace is 11
- where val = sum (map cardValue cards)
- -- A4 -------------------------
- --Hand looses if value of cards > 21
- gameOver :: Hand -> Bool
- gameOver cards = value cards > 21
- --Gets which player has the winning hand
- winner :: Hand -> Hand -> Player
- winner guest bank
- |not (gameOver guest) && value guest > value bank = Guest
- |gameOver bank = Guest
- |otherwise = Bank
- -- B1 -------------------------
- --get all cards
- fullDeck=[(Card y x)|x<-[Hearts,Spades,Clubs,Diamonds],
- y<-Jack:Queen:King:Ace:[(Numeric n)|n<-[2..10]]]
- -- B2 -------------------------
- --draw a card from deck into hand
- draw :: Deck -> Hand -> (Deck,Hand)
- draw [] _ = error "draw: deck is empty"
- draw deck hand = (tail deck,(head deck):hand)
- -- B3 -------------------------
- playBank :: Deck -> Hand
- playBank [] = error "playBank: deck is empty"
- playBank deck = drawUntil16 deck []
- drawUntil16 :: Deck -> Hand -> Hand
- drawUntil16 deck hand
- |(value newHand) < 16 = (drawUntil16 restOfPile newHand)
- |otherwise = newHand
- where (restOfPile,newHand) = draw deck hand
- -- B4 -------------------------
- --shuffle the deck
- shuffle :: [Double] -> Deck -> Deck
- shuffle _ [] = []
- shuffle _ [a] = [a]
- shuffle srcRand deck = takenCard:(shuffle (tail srcRand) remainingDeck)
- where rand = head srcRand
- deckSize = (length deck)
- index = floor(rand*((fromIntegral deckSize)-1))
- (remainingDeck,takenCard) = yoink index deck
- --get arg1:th element from arg2 and arg2 with the arg1:th element removed
- yoink :: Int -> Deck -> (Deck,Card)
- yoink 0 (topcard:deck) = (deck,topcard)
- yoink index (topcard:deck) = (topcard:returnDeck,returnCard)
- where (returnDeck,returnCard) = yoink (index-1) deck
- -- B5 ----------------------------
- --PROPTEST: makes sure list has been shuffled
- -- if both the shuffled and unshuffled list contains the same cards
- -- AND that the list are the same size => is correcly shuffled
- --does deck contain card?
- belongsTo :: Card -> Deck -> Bool
- c `belongsTo` [] = False
- c `belongsTo` (c':cs) = c == c' || c `belongsTo` cs
- --PROPTEST: does the shuffled and the non-shuffled contain the same cards?
- -- & prop_size_shuffle
- prop_shuffle :: Card -> Deck -> Rand -> Bool
- prop_shuffle card deck (Rand randomlist) =
- card `belongsTo` deck == card `belongsTo` shuffle randomlist deck
- && prop_size_shuffle randomlist deck
- --PROPTEST: is the shuffled and the non-shuffled list the same size?
- prop_size_shuffle :: [Double] -> Deck -> Bool
- prop_size_shuffle randomlist deck =
- length (shuffle randomlist deck) == length deck
- -- B6 ----------------------------
- --implementation
- implementation = Interface
- {iFullDeck = fullDeck
- ,iValue = value
- ,iDisplay = display
- ,iGameOver = gameOver
- ,iWinner = winner
- ,iDraw = draw
- ,iPlayBank = playBank
- ,iShuffle = shuffle
- }
- main :: IO ()
- main = runGame implementation
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement