package com.christophdietze.jack.shared.pgn;
import com.christophdietze.jack.shared.board.Piece;
import com.christophdietze.jack.shared.board.Position;
/**
* @see http://en.wikipedia.org/wiki/Forsyth-Edwards_Notation
*/
public class FenWriter {
public FenWriter() {
}
public String write(Position position) {
StringBuilder sb = new StringBuilder();
writePosition(position, sb);
sb.append(' ');
sb.append(position.isWhiteToMove() ? 'w' : 'b');
sb.append(' ');
writeCastleAvailabitity(position, sb);
sb.append(' ');
writeEnPassantAvailability(position, sb);
sb.append(' ');
sb.append(position.getHalfmoveClock());
sb.append(' ');
sb.append(position.getFullmoveNumber());
return sb.toString();
}
private void writePosition(Position position, StringBuilder sb) {
int skipCount = 0;
for (int y = 0; y < 8; ++y) {
if (y != 0) {
if (skipCount > 0) {
sb.append(skipCount);
skipCount = 0;
}
sb.append("/");
}
for (int x = 0; x < 8; ++x) {
int index = (7 - y) * 8 + x;
Piece square = position.getPiece(index);
if (square.isEmpty()) {
skipCount++;
} else {
if (skipCount > 0) {
sb.append(skipCount);
skipCount = 0;
}
char symbol = square.getPieceType().getSymbol();
if (!square.isWhite()) {
symbol = Character.toLowerCase(symbol);
}
sb.append(symbol);
}
}
}
if (skipCount > 0) {
sb.append(skipCount);
skipCount = 0;
}
}
private void writeCastleAvailabitity(Position position, StringBuilder sb) {
boolean empty = true;
if (position.canWhiteCastleKingside()) {
sb.append('K');
empty = false;
}
if (position.canWhiteCastleQueenside()) {
sb.append('Q');
empty = false;
}
if (position.canBlackCastleKingside()) {
sb.append('k');
empty = false;
}
if (position.canBlackCastleQueenside()) {
sb.append('q');
empty = false;
}
if (empty) {
sb.append('-');
}
}
private void writeEnPassantAvailability(Position position, StringBuilder sb) {
int startIndex = position.isWhiteToMove() ? 5 * 8 : 2 * 8;
Piece square = position.isWhiteToMove() ? Piece.BLACK_EN_PASSANT_PAWN : Piece.WHITE_EN_PASSANT_PAWN;
for (int offset = 0; offset < 8; ++offset) {
int index = startIndex + offset;
if (position.getPiece(index) == square) {
sb.append((char) ('a' + offset));
sb.append(position.isWhiteToMove() ? '6' : '3');
return;
}
}
sb.append('-');
}
}