Exemplo n.º 1
0
 /** Remove pseudo-legal EP square if it is not legal, ie would leave king in check. */
 public static void fixupEPSquare(Position pos)
 {
     int epSquare = pos.getEpSquare();
     if (epSquare >= 0) {
     MoveGen MG = new MoveGen();
     MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
     MoveGen.RemoveIllegal(pos, moves);
     bool epValid = false;
     for (int mi = 0; mi < moves.size; mi++) {
         Move m = moves.m[mi];
         if (m.to == epSquare) {
             if (pos.getPiece(m.from) == (pos.whiteMove ? Piece.WPAWN : Piece.BPAWN)) {
                 epValid = true;
                 break;
             }
         }
     }
     if (!epValid) {
         pos.setEpSquare(-1);
     }
     }
 }
Exemplo n.º 2
0
        /*throws ChessParseError*/
        /** Parse a FEN string and return a chess Position object. */
        public static Position readFEN(string fen)
        {
            Position pos = new Position();
            string[] words = fen.Split(' ');
            if (words.Length < 2) {
            throw new ChessParseError(/* "Too few pieces " */);
            }

            // Piece placement
            int row = 7;
            int col = 0;
            for (int i = 0; i < words[0].Length; i++) {
            char c = words[0][i];
            switch (c) {
                case '1': col += 1; break;
                case '2': col += 2; break;
                case '3': col += 3; break;
                case '4': col += 4; break;
                case '5': col += 5; break;
                case '6': col += 6; break;
                case '7': col += 7; break;
                case '8': col += 8; break;
                case '/': row--; col = 0; break;
                case 'P': safeSetPiece(pos, col, row, Piece.WPAWN);   col++; break;
                case 'N': safeSetPiece(pos, col, row, Piece.WKNIGHT); col++; break;
            case 'B': safeSetPiece(pos, col, row, Piece.WBISHOP); col++; break;
            case 'R': safeSetPiece(pos, col, row, Piece.WROOK);   col++; break;
            case 'Q': safeSetPiece(pos, col, row, Piece.WQUEEN);  col++; break;
            case 'K': safeSetPiece(pos, col, row, Piece.WKING);   col++; break;
            case 'p': safeSetPiece(pos, col, row, Piece.BPAWN);   col++; break;
            case 'n': safeSetPiece(pos, col, row, Piece.BKNIGHT); col++; break;
            case 'b': safeSetPiece(pos, col, row, Piece.BBISHOP); col++; break;
            case 'r': safeSetPiece(pos, col, row, Piece.BROOK);   col++; break;
            case 'q': safeSetPiece(pos, col, row, Piece.BQUEEN);  col++; break;
            case 'k': safeSetPiece(pos, col, row, Piece.BKING);   col++; break;
                default: throw new ChessParseError(/* "Invalid piece" */);
            }
            }
            if (words[1].Length == 0) {
            throw new ChessParseError(/*"Invalid side"*/);
            }
            pos.setWhiteMove(words[1][0] == 'w');

            // Castling rights
            int castleMask = 0;
            if (words.Length > 2) {
            for (int i = 0; i < words[2].Length; i++) {
                char c = words[2][i];
                switch (c) {
                    case 'K':
                        castleMask |= (1 << Position.H1_CASTLE);
                        break;
                    case 'Q':
                        castleMask |= (1 << Position.A1_CASTLE);
                        break;
                    case 'k':
                        castleMask |= (1 << Position.H8_CASTLE);
                        break;
                    case 'q':
                        castleMask |= (1 << Position.A8_CASTLE);
                        break;
                    case '-':
                        break;
                    default:
                        throw new ChessParseError(/* "Invalid castling flags" */);
                }
            }
            }
            pos.setCastleMask(castleMask);

            if (words.Length > 3) {
            // En passant target square
            string epstring = words[3];
            if (epstring != "-") {
                if (epstring.Length < 2) {
                    throw new ChessParseError(/* "Invalid en passant square" */);
                }
                pos.setEpSquare(getSquare(epstring));
            }
            }

            try {
            if (words.Length > 4) {
                pos.halfMoveClock = int.Parse(words[4]);
            }
            if (words.Length > 5) {
                pos.fullMoveCounter = int.Parse(words[5]);
            }
            } catch (NumberFormatException nfe) {
            // Ignore errors here, since the fields are optional
            }

            // Each side must have exactly one king
            int wKings = 0;
            int bKings = 0;
            for (int x = 0; x < 8; x++) {
            for (int y = 0; y < 8; y++) {
                int p = pos.getPiece(Position.getSquare(x, y));
                if (p == Piece.WKING) {
                    wKings++;
                } else if (p == Piece.BKING) {
                    bKings++;
                }
            }
            }
            if (wKings != 1) {
            throw new ChessParseError(/* "White must have exactly one king" */);
            }
            if (bKings != 1) {
            throw new ChessParseError(/* "Black must have exactly one king" */);
            }

            // Make sure king can not be captured
            Position pos2 = new Position(pos);
            pos2.setWhiteMove(!pos.whiteMove);
            if (MoveGen.inCheck(pos2)) {
            throw new ChessParseError(/* "King capture possible" */);
            }

            fixupEPSquare(pos);

            return pos;
        }