-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.hs
89 lines (77 loc) · 2.68 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module Main where
import System.Random (newStdGen)
import Control.Monad.State
import Data.List (sortBy)
import Data.Char (ord)
import NoThanks
type NoThanksM a = StateT Game IO a
data Decision = Accept | Bet
-- Convenience function to putStrLn anything
ioPrint :: String -> NoThanksM ()
ioPrint = lift . putStrLn
gameLoop :: NoThanksM [Player]
gameLoop = do
emptyDeck <- liftM null $ gets deck
case emptyDeck of
True -> gets players
False -> runGame >> gameLoop
prettyPrint :: [Player] -> [String]
prettyPrint ps = map pretty' ps
where pretty' :: Player -> String
pretty' p = name p ++ ": " ++ (show $ playerCards p) ++ ", " ++ (show $ markers p) ++ " markers, score: " ++ show (totalScore p)
runGame :: NoThanksM ()
runGame = do
curr <- gets getCurrentPlayer
let nm = name curr
score = totalScore curr
top <- liftM show $ gets topCard
ms <- liftM show $ gets currentBet
futureScore <- liftM show $ gets (totalScore . getCurrentPlayer . acceptCard)
ioPrint $ "Current state:"
gets players >>= mapM_ ioPrint . prettyPrint
gets (length . deck) >>= \cs -> ioPrint $ "Cards left: " ++ (show cs)
ioPrint ""
case canBet curr of
False -> do
ioPrint $ nm ++ " has no markers, accepting card"
ioPrint $ nm ++ " got " ++ top ++ " and " ++ ms ++ " markers"
ioPrint ""
modify acceptCard
True -> do
ioPrint $ nm ++ ": the top card is " ++ top ++ ", the bet is " ++ ms
ioPrint $ nm ++ " score: " ++ (show score) ++ ", if accepting: " ++ futureScore
c <- decidePrompt nm
ioPrint ""
case c of
Bet -> modify placeBet
Accept -> modify acceptCard
where
decidePrompt nm = do
ioPrint $ nm ++ ": bet (b) or accept (a)?"
c <- lift $ getChar
case c of
'b' -> return Bet
'a' -> return Accept
_ -> do ioPrint ""
ioPrint "Invalid command, try again"
decidePrompt nm
getPlayers :: IO [String]
getPlayers = do
putStr "Select number of players (2-5): "
c <- getChar
putStrLn ""
case c `elem` ['2'..'5'] of
True -> replicateM ((ord c) - 48) $ do
putStr "Enter player name: "
getLine
False -> putStrLn "Invalid number, try again" >> getPlayers
main :: IO ()
main = do
gen <- newStdGen
players <- getPlayers
let game = newGame gen players
endGame <- execStateT gameLoop game
putStrLn "*********"
putStrLn "Game over"
putStrLn "*********"
forM_ (scoreList endGame) $ \(n,sc) -> putStrLn $ n ++ " final score: " ++ show sc