Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Blackjack where
  2.  
  3. import Cards
  4. import RunGame
  5. import Test.QuickCheck hiding (shuffle)
  6.  
  7. -- A1 -------------------------
  8. hand2 = [Card (Numeric 2) Hearts, Card Jack Spades]
  9. sizeSteps = [ size hand2
  10.   , size (Card (Numeric 2) Hearts : (Card Jack Spades : []))
  11.   , 1 + size (Card Jack Spades : [])
  12.   , 1 + 1 + size ([])
  13.   , 1 + 1 + 0
  14.   , 2
  15.  ]
  16.  
  17. --Example Cards/Hands
  18. a1crd = Card King Hearts
  19. a2crd = Card (Numeric 4) Diamonds
  20. a3crd = Card (Numeric 10) Spades
  21. a4crd = Card Ace Spades
  22. ahand = [a1crd,a2crd,a3crd]
  23. ahand2 = [a4crd]
  24. ahand3 = [a4crd,a4crd]
  25.  
  26.  
  27. -- A2 -------------------------
  28. --Display all cards in a given hand
  29. display :: Hand -> String
  30. display hand = unlines(
  31.   map cardToString hand
  32.  )
  33.  
  34. --Returns a pretty format for a given card
  35. cardToString :: Card -> String
  36. cardToString (Card rank suit) = (rankToString rank)++" of "++(show suit)
  37.  
  38. --Gets readable string of rank
  39. rankToString :: Rank -> String
  40. rankToString (Numeric n) = show n
  41. rankToString r = show r
  42.  
  43. --PROPTEST: Makes sure the output is valid (elem = "does arg2 contain arg1?"
  44. prop_rankToString :: Rank -> Bool
  45. prop_rankToString rank = elem (rankToString rank)
  46.  ["2","3","4","5","6","7","8","9","10","Jack","Queen","King","Ace"]
  47.  
  48.  
  49. -- A3 -------------------------
  50. --Gets the rank value as an Int
  51. rankValue :: Rank -> Int
  52. rankValue Ace = 11
  53. rankValue rank
  54.  |elem rank [Jack,Queen,King] = 10
  55.  |otherwise = read (rankToString rank)
  56.  
  57. --PROPTEST: test all cases for rankValue
  58. prop_rankValue :: Rank -> Bool
  59. prop_rankValue rank
  60.  |rank==(Numeric 2) = rankCalc == 2
  61.  |rank==(Numeric 3) = rankCalc == 3
  62.  |rank==(Numeric 4) = rankCalc == 4
  63.  |rank==(Numeric 5) = rankCalc == 5
  64.  |rank==(Numeric 6) = rankCalc == 6
  65.  |rank==(Numeric 7) = rankCalc == 7
  66.  |rank==(Numeric 8) = rankCalc == 8
  67.  |rank==(Numeric 9) = rankCalc == 9
  68.  |elem rank [Jack,Queen,King,(Numeric 10)] = rankCalc == 10
  69.  |rank==Ace = rankCalc == 11
  70.  where rankCalc = rankValue rank
  71.  
  72. --Gets the value of a card, ignoring special cases for ace
  73. cardValue :: Card -> Int
  74. cardValue card = rankValue (rank card)
  75.  
  76. isAce :: Card -> Bool
  77. isAce card = (rank card) == Ace
  78.  
  79. numberOfAces :: [Card] -> Int
  80. numberOfAces cards = length (filter isAce cards)
  81.  
  82. --Get the Int value of hand
  83. value :: Hand -> Int
  84. value cards
  85.  |val <= 21 = val
  86.  --if val exceeds 21, value of each ace is 1
  87.  |otherwise = val - 10 * numberOfAces cards
  88.      --val = value of all cards assuming ace is 11
  89.  where val = sum (map cardValue cards)
  90.  
  91.  
  92. -- A4 -------------------------
  93. --Hand looses if value of cards > 21
  94. gameOver :: Hand -> Bool
  95. gameOver cards = value cards > 21
  96.  
  97. --Gets which player has the winning hand
  98. winner :: Hand -> Hand -> Player
  99. winner guest bank
  100.  |not (gameOver guest) && value guest > value bank = Guest
  101.  |gameOver bank = Guest
  102.  |otherwise = Bank
  103.  
  104. -- B1 -------------------------
  105. --get all cards
  106. fullDeck=[(Card y x)|x<-[Hearts,Spades,Clubs,Diamonds],
  107.           y<-Jack:Queen:King:Ace:[(Numeric n)|n<-[2..10]]]
  108.  
  109.  
  110. -- B2 -------------------------
  111. --draw a card from deck into hand
  112. draw :: Deck -> Hand -> (Deck,Hand)
  113. draw [] _ = error "draw: deck is empty"
  114. draw deck hand = (tail deck,(head deck):hand)
  115.  
  116. -- B3 -------------------------
  117. playBank :: Deck -> Hand
  118. playBank [] = error "playBank: deck is empty"
  119. playBank deck = drawUntil16 deck []
  120.  
  121. drawUntil16 :: Deck -> Hand -> Hand
  122. drawUntil16 deck hand
  123.  |(value newHand) < 16  = (drawUntil16 restOfPile newHand)
  124.  |otherwise = newHand
  125.  where (restOfPile,newHand) = draw deck hand
  126.  
  127. -- B4 -------------------------
  128. --shuffle the deck
  129.  
  130. shuffle :: [Double] -> Deck -> Deck
  131. shuffle _ [] = []
  132. shuffle _ [a] = [a]
  133. shuffle srcRand deck = takenCard:(shuffle (tail srcRand) remainingDeck)
  134.  where rand = head srcRand
  135.        deckSize = (length deck)
  136.        index = floor(rand*((fromIntegral deckSize)-1))
  137.        (remainingDeck,takenCard) = yoink index deck
  138.  
  139. --get arg1:th element from arg2 and arg2 with the arg1:th element removed
  140. yoink :: Int -> Deck -> (Deck,Card)
  141. yoink 0 (topcard:deck) = (deck,topcard)
  142. yoink index (topcard:deck) = (topcard:returnDeck,returnCard)
  143.  where (returnDeck,returnCard) = yoink (index-1) deck
  144.  
  145.  
  146. -- B5 ----------------------------
  147. --PROPTEST: makes sure list has been shuffled
  148. -- if both the shuffled and unshuffled list contains the same cards
  149. -- AND that the list are the same size => is correcly shuffled
  150.  
  151. --does deck contain card?
  152. belongsTo :: Card -> Deck -> Bool
  153. c `belongsTo` []      = False
  154. c `belongsTo` (c':cs) = c == c' || c `belongsTo` cs
  155.  
  156. --PROPTEST: does the shuffled and the non-shuffled contain the same cards?
  157. --          & prop_size_shuffle
  158. prop_shuffle :: Card -> Deck -> Rand -> Bool
  159. prop_shuffle card deck (Rand randomlist) =
  160.  card `belongsTo` deck == card `belongsTo` shuffle randomlist deck
  161.  && prop_size_shuffle randomlist deck
  162.  
  163. --PROPTEST: is the shuffled and the non-shuffled list the same size?
  164. prop_size_shuffle :: [Double] -> Deck -> Bool
  165. prop_size_shuffle randomlist deck =
  166.  length (shuffle randomlist deck) == length deck
  167.  
  168. -- B6 ----------------------------
  169. --implementation
  170. implementation = Interface
  171.   {iFullDeck = fullDeck
  172.   ,iValue    = value
  173.   ,iDisplay  = display
  174.   ,iGameOver = gameOver
  175.   ,iWinner   = winner
  176.   ,iDraw     = draw
  177.   ,iPlayBank = playBank
  178.   ,iShuffle  = shuffle
  179.   }
  180.  
  181. main :: IO ()
  182. main = runGame implementation
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement