Skat Engine und AI auf Haskell Basis
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

104 řádky
3.0KB

  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)
  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. handCards :: Hand -> Piles -> [Card]
  63. handCards hand (Piles hs _ _) = filterMap ((==hand) . getPile) getCard hs
  64. skatCards :: Piles -> [Card]
  65. skatCards (Piles _ _ skat) = map getCard skat
  66. putAt :: p -> Card -> CardS p
  67. putAt = flip CardS
  68. distribute :: [Card] -> Piles
  69. distribute cards = Piles hands [] (map (putAt SkatP) skt)
  70. where round1 = chunksOf 3 (take 9 cards)
  71. skt = take 2 $ drop 9 cards
  72. round2 = chunksOf 4 (take 12 $ drop 11 cards)
  73. round3 = chunksOf 3 (take 9 $ drop 23 cards)
  74. hand1 = concatMap (!! 0) [round1, round2, round3]
  75. hand2 = concatMap (!! 1) [round1, round2, round3]
  76. hand3 = concatMap (!! 2) [round1, round2, round3]
  77. hands = map (putAt Hand1) hand1
  78. ++ map (putAt Hand2) hand2
  79. ++ map (putAt Hand3) hand3