tak-0.1.0.0: src/Tak/ParsePTN.hs
module Tak.ParsePTN (parsePtn) where
import Data.List
import Data.Maybe
import Text.Parsec
import Safe
import Tak.Types
parsePtn :: String -> Either ParseError Play
parsePtn str = parse ptn "" str
type Parser a = Parsec String () a
ptn :: Parser Play
ptn = try move <|> place
place :: Parser Play
place = do
ms <- optionMaybe stone
(x, y) <- loc
return $ Place (fromJustDef Flat ms) (x, y)
move :: Parser Play
move = do
mc <- optionMaybe int
(x, y) <- loc
d <- dir
drops <- many int
let drops' = case drops of
[] -> case mc of
Nothing -> [1]
Just c -> [c]
_ -> drops
optional $ stone >> return ()
return $ Move (x, y) d drops'
dir :: Parser Dir
dir = posx <|> negx <|> posy <|> negy where
posx = char '>' >> return PosX
negx = char '<' >> return NegX
posy = char '+' >> return PosY
negy = char '-' >> return NegY
stone :: Parser Stone
stone = flat <|> standing <|> cap where
flat = char 'F' >> return Flat
standing = char 'S' >> return Standing
cap = char 'C' >> return Cap
loc :: Parser (Int, Int)
loc = do
r <- rank
f <- file
return (r, f)
rank :: Parser Int
rank = do
let chars = "abcdefghijklmnopqrstuvwxyz"
c <- oneOf chars
return $ (fromJust $ elemIndex c chars) + 1
file :: Parser Int
file = int
int :: Parser Int
int = do
i <- digit
return $ read [i]