Reputation: 35
I'm trying to implement the game connect four in Haskell. It's mostly functional at this point, but I'm having trouble passing the fact that the game has ended to the IO recursive function. Currently, the code will state that I have a "non exhaustive pattern in function gameloop" and I don't know how to exit out properly when a winstate is achieved.
Here's some code snippets:
data Action = Move Piece State Col -- do Piece in State
| Start -- returns starting state
data Result = EndOfGame Int -- end of game
| ContinueGame State
deriving (Eq, Show)
type Game = Action -> Result
connectfour :: Game
connectfour Start = ContinueGame ([],[],[],[],[],[],[])
connectfour (Move move state col)
| win move (addPiece move state col) col = EndOfGame move -- player of Piece value move wins
| isTie (addPiece move state col) = EndOfGame 0 -- no moves, tie
| otherwise = ContinueGame (addPiece move state col)
gameLoop (ContinueGame state) player = do
let turn = if player == 1 then 2 else 1
-- Removed code for forum, just prepping values to feed into printboard and printing dialog
putStrLn "Please select a column to enter your piece"
input <- getLine
gameLoop (connectfour (Move turn state (read input :: Int))) turn
TDLR; I'm trying to return a string saying which player has won on exit, but I don't know how to write a condition that checks for this in gameloop.
Upvotes: 2
Views: 716
Reputation: 32309
You just need to add a case for EndOfGame
in gameLoop
:
gameLoop :: Result -> Int -> IO ()
gameLoop (EndOfGame move) _ = putStrLn ("Game over! Player " ++ show move ++ " won")
gameLoop (ContinueGame state) player = do
{- omitted -}
gameLoop (connectfour (Move turn state (read input :: Int))) turn
The "non exhaustive pattern in function gameloop
" warning is telling you that gameLoop
is missing a case - the EndOfGame
one.
On another note, you might want to consider making a player ADT:
data Player = One | Two deriving (Show)
otherPlayer :: Player -> Player
otherPlayer One = Two
otherPlayer Two = One
Upvotes: 5