From 6cb0da80d76982cad7c172598ddf6af802ca0c4e Mon Sep 17 00:00:00 2001 From: kske Date: Tue, 19 Nov 2019 06:30:53 +0100 Subject: [PATCH] Created Move#fromSAN, moved implementation from Board --- src/dev/kske/chess/board/Board.java | 80 +----------------------- src/dev/kske/chess/board/Move.java | 96 +++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 79 deletions(-) diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java index 327e7e3..3288e2b 100644 --- a/src/dev/kske/chess/board/Board.java +++ b/src/dev/kske/chess/board/Board.java @@ -6,8 +6,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import dev.kske.chess.board.Piece.Color; @@ -98,83 +96,7 @@ public class Board { * @param sanMove The move to execute in SAN (Standard Algebraic Notation) */ public void move(String sanMove) { - Map patterns = new HashMap<>(); - patterns.put("pieceMove", - Pattern.compile( - "^(?[NBRQK])(?:(?[a-h])|(?[1-8])|(?[a-h][1-8]))?x?(?[a-h][1-8])(?:\\+{0,2}|\\#)$")); - patterns.put("pawnCapture", - Pattern.compile("^(?[a-h])(?[1-8])?x(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)?$")); - patterns.put("pawnPush", Pattern.compile("^(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)$")); - patterns.put("castling", Pattern.compile("^(?O-O-O)|(?O-O)(?:\\+{0,2}|\\#)?$")); - - patterns.forEach((patternName, pattern) -> { - Matcher m = pattern.matcher(sanMove); - if (m.find()) { - Position pos = null, dest = null; - Move move = null; - switch (patternName) { - case "pieceMove": - dest = Position.fromLAN(m.group("toSquare")); - if (m.group("fromSquare") != null) pos = Position.fromLAN(m.group("fromSquare")); - else { - Class pieceClass = Piece.fromFirstChar(m.group("pieceType").charAt(0)); - char file; - int rank; - if (m.group("fromFile") != null) { - file = m.group("fromFile").charAt(0); - rank = get(pieceClass, file); - pos = Position.fromLAN(String.format("%c%d", file, rank)); - } else if (m.group("fromRank") != null) { - rank = Integer.parseInt(m.group("fromRank").substring(0, 1)); - file = get(pieceClass, rank); - pos = Position.fromLAN(String.format("%c%d", file, rank)); - } else pos = get(pieceClass, dest); - } - move = new Move(pos, dest); - break; - case "pawnCapture": - char file = m.group("fromFile").charAt(0); - int rank = m.group("fromRank") == null ? get(Pawn.class, file) : Integer.parseInt(m.group("fromRank")); - - dest = Position.fromLAN(m.group("toSquare")); - pos = Position.fromLAN(String.format("%c%d", file, rank)); - - if (m.group("promotedTo") != null) { - try { - move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0))); - } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) { - e.printStackTrace(); - } - } else move = new Move(pos, dest); - break; - case "pawnPush": - dest = Position.fromLAN(m.group("toSquare")); - int step = log.getActiveColor() == Color.WHITE ? 1 : -1; - - // One step forward - if (boardArr[dest.x][dest.y + step] != null) pos = new Position(dest.x, dest.y + step); - - // Double step forward - else pos = new Position(dest.x, dest.y + 2 * step); - - if (m.group("promotedTo") != null) { - try { - move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0))); - } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) { - e.printStackTrace(); - } - } else move = new Move(pos, dest); - break; - case "castling": - pos = new Position(4, log.getActiveColor() == Color.WHITE ? 7 : 0); - dest = new Position(m.group("kingside") != null ? 6 : 2, pos.y); - move = new Castling(pos, dest); - break; - } - move(move); - return; - } - }); + move(Move.fromSAN(sanMove, this)); } /** diff --git a/src/dev/kske/chess/board/Move.java b/src/dev/kske/chess/board/Move.java index a03a78c..6196cdf 100644 --- a/src/dev/kske/chess/board/Move.java +++ b/src/dev/kske/chess/board/Move.java @@ -1,6 +1,12 @@ package dev.kske.chess.board; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import dev.kske.chess.board.Piece.Color; /** * Project: Chess
@@ -53,6 +59,96 @@ public class Move { public String toLAN() { return getPos().toLAN() + getDest().toLAN(); } + /** + * Converts a move string from standard algebraic notation to a {@link Move} + * object. + * + * @param sanMove the move string to convert from + * @param board the board on which the move has to be executed + * @return the converted {@link Move} object + */ + public static Move fromSAN(String sanMove, Board board) { + Map patterns = new HashMap<>(); + patterns.put("pieceMove", + Pattern.compile( + "^(?[NBRQK])(?:(?[a-h])|(?[1-8])|(?[a-h][1-8]))?x?(?[a-h][1-8])(?:\\+{0,2}|\\#)$")); + patterns.put("pawnCapture", + Pattern.compile("^(?[a-h])(?[1-8])?x(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)?$")); + patterns.put("pawnPush", Pattern.compile("^(?[a-h][1-8])(?[NBRQ])?(?:\\+{0,2}|\\#)$")); + patterns.put("castling", Pattern.compile("^(?O-O-O)|(?O-O)(?:\\+{0,2}|\\#)?$")); + + for (Map.Entry entry : patterns.entrySet()) { + Matcher m = entry.getValue().matcher(sanMove); + if (m.find()) { + Position pos = null, dest = null; + Move move = null; + switch (entry.getKey()) { + case "pieceMove": + dest = Position.fromLAN(m.group("toSquare")); + if (m.group("fromSquare") != null) pos = Position.fromLAN(m.group("fromSquare")); + else { + Class pieceClass = Piece.fromFirstChar(m.group("pieceType").charAt(0)); + char file; + int rank; + if (m.group("fromFile") != null) { + file = m.group("fromFile").charAt(0); + rank = board.get(pieceClass, file); + pos = Position.fromLAN(String.format("%c%d", file, rank)); + } else if (m.group("fromRank") != null) { + rank = Integer.parseInt(m.group("fromRank").substring(0, 1)); + file = board.get(pieceClass, rank); + pos = Position.fromLAN(String.format("%c%d", file, rank)); + } else pos = board.get(pieceClass, dest); + } + move = new Move(pos, dest); + break; + case "pawnCapture": + char file = m.group("fromFile").charAt(0); + int rank = m.group("fromRank") == null ? board.get(Pawn.class, file) : Integer.parseInt(m.group("fromRank")); + + dest = Position.fromLAN(m.group("toSquare")); + pos = Position.fromLAN(String.format("%c%d", file, rank)); + + if (m.group("promotedTo") != null) { + try { + move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0))); + } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) { + e.printStackTrace(); + } + } else move = new Move(pos, dest); + break; + case "pawnPush": + dest = Position.fromLAN(m.group("toSquare")); + int step = board.getLog().getActiveColor() == Color.WHITE ? 1 : -1; + + // One step forward + if (board.getBoardArr()[dest.x][dest.y + step] != null) pos = new Position(dest.x, dest.y + step); + + // Double step forward + else pos = new Position(dest.x, dest.y + 2 * step); + + if (m.group("promotedTo") != null) { + try { + move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0))); + } catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) { + e.printStackTrace(); + } + } else move = new Move(pos, dest); + break; + case "castling": + pos = new Position(4, board.getLog().getActiveColor() == Color.WHITE ? 7 : 0); + dest = new Position(m.group("kingside") != null ? 6 : 2, pos.y); + move = new Castling(pos, dest); + break; + } + return move; + } + } + return null; + } + + public String toSAN(Board board) { return null; } + public boolean isHorizontal() { return getyDist() == 0; } public boolean isVertical() { return getxDist() == 0; }