package dev.kske.chess.board; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Objects; import dev.kske.chess.board.Piece.Color; /** * Project: Chess
* File: PawnPromotion.java
* Created: 2 Nov 2019
* * @since Chess v0.5-alpha * @author Kai S. K. Engelbart */ public class PawnPromotion extends Move { private final Constructor promotionPieceConstructor; private final char promotionPieceChar; /** * Initializes a pawn promotion move. * * @param pos the position of this move * @param dest the destination of this move * @param promotionPieceClass the class of the piece to which the pawn is * promoted * @throws ReflectiveOperationException if the promotion piece could not be * instantiated * @throws RuntimeException if the promotion piece could not be * instantiated */ public PawnPromotion( Position pos, Position dest, Class promotionPieceClass ) throws ReflectiveOperationException, RuntimeException { super(pos, dest); // Cache piece constructor promotionPieceConstructor = promotionPieceClass .getDeclaredConstructor(Color.class, Board.class); promotionPieceConstructor.setAccessible(true); // Get piece char promotionPieceChar = (char) promotionPieceClass.getMethod("firstChar") .invoke(promotionPieceConstructor.newInstance(null, null)); } /** * Creates an instance of {@link PawnPromotion}. * * @param xPos the horizontal position of this move * @param yPos the vertical position of this move * @param xDest the horizontal destination of this move * @param yDest the vertical destination of this move * @param promotionPieceClass the class of the piece to which the pawn is * promoted * @throws ReflectiveOperationException if the promotion piece could not be * instantiated * @throws RuntimeException if the promotion piece could not be * instantiated */ public PawnPromotion( int xPos, int yPos, int xDest, int yDest, Class promotionPieceClass ) throws ReflectiveOperationException, RuntimeException { this( new Position(xPos, yPos), new Position(xDest, yDest), promotionPieceClass ); } @Override public void execute(Board board) { try { board.set( pos, promotionPieceConstructor.newInstance(board.get(pos).getColor(), board) ); super.execute(board); } catch ( InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e ) { e.printStackTrace(); } } @Override public void revert(Board board, Piece capturedPiece) { board.set(dest, new Pawn(board.get(dest).getColor(), board)); super.revert(board, capturedPiece); } @Override public String toLAN() { return pos.toLAN() + dest.toLAN() + promotionPieceChar; } @Override public String toSAN(Board board) { String san = super.toSAN(board); return san + Character.toUpperCase(promotionPieceChar); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + Objects.hash(promotionPieceChar, promotionPieceConstructor); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (!(obj instanceof PawnPromotion)) return false; PawnPromotion other = (PawnPromotion) obj; return promotionPieceChar == other.promotionPieceChar && Objects .equals(promotionPieceConstructor, other.promotionPieceConstructor); } }