|
- {-# LANGUAGE MultiParamTypeClasses #-}
- {-# LANGUAGE FlexibleInstances #-}
-
- module Pile where
-
- import Data.List
-
- import Card
- import Utils
- import Control.Exception
-
- data Team = Team | Single
- deriving (Show, Eq, Ord, Enum)
-
- data CardS p = CardS { getCard :: Card
- , getPile :: p }
- deriving (Show, Eq)
-
- instance Countable (CardS p) Int where
- count = count . getCard
-
- data Hand = Hand1 | Hand2 | Hand3
- deriving (Show, Eq)
-
- next :: Hand -> Hand
- next Hand1 = Hand2
- next Hand2 = Hand3
- next Hand3 = Hand1
-
- prev :: Hand -> Hand
- prev Hand1 = Hand3
- prev Hand2 = Hand1
- prev Hand3 = Hand2
-
- data Played = Table Hand
- | Won Hand Team
- deriving (Show, Eq)
-
- data SkatP = SkatP
- deriving (Show, Eq)
-
- data Piles = Piles { hands :: [CardS Hand]
- , played :: [CardS Played]
- , skat :: [CardS SkatP] }
- deriving (Show, Eq)
-
- instance Countable Piles (Int, Int) where
- count ps = (sgl, tm)
- where sgl = count (skatCards ps) + count (wonCards Single ps)
- tm = count (wonCards Team ps)
-
- origin :: CardS Played -> Hand
- origin (CardS _ (Table hand)) = hand
- origin (CardS _ (Won hand _)) = hand
-
- originOfCard :: Card -> Piles -> Maybe Hand
- originOfCard card (Piles _ pld _) = origin <$> find ((==card) . getCard) pld
-
- playCard :: Card -> Piles -> Piles
- playCard card (Piles hs pld skt) = Piles hs' (ca : pld) skt
- where (CardS _ hand, hs') = remove ((==card) . getCard) hs
- ca = CardS card (Table hand)
-
- winCard :: Team -> CardS Played -> CardS Played
- winCard team (CardS card (Table hand)) = CardS card (Won hand team)
- winCard team c = c
-
- wonCards :: Team -> Piles -> [Card]
- wonCards team (Piles _ pld _) = filterMap (f . getPile) getCard pld
- where f (Won _ tm) = tm == team
- f _ = False
-
- cleanTable :: Team -> Piles -> Piles
- cleanTable winner ps@(Piles hs pld skt) = Piles hs pld' skt
- where table = tableCards ps
- pld' = map (winCard winner) pld
-
- tableCards :: Piles -> [Card]
- tableCards (Piles _ pld _) = filterMap (f . getPile) getCard pld
- where f (Table _) = True
- f _ = False
-
- handCards :: Hand -> Piles -> [Card]
- handCards hand (Piles hs _ _) = filterMap ((==hand) . getPile) getCard hs
-
- skatCards :: Piles -> [Card]
- skatCards (Piles _ _ skat) = map getCard skat
-
- putAt :: p -> Card -> CardS p
- putAt = flip CardS
-
- distribute :: [Card] -> Piles
- distribute cards = Piles hands [] (map (putAt SkatP) skt)
- where round1 = chunksOf 3 (take 9 cards)
- skt = take 2 $ drop 9 cards
- round2 = chunksOf 4 (take 12 $ drop 11 cards)
- round3 = chunksOf 3 (take 9 $ drop 23 cards)
- hand1 = concatMap (!! 0) [round1, round2, round3]
- hand2 = concatMap (!! 1) [round1, round2, round3]
- hand3 = concatMap (!! 2) [round1, round2, round3]
- hands = map (putAt Hand1) hand1
- ++ map (putAt Hand2) hand2
- ++ map (putAt Hand3) hand3
|