From 63c6921b102b5b97bc3d030b22fc941c64c0acd2 Mon Sep 17 00:00:00 2001 From: Frederick Yin Date: Sun, 8 Jan 2023 21:48:10 +0800 Subject: Validate attempted shed against prev card --- Game.hs | 68 ++++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 30 deletions(-) (limited to 'Game.hs') diff --git a/Game.hs b/Game.hs index 871d188..e6d8270 100644 --- a/Game.hs +++ b/Game.hs @@ -12,6 +12,7 @@ data Game = Game { players :: [Player] , playerIdx :: Int , attack :: Int , direction :: Int -- ^ 1 when CCW, -1 when CW + , prevCard :: Card , stockPile :: [Card] , discardPile :: [Card] } @@ -27,35 +28,38 @@ beginRounds n game = do -- | Let current player take their turn. beginTurn :: Game -> IO Game -beginTurn game@(Game plyrs pidx att dir stock disc) = do +beginTurn game@(Game plyrs pidx att dir prev stock disc) = do + let player = plyrs !! pidx + putStrLn $ replicate 80 '-' + putStrLn $ P.name player ++ "'s turn (input 0 to skip turn and draw card)" + putStrLn $ P.showCards player putStrLn $ "Current attack: " ++ show att - decision <- prompt game + putStrLn $ "Prev card: " ++ C.showCard prev - let player = plyrs !! pidx - game'@(Game _ pidx' _ _ _ _) - <- case decision of - Nothing -> drawAndSkip game - Just card -> shedAndContinue card game + decision <- prompt game + game' <- case decision of + Nothing -> drawAndSkip game + Just card -> shedAndContinue card game - if pidx' == pidx -- shedAndContinue does this when player wins + if playerIdx game' == pidx -- shedAndContinue does this when player wins then return game' else beginTurn game' -- | Game state after player draws card(s) and skips turn. drawAndSkip :: Game -> IO Game -drawAndSkip game@(Game plyrs pidx att dir stock disc) = do +drawAndSkip game@(Game plyrs pidx att dir prev stock disc) = do let player = plyrs !! pidx let player' = player `draw` (take att stock) let plyrs' = P.update plyrs pidx player' let pidx' = (pidx + dir) `mod` length plyrs let stock' = drop att stock putStrLn $ (P.name player) ++ " draws " ++ (C.showCards $ take att stock) - return $ Game plyrs' pidx' 1 dir stock' disc + return $ Game plyrs' pidx' 1 dir prev stock' disc -- | Game state after player sheds card. shedAndContinue :: Card -> Game -> IO Game -shedAndContinue card game@(Game plyrs pidx att dir stock disc) = do +shedAndContinue card game@(Game plyrs pidx att dir prev stock disc) = do let player = plyrs !! pidx let player' = player `shed` card let disc' = card:disc @@ -73,35 +77,39 @@ shedAndContinue card game@(Game plyrs pidx att dir stock disc) = do Card _ C.Three -> if att == 1 then 3 else att + 3 _ -> 1 putStrLn $ (P.name player) ++ " plays " ++ (C.showCard card) - return $ Game plyrs' pidx' att' dir' stock disc' + return $ Game plyrs' pidx' att' dir' card stock disc' -- | Prompt player to play a card (or draw card and skip turn). prompt :: Game -> IO (Maybe Card) -prompt game@(Game plyrs pidx att _ _ _) = do +prompt game@(Game plyrs pidx att _ prev _ _) = do let player = plyrs !! pidx let cards = P.cards player - putStrLn $ P.name player ++ "'s turn (input 0 to skip turn and draw card)" - putStrLn $ P.showCards player cardIdxStr <- getLine if any (== False) $ map isDigit cardIdxStr - then do - putStrLn "Please input card #" - prompt game - else do - let cardIdx = read cardIdxStr - 1 - if cardIdx == -1 - then do - return Nothing - else do - if cardIdx < 0 || cardIdx >= length cards - then do - putStrLn "This card does not exist, try again" - prompt game - else return $ Just (cards !! cardIdx) + then do + putStrLn "Please input card #" + prompt game + else do + let cardIdx = read cardIdxStr - 1 + if cardIdx == -1 + then do + return Nothing + else do + if cardIdx < 0 || cardIdx >= length cards + then do + putStrLn "This card does not exist, try again" + prompt game + else do + let card = cards !! cardIdx + if C.isValid prev card + then return $ Just card + else do + putStrLn "You cannot play this card, try again" + prompt game -- | Deal c cards to each player in game. dealCards :: Int -> Game -> Game -dealCards c game@(Game plyrs _ _ _ stock disc) +dealCards c game@(Game plyrs _ _ _ _ stock disc) | (length $ P.cards $ head plyrs) < c = dealCards c game { players = newPlyrs, stockPile = newStock } | otherwise = game -- cgit v1.2.3