Skat Engine und AI auf Haskell Basis
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

109 lignes
3.1KB

  1. {-# LANGUAGE MultiParamTypeClasses #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. module Pile where
  4. import Data.List
  5. import Card
  6. import Utils
  7. import Control.Exception
  8. data Team = Team | Single
  9. deriving (Show, Eq, Ord, Enum)
  10. data CardS p = CardS { getCard :: Card
  11. , getPile :: p }
  12. deriving (Show, Eq)
  13. instance Countable (CardS p) Int where
  14. count = count . getCard
  15. data Hand = Hand1 | Hand2 | Hand3
  16. deriving (Show, Eq, Ord)
  17. next :: Hand -> Hand
  18. next Hand1 = Hand2
  19. next Hand2 = Hand3
  20. next Hand3 = Hand1
  21. prev :: Hand -> Hand
  22. prev Hand1 = Hand3
  23. prev Hand2 = Hand1
  24. prev Hand3 = Hand2
  25. data Played = Table Hand
  26. | Won Hand Team
  27. deriving (Show, Eq)
  28. data SkatP = SkatP
  29. deriving (Show, Eq)
  30. data Piles = Piles { hands :: [CardS Hand]
  31. , played :: [CardS Played]
  32. , skat :: [CardS SkatP] }
  33. deriving (Show, Eq)
  34. instance Countable Piles (Int, Int) where
  35. count ps = (sgl, tm)
  36. where sgl = count (skatCards ps) + count (wonCards Single ps)
  37. tm = count (wonCards Team ps)
  38. origin :: CardS Played -> Hand
  39. origin (CardS _ (Table hand)) = hand
  40. origin (CardS _ (Won hand _)) = hand
  41. originOfCard :: Card -> Piles -> Maybe Hand
  42. originOfCard card (Piles _ pld _) = origin <$> find ((==card) . getCard) pld
  43. playCard :: Card -> Piles -> Piles
  44. playCard card (Piles hs pld skt) = Piles hs' (ca : pld) skt
  45. where (CardS _ hand, hs') = remove ((==card) . getCard) hs
  46. ca = CardS card (Table hand)
  47. winCard :: Team -> CardS Played -> CardS Played
  48. winCard team (CardS card (Table hand)) = CardS card (Won hand team)
  49. winCard team c = c
  50. wonCards :: Team -> Piles -> [Card]
  51. wonCards team (Piles _ pld _) = filterMap (f . getPile) getCard pld
  52. where f (Won _ tm) = tm == team
  53. f _ = False
  54. cleanTable :: Team -> Piles -> Piles
  55. cleanTable winner ps@(Piles hs pld skt) = Piles hs pld' skt
  56. where table = tableCards ps
  57. pld' = map (winCard winner) pld
  58. tableCards :: Piles -> [Card]
  59. tableCards (Piles _ pld _) = filterMap (f . getPile) getCard pld
  60. where f (Table _) = True
  61. f _ = False
  62. tableCardsS :: Piles -> [CardS Played]
  63. tableCardsS (Piles _ pld _) = filter (f . getPile) pld
  64. where f (Table _) = True
  65. f _ = False
  66. handCards :: Hand -> Piles -> [Card]
  67. handCards hand (Piles hs _ _) = filterMap ((==hand) . getPile) getCard hs
  68. skatCards :: Piles -> [Card]
  69. skatCards (Piles _ _ skat) = map getCard skat
  70. putAt :: p -> Card -> CardS p
  71. putAt = flip CardS
  72. distribute :: [Card] -> Piles
  73. distribute cards = Piles hands [] (map (putAt SkatP) skt)
  74. where round1 = chunksOf 3 (take 9 cards)
  75. skt = take 2 $ drop 9 cards
  76. round2 = chunksOf 4 (take 12 $ drop 11 cards)
  77. round3 = chunksOf 3 (take 9 $ drop 23 cards)
  78. hand1 = concatMap (!! 0) [round1, round2, round3]
  79. hand2 = concatMap (!! 1) [round1, round2, round3]
  80. hand3 = concatMap (!! 2) [round1, round2, round3]
  81. hands = map (putAt Hand1) hand1
  82. ++ map (putAt Hand2) hand2
  83. ++ map (putAt Hand3) hand3