PageRenderTime 30ms CodeModel.GetById 26ms app.highlight 2ms RepoModel.GetById 0ms app.codeStats 1ms

/examples/BlackjackClient.hs

http://github.com/DanBurton/netspec
Haskell | 71 lines | 58 code | 13 blank | 0 comment | 5 complexity | 1c0d6dbe557914d41e6c959490f2cf0a MD5 | raw file
Possible License(s): BSD-3-Clause
 1module BlackjackClient where
 2
 3import BlackjackData
 4
 5import Network.NetSpec
 6import Network.NetSpec.Json
 7
 8import Control.Monad (void)
 9import Data.List (intercalate)
10import System.Environment (getArgs)
11import Text.Printf (printf)
12
13readInt :: String -> Int
14readInt = read
15
16data ClientState = CS
17  { myIndex :: Int }
18
19askAction :: Hand -> IO BlackjackClientMessage
20askAction _ = putStrLn "Hit or Stand?" >> read <$> getLine
21
22botAction :: Hand -> IO BlackjackClientMessage
23botAction h
24  | hiVal h > 17 = putStrLn "Stand" >> return Stand
25  | loVal h > 14 = putStrLn "Stand" >> return Stand
26  | otherwise    = putStrLn "Hit" >> return Hit
27
28resolution :: String -> ClientState -> BlackjackState -> IO ()
29resolution str (CS i) (BJ hs _) = printEnd hs i >> putStrLn str
30
31win :: ClientState -> BlackjackState -> IO ()
32win = resolution "You win!"
33
34lose :: ClientState -> BlackjackState -> IO ()
35lose = resolution "You lose!"
36
37printEnd :: [Hand] -> Int -> IO ()
38printEnd [h0,h1] i = let (you, opp) = if i == 0 then (h0,h1) else (h1,h0)
39                     in do putStrLn $ replicate 40 '-'
40                           void $ printf "You:  %s (%d)\n" (show you) (bestVal you)
41                           void $ printf "Them: %s (%d)\n" (show opp) (bestVal opp)
42printEnd _ _ = error "Unexpected number of hands"
43
44displayTurn :: Hand -> Card -> Int -> IO ()
45displayTurn hand c n = do
46  void $ printf "You: %s" (show hand)
47  putStrLn $ replicate 20 ' '
48  void $ printf "Opponent: [%s,%s]\n" (show c) oHand
49  where oHand = intercalate "," $ replicate (pred n) "|??|"
50
51main :: IO ()
52main = do
53  (host:port:bot) <- getArgs
54  let chooseAction = if null bot then askAction else botAction
55  runSpec ClientSpec
56    { _conns = [(host, PortNumber (fromIntegral $ readInt port))]
57    , _begin = \[h] -> do
58         Just m <- receive h
59         case m of YouAre i -> return $ CS i
60    , _loop = \[h] s -> do
61         Just m <- receive h
62         case m of
63           YourTurn hand c n -> do
64             displayTurn hand c n
65             action <- chooseAction hand
66             h ! action
67             continue s
68           YouWin gs -> win s gs >> stop s
69           YouLose gs -> lose s gs >> stop s
70    , _end = \_ _ -> return ()
71    }