Skat Engine und AI auf Haskell Basis
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

150 строки
3.5KB

  1. {-# LANGUAGE MultiParamTypeClasses #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. module Skat.Card where
  5. import Data.List
  6. import Data.Aeson
  7. import System.Random (newStdGen)
  8. import Control.DeepSeq
  9. import Skat.Utils
  10. class Countable a b where
  11. count :: a -> b
  12. data Type = Seven
  13. | Eight
  14. | Nine
  15. | Queen
  16. | King
  17. | Ten
  18. | Ace
  19. | Jack
  20. deriving (Eq, Ord, Show, Enum, Read)
  21. instance Countable Type Int where
  22. count Ace = 11
  23. count Ten = 10
  24. count King = 4
  25. count Queen = 3
  26. count Jack = 2
  27. count _ = 0
  28. data Colour = Diamonds
  29. | Hearts
  30. | Spades
  31. | Clubs
  32. deriving (Eq, Ord, Show, Enum, Read)
  33. data Card = Card Type Colour
  34. deriving (Eq, Show, Ord)
  35. instance ToJSON Card where
  36. toJSON (Card t c) =
  37. object ["type" .= show t, "colour" .= show c]
  38. instance FromJSON Card where
  39. parseJSON = withObject "Card" $ \v -> do
  40. t <- v .: "type"
  41. c <- v .: "colour"
  42. return $ Card (read t) (read c)
  43. getColour :: Card -> Colour
  44. getColour (Card _ c) = c
  45. getID :: Card -> Int
  46. getID (Card t _) = case t of
  47. Seven -> 0
  48. Eight -> 0
  49. Nine -> 0
  50. Queen -> 2
  51. King -> 4
  52. Ten -> 8
  53. Ace -> 16
  54. Jack -> 32
  55. instance Countable Card Int where
  56. count (Card t _) = count t
  57. instance Countable [Card] Int where
  58. count = sum . map count
  59. instance NFData Card where
  60. rnf (Card t c) = t `seq` c `seq` ()
  61. equals :: Colour -> Maybe Colour -> Bool
  62. equals col (Just x) = col == x
  63. equals col Nothing = True
  64. isTrump :: Colour -> Card -> Bool
  65. isTrump trumpCol (Card tp col)
  66. | tp == Jack = True
  67. | otherwise = col == trumpCol
  68. effectiveColour :: Colour -> Card -> Colour
  69. effectiveColour trumpCol card@(Card _ col) =
  70. if trump then trumpCol else col
  71. where trump = isTrump trumpCol card
  72. isAllowed :: Colour -> Maybe Colour -> [Card] -> Card -> Bool
  73. isAllowed trumpCol turnCol cs card =
  74. if col `equals` turnCol
  75. then True
  76. else not $ any (\ca -> effectiveColour trumpCol ca `equals` turnCol && ca /= card) cs
  77. where col = effectiveColour trumpCol card
  78. compareCards :: Colour
  79. -> Maybe Colour
  80. -> Card
  81. -> Card
  82. -> Ordering
  83. compareCards _ _ (Card Jack col1) (Card Jack col2) = compare col1 col2
  84. compareCards trumpCol turnCol c1@(Card tp1 col1) c2@(Card tp2 col2) =
  85. case (trp1, trp2) of
  86. (True, True) -> compare tp1 tp2
  87. (False, False) -> case compare (col1 `equals` turnCol)
  88. (col2 `equals` turnCol) of
  89. EQ -> compare tp1 tp2
  90. v -> v
  91. _ -> compare trp1 trp2
  92. where trp1 = isTrump trumpCol c1
  93. trp2 = isTrump trumpCol c2
  94. sortCards :: Colour -> Maybe Colour -> [Card] -> [Card]
  95. sortCards trumpCol turnCol cs = sortBy (compareCards trumpCol turnCol) cs
  96. highestCard :: Colour -> Maybe Colour -> [Card] -> Card
  97. highestCard trumpCol turnCol cs = maximumBy (compareCards trumpCol turnCol) cs
  98. shuffleCards :: IO [Card]
  99. shuffleCards = do
  100. gen <- newStdGen
  101. return $ shuffle gen allCards
  102. -- TESTING VARS
  103. c1 :: Card
  104. c1 = Card Jack Spades
  105. c2 :: Card
  106. c2 = Card Ace Diamonds
  107. c3 :: Card
  108. c3 = Card Queen Diamonds
  109. c4 :: Card
  110. c4 = Card Queen Hearts
  111. c5 :: Card
  112. c5 = Card Jack Clubs
  113. h1 :: [Card]
  114. h1 = [c1,c2,c3,c4,c5]
  115. allCards :: [Card]
  116. allCards = [ Card t c | t <- tps, c <- cols ]
  117. where tps = [Seven .. Jack]
  118. cols = [Diamonds .. Clubs]