package com.christophdietze.jack.shared.pgn;
import com.christophdietze.jack.shared.board.Piece;
import com.christophdietze.jack.shared.board.PieceType;
import com.christophdietze.jack.shared.board.Position;
/**
* Parser for a reduced version of FEN. The differences are:
* <ul>
* <li>Only the position is stored. Meta info such as e.p., castles, etc. is omitted.</li>
* <li>The seperator '/' is omitted.</li>
* <li>It starts from a1 instead of a8.</li>
* <li>Any consecutive numbers are replaced by their sum.</li>
* <li>A trailing number is omitted.</li>
* </ul>
* E.g. 'RNBQKBNRPPPPPPPP32pppppppprnbqkbnr' is the initial position.
*/
public class ReducedFenParser {
private Position.Builder builder;
private String inputString;
public ReducedFenParser() {
}
public void parse(String inputString) throws ReducedFenParsingException {
this.inputString = inputString;
builder = new Position.Builder();
parsePosition();
}
public Position getPosition() {
return builder.build();
}
private void parsePosition() throws ReducedFenParsingException {
int skipCount = 0;
int index = 0;
for (char ch : inputString.toCharArray()) {
if (ch >= '0' && ch <= '9') {
skipCount *= 10;
skipCount += ch - '0';
continue;
}
if (skipCount > 0) {
index += skipCount;
skipCount = 0;
}
boolean isWhite;
if (Character.isUpperCase(ch)) {
isWhite = true;
} else {
isWhite = false;
ch = Character.toUpperCase(ch);
}
PieceType piece = PieceType.getBySymbol(ch);
if (piece == null) {
throw new ReducedFenParsingException("Unrecognized symbol '" + ch + "'");
}
Piece square = Piece.getFromColorAndPieceType(isWhite, piece);
if (index > 63) {
throw new ReducedFenParsingException("Input too long");
}
builder.piece(index, square);
index++;
}
}
}