/** Score castling ability. */ private int castleBonus(Position pos) { if (pos.getCastleMask() == 0) return 0; int k1 = kt1b[7*8+6] - kt1b[7*8+4]; int k2 = kt2b[7*8+6] - kt2b[7*8+4]; int t1 = qV + 2 * rV + 2 * bV; int t2 = rV; int t = pos.bMtrl - pos.bMtrlPawns; int ks = interpolate(t, t2, k2, t1, k1); int castleValue = ks + rt1b[7*8+5] - rt1b[7*8+7]; if (castleValue <= 0) return 0; ulong occupied = pos.whiteBB | pos.blackBB; int tmp = (int) (occupied & 0x6E); if (pos.a1Castle()) tmp |= 1; if (pos.h1Castle()) tmp |= (1 << 7); int wBonus = (castleValue * castleFactor[tmp]) >> 10; tmp = (int) ((occupied >> 56) & 0x6E); if (pos.a8Castle()) tmp |= 1; if (pos.h8Castle()) tmp |= (1 << 7); int bBonus = (castleValue * castleFactor[tmp]) >> 10; return wBonus - bBonus; }
/** Return a FEN string corresponding to a chess Position object. */ public static string toFEN(Position pos) { string ret = ""; // Piece placement for (int r = 7; r >=0; r--) { int numEmpty = 0; for (int c = 0; c < 8; c++) { int p = pos.getPiece(Position.getSquare(c, r)); if (p == Piece.EMPTY) { numEmpty++; } else { if (numEmpty > 0) { ret+=numEmpty.ToString(); numEmpty = 0; } switch (p) { case Piece.WKING: ret+=('K'); break; case Piece.WQUEEN: ret+=('Q'); break; case Piece.WROOK: ret+=('R'); break; case Piece.WBISHOP: ret+=('B'); break; case Piece.WKNIGHT: ret+=('N'); break; case Piece.WPAWN: ret+=('P'); break; case Piece.BKING: ret+=('k'); break; case Piece.BQUEEN: ret+=('q'); break; case Piece.BROOK: ret+=('r'); break; case Piece.BBISHOP: ret+=('b'); break; case Piece.BKNIGHT: ret+=('n'); break; case Piece.BPAWN: ret+=('p'); break; default: throw new RuntimeException(); } } } if (numEmpty > 0) { ret += numEmpty.ToString(); } if (r > 0) { ret += ('/'); } } ret += (pos.whiteMove ? " w " : " b "); // Castling rights bool anyCastle = false; if (pos.h1Castle()) { ret += ('K'); anyCastle = true; } if (pos.a1Castle()) { ret += ('Q'); anyCastle = true; } if (pos.h8Castle()) { ret += ('k'); anyCastle = true; } if (pos.a8Castle()) { ret += ('q'); anyCastle = true; } if (!anyCastle) { ret += ('-'); } // En passant target square { ret += (' '); if (pos.getEpSquare() >= 0) { int x = Position.getX(pos.getEpSquare()); int y = Position.getY(pos.getEpSquare()); ret += ((char)(x + 'a')); ret += ((char)(y + '1')); } else { ret += ('-'); } } // Move counters ret += " " + pos.halfMoveClock; ret += " " + pos.fullMoveCounter; return ret; }