1
1
{-# LANGUAGE DeriveDataTypeable #-}
2
2
{-# LANGUAGE OverloadedStrings #-}
3
3
{-# LANGUAGE TypeFamilies #-}
4
+ {-# LANGUAGE RecordWildCards #-}
4
5
5
6
module Formats.Pdn where
6
7
7
8
import Control.Monad
8
9
import Control.Monad.State
9
10
import Data.Char
10
11
import Data.Maybe
12
+ import Data.List
11
13
import qualified Data.Map as M
12
14
import qualified Data.Text as T
13
15
import Text.Megaparsec hiding (Label , State )
@@ -44,13 +46,15 @@ pSemiMove rules = try full <|> try short
44
46
x <- oneOf [' -' , ' x' ]
45
47
let capture = (x == ' x' )
46
48
to <- pLabel rules
47
- return $ SemiMoveRec from to capture
49
+ return $ ShortSemiMoveRec from to capture
48
50
49
51
full = do
50
- from <- pLabel rules
52
+ first <- pLabel rules
53
+ char ' x'
54
+ second <- pLabel rules
51
55
char ' x'
52
- labels <- pLabel rules `sepBy1` char ' x'
53
- return $ SemiMoveRec from ( last labels) True
56
+ rest <- pLabel rules `sepBy1` char ' x'
57
+ return $ FullSemiMoveRec (first : second : rest)
54
58
55
59
whitespace :: Parser ()
56
60
whitespace = label " white space or comment" $ do
@@ -202,13 +206,22 @@ parsePdnFile dfltRules path = do
202
206
parseMoveRec :: GameRules rules => rules -> Side -> Board -> SemiMoveRec -> Move
203
207
parseMoveRec rules side board rec =
204
208
let moves = possibleMoves rules side board
205
- suits m = aLabel (pmBegin m) == smrFrom rec &&
206
- aLabel (pmEnd m) == smrTo rec &&
207
- (not $ null $ pmVictims m) == smrCapture rec
209
+ passedFields m = nonCaptureLabels rules side board (pmMove m)
210
+ suits m =
211
+ case rec of
212
+ ShortSemiMoveRec {.. } ->
213
+ aLabel (pmBegin m) == smrFrom &&
214
+ aLabel (pmEnd m) == smrTo &&
215
+ (not $ null $ pmVictims m) == smrCapture
216
+ FullSemiMoveRec {.. } ->
217
+ (not $ null $ pmVictims m) &&
218
+ smrLabels `isSubsequenceOf` passedFields m
208
219
in case filter suits moves of
209
220
[m] -> pmMove m
210
- [] -> error $ printf " no such move: %s; side: %s; board: %s" (show rec ) (show side) (show board)
211
- ms -> error $ " ambigous move: " ++ show ms
221
+ [] -> error $ printf " no such move: %s; side: %s; board: %s; possible: %s"
222
+ (show rec ) (show side) (show board) (show $ map passedFields moves)
223
+ ms -> error $ printf " ambigous move: %s; candidates are: %s; board: %s"
224
+ (show rec ) (show ms) (show board)
212
225
213
226
fenFromTags :: [Tag ] -> Maybe Fen
214
227
fenFromTags [] = Nothing
@@ -359,7 +372,7 @@ gameToPdn game =
359
372
360
373
translateMove :: SomeRules -> Side -> Board -> Move -> SemiMoveRec
361
374
translateMove (SomeRules rules) side board move =
362
- SemiMoveRec {
375
+ ShortSemiMoveRec {
363
376
smrFrom = aLabel (moveBegin move)
364
377
, smrTo = aLabel (moveEnd rules side board move)
365
378
, smrCapture = isCapture move
@@ -379,9 +392,9 @@ showPdn (SomeRules rules) gr =
379
392
showMove n (MoveRec (Just s1) Nothing ) = T. pack (show n) <> " . " <> showSemiMove s1
380
393
showMove n (MoveRec (Just s1) (Just s2)) = T. pack (show n) <> " . " <> showSemiMove s1 <> " " <> showSemiMove s2
381
394
382
- showSemiMove (SemiMoveRec from to False ) =
395
+ showSemiMove (ShortSemiMoveRec from to False ) =
383
396
boardNotation rules from <> " -" <> boardNotation rules to
384
- showSemiMove (SemiMoveRec from to True ) =
397
+ showSemiMove (ShortSemiMoveRec from to True ) =
385
398
boardNotation rules from <> " x" <> boardNotation rules to
386
399
387
400
showTag (Event text) = T. pack (printf " [Event \" %s\" ]" text)
0 commit comments