module Api( Player (..), Board (..), Row, Col, move, whoWon, takeBack, playerAt)whereimport Preludeimport Data.List (elemIndex)data Player = X | Oderiving (Eq, Show)data Row = R1 | R2 | R3deriving (Eq, Show)data Col = C1 | C2 | C3deriving (Eq, Show)type Position = (Row, Col)data Board = Empty| InPlay [Position] Player| Won [Position] Playermove :: Board -> Position -> Boardmove Empty pos = InPlay [pos] O -- X first, O nextmove brd@(InPlay ps player) pos =let occupied = pos `elem` psnewps = if occupied then ps else (pos:ps)done = full || won -- || unwinable -- TODOfull = length newps == 9-- unwinable = cantwin X && cantwin Y -- TODOwon = haswon X || haswon Ohaswon X = wins xmoveshaswon O = wins omovesxmoves = evenmoves psomoves = evenmoves (tail ps)evenmoves [] = []evenmoves (m:ms) = m : evenmoves (tail ms)wins moves =ownsrow R1 moves|| ownsrow R2 moves|| ownsrow R3 moves|| ownscol C1 moves|| ownscol C2 moves|| ownscol C3 moves|| owns [(R1,C1), (R2,C2), (R3,C3)] moves|| owns [(R3,C1), (R2,C2), (R1,C3)] movesownsrow :: Row -> [Position] -> Boolownsrow r moves = 3 == length (filter ((== r) . fst) moves)ownscol c moves = 3 == length (filter ((== c) . snd) moves)owns cells moves = all (`elem` moves) cellsinif occupiedthen brdelse if donethen Won (pos:ps) playerelse InPlay (pos:ps) (other player)whoWon :: Board -> PlayerwhoWon (Won _ player) = playertakeBack :: Board -> BoardtakeBack (Won (_:ps) player) = InPlay ps playertakeBack (InPlay (_:ps) player) = InPlay ps (other player)playerAt :: Board -> Position -> Maybe PlayerplayerAt Empty _ = NothingplayerAt (InPlay ps _) pos =case pos `elemIndex` ps ofJust idx -> Just $ if even idx then X else ONothing -> Nothing-- Todo: Copy paste makes me sadplayerAt (Won ps _) pos =case pos `elemIndex` ps ofJust idx -> Just $ if even idx then X else ONothing -> Nothingother :: Player -> Playerother X = Oother O = X-- WTF?-- Api.hs|53 col 5 error| Not in scope: ‘ifThenElse’-- ifThenElse :: Bool -> a -> a-- ifThenElse True a _ = a-- ifThenElse False _ b = b
{-# LANGUAGE NoMonomorphismRestriction #-}module Api( Player (..), Board (..), Row, Col, move, whoWon, takeBack, playerAt)whereimport Preludeimport Data.List (elemIndex)data Player = X | Oderiving (Eq, Show)data Row = R1 | R2 | R3deriving (Eq, Show)data Col = C1 | C2 | C3deriving (Eq, Show)type Position = (Row, Col)class Board a wherepositions :: a -> [Position]data Empty = Emptydata InPlay = InPlay [Position]data Won = Won [Position]instance Board Empty wherepositions _ = []instance Board InPlay wherepositions (InPlay poss) = possinstance Board Won wherepositions (Won poss) = possclass Started a wheretakeBack :: (Started a, Unfinished b) => a -> binstance Started InPlay wheretakeBack brd =case positions brd of[p] -> Empty(_:ps) -> InPlay psinstance Started Won wheretakeBack brd =InPlay (tail (positions brd))class Unfinished ainstance Unfinished Emptyinstance Unfinished InPlaymove :: (Unfinished a, Board b) => a -> Position -> bmove brd pos =letps = positions brdoccupied = pos `elem` psnewps = if occupied then ps else (pos:ps)done = full || won -- || unwinable -- TODOfull = length newps == 9-- unwinable = cantwin X && cantwin Y -- TODOwon = haswon X || haswon Ohaswon X = wins xmoveshaswon O = wins omovesxmoves = evenmoves psomoves = evenmoves (tail ps)evenmoves [] = []evenmoves (m:ms) = m : evenmoves (tail ms)wins moves =ownsrow R1 moves|| ownsrow R2 moves|| ownsrow R3 moves|| ownscol C1 moves|| ownscol C2 moves|| ownscol C3 moves|| owns [(R1,C1), (R2,C2), (R3,C3)] moves|| owns [(R3,C1), (R2,C2), (R1,C3)] movesownsrow :: Row -> [Position] -> Boolownsrow r moves = 3 == length (filter ((== r) . fst) moves)ownscol c moves = 3 == length (filter ((== c) . snd) moves)owns cells moves = all (`elem` moves) cellsinif occupiedthen brdelse if donethen Won (pos:ps)else InPlay (pos:ps)whoWon :: Won -> PlayerwhoWon (Won poss) = other (nextPlayer poss)nextPlayer poss| even (length poss) = O| otherwise = XplayerAt :: Board a => a -> Position -> Maybe PlayerplayerAt brd pos =let ps = positions brdincase pos `elemIndex` ps ofJust idx -> Just $ if even idx then X else ONothing -> Nothingother :: Player -> Playerother X = Oother O = X
--
You received this message because you are subscribed to the Google Groups "haskell-exercises" group.
To unsubscribe from this group and stop receiving emails from it, send an email to haskell-exerci...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.