From e92664dd070957fc7237beb9c80af71e7a1b642a Mon Sep 17 00:00:00 2001 From: kske Date: Mon, 4 Nov 2019 18:11:23 +0100 Subject: [PATCH] Added pawn promotion support to LAN --- src/dev/kske/chess/board/Board.java | 29 ++++++++++++++++----- src/dev/kske/chess/board/Move.java | 18 ++++++++++--- src/dev/kske/chess/board/Pawn.java | 4 ++- src/dev/kske/chess/board/PawnPromotion.java | 19 +++++++++++--- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/dev/kske/chess/board/Board.java b/src/dev/kske/chess/board/Board.java index d6c440f..997326b 100644 --- a/src/dev/kske/chess/board/Board.java +++ b/src/dev/kske/chess/board/Board.java @@ -1,5 +1,6 @@ package dev.kske.chess.board; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -133,25 +134,39 @@ public class Board { move = new Move(pos, dest); break; case "pawnCapture": - dest = Position.fromLAN(m.group("toSquare")); char file = m.group("fromFile").charAt(0); int rank = m.group("fromRank") == null ? get(Pawn.class, file) : Integer.parseInt(m.group("fromRank")); - pos = Position.fromLAN(String.format("%c%d", file, rank)); - if (m.group("promotedTo") != null) { - } - move = new Move(pos, dest); + 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 | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | InstantiationException e) { + e.printStackTrace(); + } + } else move = new Move(pos, dest); break; case "pawnPush": dest = Position.fromLAN(m.group("toSquare")); - // TODO: Pawn promotion 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); - move = new Move(pos, dest); + + if (m.group("promotedTo") != null) { + try { + move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0))); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | InstantiationException e) { + e.printStackTrace(); + } + } else move = new Move(pos, dest); break; case "castling": pos = new Position(4, log.getActiveColor() == Color.WHITE ? 7 : 0); diff --git a/src/dev/kske/chess/board/Move.java b/src/dev/kske/chess/board/Move.java index f71cf37..e016246 100644 --- a/src/dev/kske/chess/board/Move.java +++ b/src/dev/kske/chess/board/Move.java @@ -1,5 +1,6 @@ package dev.kske.chess.board; +import java.lang.reflect.InvocationTargetException; import java.util.Objects; /** @@ -26,9 +27,6 @@ public class Move { public Move(int xPos, int yPos, int xDest, int yDest) { this(new Position(xPos, yPos), new Position(xDest, yDest)); } - // TODO: Pawn promotion - public static Move fromLAN(String move) { return new Move(Position.fromLAN(move.substring(0, 2)), Position.fromLAN(move.substring(2))); } - public void execute(Board board) { // Move the piece to the move's destination square and clean the old position board.set(dest, board.get(pos)); @@ -41,6 +39,20 @@ public class Move { board.set(dest, capturedPiece); } + public static Move fromLAN(String move) { + Position pos = Position.fromLAN(move.substring(0, 2)); + Position dest = Position.fromLAN(move.substring(2)); + if (move.length() == 5) { + try { + return new PawnPromotion(pos, dest, Piece.fromFirstChar(move.charAt(4))); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException e) { + e.printStackTrace(); + return null; + } + } else return new Move(pos, dest); + } + public String toLAN() { return getPos().toLAN() + getDest().toLAN(); } public boolean isHorizontal() { return getyDist() == 0; } diff --git a/src/dev/kske/chess/board/Pawn.java b/src/dev/kske/chess/board/Pawn.java index 177abba..eb048ad 100644 --- a/src/dev/kske/chess/board/Pawn.java +++ b/src/dev/kske/chess/board/Pawn.java @@ -1,5 +1,6 @@ package dev.kske.chess.board; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; @@ -74,7 +75,8 @@ public class Pawn extends Piece { moves.add(new PawnPromotion(pos, dest, Rook.class)); moves.add(new PawnPromotion(pos, dest, Knight.class)); moves.add(new PawnPromotion(pos, dest, Bishop.class)); - } catch (NoSuchMethodException | SecurityException e) { + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | InstantiationException e) { e.printStackTrace(); } } else moves.add(move); diff --git a/src/dev/kske/chess/board/PawnPromotion.java b/src/dev/kske/chess/board/PawnPromotion.java index f8fa22b..e2c6896 100644 --- a/src/dev/kske/chess/board/PawnPromotion.java +++ b/src/dev/kske/chess/board/PawnPromotion.java @@ -15,16 +15,24 @@ import dev.kske.chess.board.Piece.Color; */ public class PawnPromotion extends Move { - private Constructor promotionPieceConstructor; + private final Constructor promotionPieceConstructor; + private final char promotionPieceChar; - public PawnPromotion(Position pos, Position dest, Class promotionPiece) throws NoSuchMethodException, SecurityException { + public PawnPromotion(Position pos, Position dest, Class promotionPiece) throws NoSuchMethodException, SecurityException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { super(pos, dest); + + // Cache piece constructor promotionPieceConstructor = promotionPiece.getDeclaredConstructor(Color.class, Board.class); promotionPieceConstructor.setAccessible(true); + + // Cache piece first char + promotionPieceChar = (char) promotionPiece.getMethod("firstChar").invoke(promotionPieceConstructor.newInstance(null, null)); } public PawnPromotion(int xPos, int yPos, int xDest, int yDest, Class promotionPiece) - throws NoSuchMethodException, SecurityException { + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, + InstantiationException { this(new Position(xPos, yPos), new Position(xDest, yDest), promotionPiece); } @@ -40,7 +48,10 @@ public class PawnPromotion extends Move { @Override public void revert(Board board, Piece capturedPiece) { + board.set(dest, new Pawn(board.get(dest).getColor(), board)); super.revert(board, capturedPiece); - board.set(pos, new Pawn(board.get(dest).getColor(), board)); } + + @Override + public String toLAN() { return pos.toLAN() + dest.toLAN() + promotionPieceChar; } }