barrysw19.calculon.notation.FENUtils.java Source code

Java tutorial

Introduction

Here is the source code for barrysw19.calculon.notation.FENUtils.java

Source

/**
 * Calculon - A Java chess-engine.
 *
 * Copyright (C) 2008-2009 Barry Smith
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package barrysw19.calculon.notation;

import barrysw19.calculon.engine.BitBoard;
import barrysw19.calculon.engine.EngineUtils;
import barrysw19.calculon.model.Piece;
import org.apache.commons.lang.StringUtils;

public class FENUtils {
    private static final String FILES = "abcdefgh";

    public static String generate(BitBoard bitBoard) {
        StringBuilder fen = new StringBuilder();
        fen.append(generatePosition(bitBoard));

        fen.append(" ").append(bitBoard.getPlayer() == Piece.WHITE ? "w" : "b");
        fen.append(" ").append(generateCastling(bitBoard));
        fen.append(" ").append(generateEnPassant(bitBoard));
        fen.append(" ").append(bitBoard.getHalfMoveCount());
        fen.append(" ").append(bitBoard.getMoveNumber());

        return fen.toString();
    }

    public static String generateWithoutMoveCounts(BitBoard bitBoard) {
        StringBuilder fen = new StringBuilder();
        fen.append(generatePosition(bitBoard));

        fen.append(" ").append(bitBoard.getPlayer() == Piece.WHITE ? "w" : "b");
        fen.append(" ").append(generateCastling(bitBoard));
        fen.append(" ").append(generateEnPassant(bitBoard));

        return fen.toString();
    }

    public static String generateEnPassant(BitBoard board) {

        if (!board.isEnPassant()) {
            return "-";
        }

        StringBuilder fen = new StringBuilder();
        fen.append(Character.toLowerCase(EngineUtils.FILES.charAt(board.getEnPassantFile())));
        fen.append(EngineUtils.RANKS.charAt(board.getEnPassantRank()));

        return fen.toString();
    }

    public static String generateCastling(BitBoard board) {
        StringBuilder fen = new StringBuilder();

        if ((board.getCastlingOptions() & BitBoard.CASTLE_WKS) != 0) {
            fen.append("K");
        }
        if ((board.getCastlingOptions() & BitBoard.CASTLE_WQS) != 0) {
            fen.append("Q");
        }
        if ((board.getCastlingOptions() & BitBoard.CASTLE_BKS) != 0) {
            fen.append("k");
        }
        if ((board.getCastlingOptions() & BitBoard.CASTLE_BQS) != 0) {
            fen.append("q");
        }
        if (fen.length() == 0) {
            fen.append("-");
        }

        return fen.toString();
    }

    public static String generatePosition(BitBoard board) {
        StringBuilder fen = new StringBuilder();

        for (int rank = 7; rank >= 0; rank--) {
            int emptyCount = 0;
            for (int file = 0; file < 8; file++) {
                long pos = 1L << (rank << 3) << file;
                String symbol = getSymbol((byte) (((board.getBitmapBlack() & pos) == 0 ? Piece.WHITE : Piece.BLACK)
                        | board.getPiece(pos)));
                if (symbol == null) {
                    emptyCount++;
                } else {
                    if (emptyCount > 0) {
                        fen.append(emptyCount);
                        emptyCount = 0;
                    }
                    fen.append(symbol);
                }
            }
            if (emptyCount > 0) {
                fen.append(emptyCount);
            }
            if (rank > 0) {
                fen.append("/");
            }
        }

        return fen.toString();
    }

    static String getSymbol(byte piece) {

        byte pieceType = EngineUtils.getType(piece);

        if (pieceType == Piece.EMPTY) {
            return null;
        }

        String symbol = null;
        if (pieceType == Piece.PAWN) {
            symbol = "p";
        } else if (pieceType == Piece.KNIGHT) {
            symbol = "n";
        } else if (pieceType == Piece.BISHOP) {
            symbol = "b";
        } else if (pieceType == Piece.ROOK) {
            symbol = "r";
        } else if (pieceType == Piece.QUEEN) {
            symbol = "q";
        } else if (pieceType == Piece.KING) {
            symbol = "k";
        }

        if (EngineUtils.getColor(piece) == Piece.BLACK) {
            return symbol;
        } else {
            return symbol != null ? symbol.toUpperCase() : null;
        }
    }

    public static BitBoard loadPosition(String string, BitBoard board) {
        board.clear();
        String[] fields = StringUtils.split(string);
        String[] ranks = StringUtils.split(fields[0], '/');

        for (int rank = 7; rank >= 0; rank--) {
            int file = 0;
            for (int j = 0; j < ranks[7 - rank].length(); j++) {
                char c = ranks[7 - rank].charAt(j);
                switch (c) {
                case 'P':
                    board.setPiece(file, rank, (byte) (Piece.PAWN | Piece.WHITE));
                    break;
                case 'p':
                    board.setPiece(file, rank, (byte) (Piece.PAWN | Piece.BLACK));
                    break;
                case 'R':
                    board.setPiece(file, rank, (byte) (Piece.ROOK | Piece.WHITE));
                    break;
                case 'r':
                    board.setPiece(file, rank, (byte) (Piece.ROOK | Piece.BLACK));
                    break;
                case 'N':
                    board.setPiece(file, rank, (byte) (Piece.KNIGHT | Piece.WHITE));
                    break;
                case 'n':
                    board.setPiece(file, rank, (byte) (Piece.KNIGHT | Piece.BLACK));
                    break;
                case 'B':
                    board.setPiece(file, rank, (byte) (Piece.BISHOP | Piece.WHITE));
                    break;
                case 'b':
                    board.setPiece(file, rank, (byte) (Piece.BISHOP | Piece.BLACK));
                    break;
                case 'Q':
                    board.setPiece(file, rank, (byte) (Piece.QUEEN | Piece.WHITE));
                    break;
                case 'q':
                    board.setPiece(file, rank, (byte) (Piece.QUEEN | Piece.BLACK));
                    break;
                case 'K':
                    board.setPiece(file, rank, (byte) (Piece.KING | Piece.WHITE));
                    break;
                case 'k':
                    board.setPiece(file, rank, (byte) (Piece.KING | Piece.BLACK));
                    break;
                }
                if (c >= '1' && c <= '8') {
                    file += c - '1';
                }
                file++;
            }
        }

        board.setPlayer("b".equals(fields[1]) ? Piece.BLACK : Piece.WHITE);
        board.setCastlingOptions((byte) ((fields[2].contains("K") ? BitBoard.CASTLE_WKS : 0)
                | (fields[2].contains("Q") ? BitBoard.CASTLE_WQS : 0)
                | (fields[2].contains("k") ? BitBoard.CASTLE_BKS : 0)
                | (fields[2].contains("q") ? BitBoard.CASTLE_BQS : 0)));

        if (fields[3].length() == 2) {
            board.setEnPassantFile(FILES.indexOf(fields[3].charAt(0)));
        } else {
            board.setEnPassantFile(-1);
        }
        board.setMoveNumber(Short.parseShort(fields[5]));

        return board;
    }

    public static BitBoard getBoard(String fen) {
        BitBoard board = new BitBoard();
        loadPosition(fen, board);
        return board;
    }
}