[LIB-9] Add SAN, NAG, move number and result PGN tokens
[chesshog.git] / chesshog-format / src / main / java / org / hedgecode / chess / pgn / token / MoveToken.java
index de59a2c..ea89dfc 100644 (file)
@@ -21,7 +21,11 @@ import java.util.regex.Pattern;
 
 import org.hedgecode.chess.ParseException;
 import org.hedgecode.chess.pgn.entity.DetailMove;
+import org.hedgecode.chess.pgn.entity.MoveNumber;
 import org.hedgecode.chess.pgn.entity.Moves;
+import org.hedgecode.chess.pgn.nag.Glyph;
+import org.hedgecode.chess.pgn.token.san.CommonSANToken;
+import org.hedgecode.chess.pgn.token.san.SANToken;
 
 /**
  * MoveToken
@@ -30,32 +34,44 @@ import org.hedgecode.chess.pgn.entity.Moves;
  */
 public class MoveToken implements Token<Moves> {
 
-    private static final String MOVE_REGEX = "^\\s*(([0-9]+)\\s*(\\.|\\.{3})\\s*)*([PNBRQK]?[a-hx1-8\\-O]+(=[NBRQ])?([+#])?)";
+    public static final String MOVE_REGEX = "^\\s*([PNBRQKa-hx1-8=+#\\-O!?]+)(\\s+\\$([0-9]+))?";
     private static final Pattern MOVE_PATTERN = Pattern.compile(MOVE_REGEX);
-    private static final int PLY_GROUP = 2, DOT_GROUP = 3, MOVE_GROUP = 4;
-    private static final String DOT_BLACK = "...";
+    private static final int MOVE_GROUP = 1, NAG_GROUP = 3;
+
+    private final Token<MoveNumber> moveNumberToken = new MoveNumberToken();
+    private final SANToken moveSanToken = new CommonSANToken();
 
     @Override
     public int token(Moves moves, String pgn) throws ParseException {
+        MoveNumber moveNumber = new MoveNumber(
+                moves.currentMove().ply()
+        );
+        int numberLength = moveNumberToken.token(moveNumber, pgn);
+        if (numberLength > 0) {
+            pgn = pgn.substring(numberLength);
+        }
         Matcher matcher = MOVE_PATTERN.matcher(pgn);
         if (!matcher.find()) {
             throw new ParseException("parse.pgn.incorrect.move", pgn);
         } else {
-            boolean isBlackMove = isBlackMove(matcher.group(DOT_GROUP));
-            String plyStr = matcher.group(PLY_GROUP);
-            int ply = plyStr != null
-                    ? Integer.parseInt(plyStr) * 2 - (isBlackMove ? 0 : 1)
-                    : moves.currentMove().ply() + 1;
             String move = matcher.group(MOVE_GROUP);
+            moveSanToken.token(move);
+            DetailMove detailMove = new DetailMove(
+                    moveNumber.ply(), move
+            );
             moves.addMove(
-                    new DetailMove(ply, move)
+                    detailMove
             );
+            String glyph = matcher.group(NAG_GROUP); // todo: more then one NAG
+            if (glyph != null) {
+                detailMove.addGlyph(
+                        Glyph.byNumber(
+                                Integer.parseInt(glyph)
+                        )
+                );
+            }
         }
-        return matcher.group().length();
-    }
-
-    private boolean isBlackMove(String dotGroup) {
-        return dotGroup == null || dotGroup.equals(DOT_BLACK);
+        return numberLength + matcher.group().length();
     }
 
 }