summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2023-01-08 21:48:10 +0800
committerFrederick Yin <fkfd@fkfd.me>2023-01-08 21:48:10 +0800
commit63c6921b102b5b97bc3d030b22fc941c64c0acd2 (patch)
tree3c913a188453ebe182dccfa54ea4d636926e6eab
parent23c093dbf45f13e1842dada2dc933944a1402fd6 (diff)
Validate attempted shed against prev card
-rw-r--r--Game.hs68
-rw-r--r--Main.hs3
2 files changed, 40 insertions, 31 deletions
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
diff --git a/Main.hs b/Main.hs
index 7e66efa..aaae87c 100644
--- a/Main.hs
+++ b/Main.hs
@@ -29,7 +29,8 @@ main = do
, playerIdx = 0
, attack = 1
, direction = 1
- , stockPile = stock
+ , prevCard = head stock
+ , stockPile = tail stock
, discardPile = discard
}