Skip to content

Commit

Permalink
improved the ways messages are sent between client and server and int…
Browse files Browse the repository at this point in the history
…roduced new msg type BOARD
  • Loading branch information
nikolasburk committed Nov 25, 2015
1 parent 9d6fd74 commit 5c6f848
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
7 changes: 5 additions & 2 deletions Board.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ boardFromRows rows
| length rows /= 3 = Left ("Not the right number of rows: " ++ show (length rows))
| otherwise = Right (BoardCons (rows !! 0) (rows !! 1) (rows !! 2))

boardFromRows' :: [Row] -> Board
boardFromRows' rows = (BoardCons (rows !! 0) (rows !! 1) (rows !! 2))


-- checks the range of the indices
isValidIndex :: (Int, Int) -> Bool
Expand Down Expand Up @@ -94,8 +97,8 @@ replaceRow newRow i (BoardCons r0 r1 r2)

-- HELPERS: Board encoding / decoding

decodeBoard :: String -> BoardOrMsg
decodeBoard s = boardFromRows $ snd $ foldl dec (0, [], []) s
decodeBoard :: String -> Board
decodeBoard s = boardFromRows' $ snd $ foldl dec (0, [], []) s
where snd (_, x, _) = x

dec :: (Int, [Row], [Field])-> Char -> (Int, [Row], [Field])
Expand Down
40 changes: 23 additions & 17 deletions TTTClient.hs
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import Network.Socket
import Network.BSD
import Control.Monad
import System.IO
import TTTServer
import TicTacToe

import Board

playGame :: HostName -> String -> IO ()
playGame hostname port = do
p <- getPlayerFromConnection hostname port
playersTurn p
playersTurn' p
return ()


playersTurn :: Player -> IO ()
playersTurn p = do
m1 <- hGetLine $ handle p
putStrLn $ "did reveive msg from server: " ++ m1
col <- getLine
hPutStrLn (handle p) col
m2 <- hGetLine $ handle p
putStrLn $ "did reveive msg from server: " ++ m2
row <- getLine
hPutStrLn (handle p) row
playersTurn p
return ()
playersTurn' :: Player -> IO ()
playersTurn' p = do
m <- hGetLine $ handle p
putStrLn m
maybeInp <- processMsg m
case maybeInp of
Nothing -> playersTurn' p
Just inp -> do
hPutStrLn (handle p) inp
playersTurn' p

processMsg :: String -> IO (Maybe String)
processMsg s = let msg = stringToMsg s
in case msgType msg of
REQ_INPUT -> do
inp <- getLine
return $ Just inp
_ -> return Nothing

getPlayerFromConnection :: HostName -> String -> IO Player
getPlayerFromConnection hostname port = do
Expand All @@ -47,8 +53,8 @@ getPlayerFromConnection hostname port = do
h <- socketToHandle sock ReadWriteMode
hSetBuffering h LineBuffering

info <- hGetLine h
putStrLn $ "initial info: " ++ info
--info <- hGetLine h
--putStrLn $ "initial info: " ++ info

return $ Player h Cross

36 changes: 23 additions & 13 deletions TTTServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ data Game = Game { player1 :: Player,

type PendingPlayers = [Handle]

data MsgType = REQ_INPUT | INFO deriving (Eq, Show)
data Message = Message { msgType :: MsgType,
msg :: String }

instance Show Message where
show m = show (msgType m) ++ ": " ++ msg m


serveTTT :: String -> IO ()
serveTTT port = do
Expand Down Expand Up @@ -77,21 +70,27 @@ serveTTT port = do
sendMessage (Message INFO "You're playing 'O'") p2
manageRound game
return ()

manageRound :: Game -> IO ()
manageRound game = do

-- | check if someone won the game already
case checkWinnerPure $ board game of
Nothing -> print $ board game
Just p -> do
putStrLn $ "Player " ++ show p ++ " won the game"
handleGameOver game
return ()

-- | determined the current player
let p = case currentPlayer $ board game of
Cross -> player1 game
Circle -> player2 game
--let boardInfo = "Board:\n" ++ show (board game)
--sendMessage (Message INFO boardInfo) p

-- | send the current board to the player
sendMessage (Message BOARD $ encodeBoard $ board game) p

-- | get the input from the current player
(col, row) <- getPlayerChoice p
case mkChoice (col, row, marker p) $ board game of
Left msg -> do
Expand All @@ -103,6 +102,7 @@ serveTTT port = do
manageRound newGame
return ()

-- | get input from from a player
getPlayerChoice :: Player -> IO (Int, Int)
getPlayerChoice p = do
col <- getPlayerInput p "column"
Expand Down Expand Up @@ -130,16 +130,26 @@ serveTTT port = do

-- | HELPERS: Messaging

data MsgType = REQ_INPUT | INFO | BOARD | UNKNOWN deriving (Eq, Show)
data Message = Message { msgType :: MsgType,
content :: String}

instance Show Message where
show m = show (msgType m) ++ ": " ++ content m

sendMessage :: Message -> Player -> IO ()
sendMessage m p = do
hPrint (handle p) m
hPrint (handle p) m
putStrLn $ "did send message to client: " ++ show m

stringToMsg :: String -> Message
stringToMsg s
| isPrefix "INFO" s = Message INFO (drop 5 s)
| isPrefix "REQ_INPUT" s = Message REQ_INPUT (drop 10 s)
| isPrefix "INFO" s = Message INFO $ drop 5 s
| isPrefix "REQ_INPUT" s = Message REQ_INPUT $ drop 10 s
| isPrefix "BOARD" s = Message BOARD $ drop 6 s
| otherwise = Message UNKNOWN s

-- HELPERS :: General

updateBoard :: Board -> Game -> Game
updateBoard b g = Game (player1 g) (player2 g) b
Expand Down

0 comments on commit 5c6f848

Please sign in to comment.