module Chess.FEN (writeFEN, readFEN) where
import Chess.Internal.Move
import Chess.Internal.FEN
writeFEN :: GameState -> String
writeFEN :: GameState -> String
writeFEN GameState
state = [String] -> String
unwords [Board -> String
writeBoard (GameState -> Board
stateBoard GameState
state),
Color -> String
writePlayer (GameState -> Color
currentPlayer GameState
state),
[CastlingType] -> [CastlingType] -> String
writeCastlings (GameState -> [CastlingType]
whiteCastlingsPossible GameState
state) (GameState -> [CastlingType]
blackCastlingsPossible GameState
state),
Maybe Coordinates -> String
writeEnPassant (GameState -> Maybe Coordinates
enPassantSquare GameState
state),
Integer -> String
forall a. Show a => a -> String
show (GameState -> Integer
halfmoveClock GameState
state),
Integer -> String
forall a. Show a => a -> String
show (GameState -> Integer
moveNumber GameState
state)]
readFEN :: String -> Maybe GameState
readFEN :: String -> Maybe GameState
readFEN String
str | [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
parts Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
6 = Maybe GameState
forall a. Maybe a
Nothing
| Bool
otherwise = do Board
board' <- String -> Maybe Board
readBoard (String -> Maybe Board) -> String -> Maybe Board
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. [a] -> a
head [String]
parts
Color
player <- String -> Maybe Color
readPlayer (String -> Maybe Color) -> String -> Maybe Color
forall a b. (a -> b) -> a -> b
$ [String]
parts [String] -> Int -> String
forall a. [a] -> Int -> a
!! Int
1
([CastlingType], [CastlingType])
castlings <- String -> Maybe ([CastlingType], [CastlingType])
readCastlings (String -> Maybe ([CastlingType], [CastlingType]))
-> String -> Maybe ([CastlingType], [CastlingType])
forall a b. (a -> b) -> a -> b
$ [String]
parts [String] -> Int -> String
forall a. [a] -> Int -> a
!! Int
2
Maybe Coordinates
enPassant <- String -> Maybe (Maybe Coordinates)
readEnPassant (String -> Maybe (Maybe Coordinates))
-> String -> Maybe (Maybe Coordinates)
forall a b. (a -> b) -> a -> b
$ [String]
parts [String] -> Int -> String
forall a. [a] -> Int -> a
!! Int
3
Integer
halfmoves <- Integer -> String -> Maybe Integer
forall a. (Ord a, Read a) => a -> String -> Maybe a
readNumberWithLimit Integer
0 (String -> Maybe Integer) -> String -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ [String]
parts [String] -> Int -> String
forall a. [a] -> Int -> a
!! Int
4
Integer
moves <- Integer -> String -> Maybe Integer
forall a. (Ord a, Read a) => a -> String -> Maybe a
readNumberWithLimit Integer
1 (String -> Maybe Integer) -> String -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ [String]
parts [String] -> Int -> String
forall a. [a] -> Int -> a
!! Int
5
GameState -> Maybe GameState
forall (m :: * -> *) a. Monad m => a -> m a
return (GameState -> Maybe GameState) -> GameState -> Maybe GameState
forall a b. (a -> b) -> a -> b
$ ([CastlingType]
-> [CastlingType]
-> Maybe Coordinates
-> Integer
-> Integer
-> GameState)
-> ([CastlingType], [CastlingType])
-> Maybe Coordinates
-> Integer
-> Integer
-> GameState
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Board
-> Color
-> [CastlingType]
-> [CastlingType]
-> Maybe Coordinates
-> Integer
-> Integer
-> GameState
State Board
board' Color
player) ([CastlingType], [CastlingType])
castlings Maybe Coordinates
enPassant Integer
halfmoves Integer
moves
where parts :: [String]
parts = String -> [String]
words String
str