Working on SAN serialization of moves
+ SAN generation for castling moves + Appending promotion piece symbol in pawn promotion SAN + Asking the user to view a generated PGN file
This commit is contained in:
parent
6cb0da80d7
commit
4cb6e0e08b
@ -32,4 +32,13 @@ public class Castling extends Move {
|
||||
super.revert(board, capturedPiece);
|
||||
rookMove.revert(board, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code O-O-O} for a queenside castling or {@code O-O} for a kingside
|
||||
* castling
|
||||
*/
|
||||
@Override
|
||||
public String toSAN(Board board) {
|
||||
return rookMove.pos.x == 0 ? "O-O-O" : "O-O";
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class Move {
|
||||
if (move.length() == 5) {
|
||||
try {
|
||||
return new PawnPromotion(pos, dest, Piece.fromFirstChar(move.charAt(4)));
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
@ -112,7 +112,7 @@ public class Move {
|
||||
if (m.group("promotedTo") != null) {
|
||||
try {
|
||||
move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0)));
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else move = new Move(pos, dest);
|
||||
@ -130,7 +130,7 @@ public class Move {
|
||||
if (m.group("promotedTo") != null) {
|
||||
try {
|
||||
move = new PawnPromotion(pos, dest, Piece.fromFirstChar(m.group("promotedTo").charAt(0)));
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else move = new Move(pos, dest);
|
||||
@ -147,7 +147,27 @@ public class Move {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toSAN(Board board) { return null; }
|
||||
public String toSAN(Board board) {
|
||||
final Piece piece = board.get(pos);
|
||||
StringBuilder sb = new StringBuilder(8);
|
||||
|
||||
// Piece symbol
|
||||
if(!(piece instanceof Pawn))
|
||||
sb.append(Character.toUpperCase(piece.firstChar()));
|
||||
|
||||
// Position
|
||||
// TODO: Deconstruct position into optional file or rank
|
||||
// TODO: Omit if the move is a pawn push
|
||||
sb.append(pos.toLAN());
|
||||
|
||||
// Capture indicator
|
||||
if (board.get(dest) != null) sb.append('x');
|
||||
|
||||
// Destination
|
||||
sb.append(dest.toLAN());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean isHorizontal() { return getyDist() == 0; }
|
||||
|
||||
|
@ -74,7 +74,7 @@ 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 | IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else moves.add(move);
|
||||
|
@ -16,21 +16,23 @@ import dev.kske.chess.board.Piece.Color;
|
||||
*/
|
||||
public class PawnPromotion extends Move {
|
||||
|
||||
private final Class<? extends Piece> promotionPieceClass;
|
||||
private final Constructor<? extends Piece> promotionPieceConstructor;
|
||||
private final char promotionPieceChar;
|
||||
|
||||
public PawnPromotion(Position pos, Position dest, Class<? extends Piece> promotionPieceClass) throws NoSuchMethodException, SecurityException {
|
||||
public PawnPromotion(Position pos, Position dest, Class<? extends Piece> promotionPieceClass)
|
||||
throws ReflectiveOperationException, RuntimeException {
|
||||
super(pos, dest);
|
||||
this.promotionPieceClass = promotionPieceClass;
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
public PawnPromotion(int xPos, int yPos, int xDest, int yDest, Class<? extends Piece> promotionPiece)
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
|
||||
InstantiationException {
|
||||
throws ReflectiveOperationException, RuntimeException {
|
||||
this(new Position(xPos, yPos), new Position(xDest, yDest), promotionPiece);
|
||||
}
|
||||
|
||||
@ -51,22 +53,19 @@ public class PawnPromotion extends Move {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toLAN() {
|
||||
char promotionPieceChar = '-';
|
||||
try {
|
||||
promotionPieceChar = (char) promotionPieceClass.getMethod("firstChar").invoke(promotionPieceConstructor.newInstance(null, null));
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException
|
||||
| InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return pos.toLAN() + dest.toLAN() + promotionPieceChar;
|
||||
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(promotionPieceClass);
|
||||
result = prime * result + Objects.hash(promotionPieceChar, promotionPieceConstructor);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -74,8 +73,8 @@ public class PawnPromotion extends Move {
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!super.equals(obj)) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
if (!(obj instanceof PawnPromotion)) return false;
|
||||
PawnPromotion other = (PawnPromotion) obj;
|
||||
return Objects.equals(promotionPieceClass, other.promotionPieceClass);
|
||||
return promotionPieceChar == other.promotionPieceChar && Objects.equals(promotionPieceConstructor, other.promotionPieceConstructor);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dev.kske.chess.ui;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.dnd.DropTarget;
|
||||
@ -168,7 +169,6 @@ public class MainWindow extends JFrame {
|
||||
|
||||
public void saveFile(File file) {
|
||||
final int dotIndex = file.getName().lastIndexOf('.');
|
||||
final String name = file.getName().substring(0, dotIndex);
|
||||
final String extension = file.getName().substring(dotIndex).toLowerCase();
|
||||
|
||||
if (extension.equals(".pgn")) try {
|
||||
@ -178,6 +178,12 @@ public class MainWindow extends JFrame {
|
||||
PGNDatabase pgnDB = new PGNDatabase();
|
||||
pgnDB.getGames().add(pgnGame);
|
||||
pgnDB.save(file);
|
||||
|
||||
if (JOptionPane.showConfirmDialog(this,
|
||||
"Game export finished. Do you want to view the created file?",
|
||||
"Game export finished",
|
||||
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
|
||||
Desktop.getDesktop().open(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
JOptionPane.showMessageDialog(this,
|
||||
|
Reference in New Issue
Block a user