|
- {-# LANGUAGE ExistentialQuantification #-}
-
- module Skat.Preperation (
-
- ) where
-
- import Control.Monad.IO.Class
- import Control.Monad.State
-
- import Skat.Pile
- import Skat.Card
- import Skat.Player (PL, Players(..))
- import Skat.Bidding
- import Skat (SkatEnv, mkSkatEnv)
-
- type Bid = Int
-
- data PrepEnv = PrepEnv { piles :: Piles
- , currentBid :: Bid
- , currentHand :: Hand
- , bidders :: Bidders }
- deriving Show
-
- type Preperation = StateT PrepEnv IO
-
- class Bidder a where
- hand :: a -> Hand
- askBid :: MonadIO m => a -> Hand -> Bid -> m (Maybe Bid)
- askResponse :: MonadIO m => a -> Hand -> m Bool
- askGame :: MonadIO m => a -> Bid -> m Game
- askHand :: MonadIO m => a -> Bid -> m Bool
- askSkat :: MonadIO m => a -> Bid -> [Card] -> m [Card]
- toPlayer :: a -> Team -> PL
-
- -- | trick to allow heterogenous bidder list
- data BD = forall b. (Show b, Bidder b) => BD b
-
- instance Show BD where
- show (BD b) = show b
-
- instance Bidder BD where
- hand (BD b) = hand b
- askBid (BD b) = askBid b
- askGame (BD b) = askGame b
- askHand (BD b) = askHand b
- askSkat (BD b) = askSkat b
- askResponse (BD b) = askResponse b
- toPlayer (BD b) = toPlayer b
-
- data Bidders = Bidders BD BD BD
- deriving Show
-
- bidder :: Bidders -> Hand -> BD
- bidder (Bidders b _ _) Hand1 = b
- bidder (Bidders _ b _) Hand2 = b
- bidder (Bidders _ _ b) Hand3 = b
-
- toPlayers :: Hand -> Bidders -> Players
- toPlayers single (Bidders b1 b2 b3) =
- Players (toPlayer b1 $ if single == Hand1 then Single else Team)
- (toPlayer b2 $ if single == Hand2 then Single else Team)
- (toPlayer b3 $ if single == Hand3 then Single else Team)
-
- runPreperation :: Preperation (Maybe SkatEnv)
- runPreperation = do
- bds <- gets bidders
- (winner, bid) <- runBidding 0 (bidder bds Hand2) (bidder bds Hand1)
- (finalWinner, finalBid) <- runBidding 0 (bidder bds Hand3) (bidder bds winner)
- if finalBid == 0 then do
- bid <- askBid (bidder bds finalWinner) finalWinner 0
- case bid of
- Just val -> Just <$> initGame finalWinner val
- Nothing -> return Nothing
- else Just <$> initGame finalWinner finalBid
-
- runBidding :: Bid -> BD -> BD -> Preperation (Hand, Bid)
- runBidding startingBid reizer gereizter = do
- first <- askBid reizer (hand gereizter) startingBid
- case first of
- Just val -> do
- response <- askResponse gereizter (hand reizer)
- if response then runBidding val reizer gereizter
- else return (hand reizer, val)
- Nothing -> return (hand gereizter, startingBid)
-
- initGame :: Hand -> Bid -> Preperation SkatEnv
- initGame single bid = do
- ps <- gets piles
- bds <- gets bidders
- -- ask if player wants to play hand
- noSkat <- askHand (bidder bds single) bid
- -- either return piles or ask for skat cards and modify piles
- ps' <- if noSkat then return ps else do
- let skat = skatCards ps
- skat' <- askSkat (bidder bds single) bid skat
- return $ moveToSkat single skat' ps
- -- ask for game kind
- (Colour col _) <- askGame (bidder bds single) bid
- -- construct skat env
- return $ mkSkatEnv ps Nothing col (toPlayers single bds) Hand1
|