int isPawnSupported(S8 sq, S8 side) { int step; if (side == WHITE) step = SOUTH; else step = NORTH; if ( IS_SQ(sq+WEST) && isPiece(side,PAWN, sq + WEST) ) return 1; if ( IS_SQ(sq+EAST) && isPiece(side,PAWN, sq + EAST) ) return 1; if ( IS_SQ(sq+step+WEST) && isPiece(side,PAWN, sq + step+WEST ) ) return 1; if ( IS_SQ(sq+step+EAST) && isPiece(side,PAWN, sq + step+EAST ) ) return 1; return 0; }
void EvalQueen(S8 sq, S8 side) { v.gamePhase += 4; int att = 0; int mob = 0; /**************************************************************** * A queen should not be developed too early * ****************************************************************/ if (side == WHITE && ROW(sq) > ROW_2) { if (isPiece(WHITE, KNIGHT, B1)) v.PositionalThemes[WHITE] -= 2; if (isPiece(WHITE, BISHOP, C1)) v.PositionalThemes[WHITE] -= 2; if (isPiece(WHITE, BISHOP, F1)) v.PositionalThemes[WHITE] -= 2; if (isPiece(WHITE, KNIGHT, G1)) v.PositionalThemes[WHITE] -= 2; } if (side == BLACK && ROW(sq) < ROW_7) { if (isPiece(BLACK, KNIGHT, B8)) v.PositionalThemes[BLACK] -= 2; if (isPiece(BLACK, BISHOP, C8)) v.PositionalThemes[BLACK] -= 2; if (isPiece(BLACK, BISHOP, F8)) v.PositionalThemes[BLACK] -= 2; if (isPiece(BLACK, KNIGHT, G8)) v.PositionalThemes[BLACK] -= 2; } /**************************************************************** * Collect data about mobility and king attacks * ****************************************************************/ for (char dir=0;dir<vectors[QUEEN];dir++) { for (char pos = sq;;) { pos = pos + vector[QUEEN][dir]; if (! IS_SQ(pos)) break; if (b.pieces[pos] == PIECE_EMPTY) { mob++; if ( e.sqNearK[!side] [b.KingLoc[!side] ] [pos] ) ++att; } else if (b.color[pos] != side) { mob++; if ( e.sqNearK[!side] [b.KingLoc[!side] ] [pos] ) ++att; break; } else { break; } } } v.mgMob[side] += 1 * (mob-14); v.egMob[side] += 2 * (mob-14); if (att) { v.attCnt[side]++; v.attWeight[side] += 4*att; } }
int leaperAttack( char byColor, S8 sq, char byPiece ) { S8 nextSq; for ( int dir = 0; dir < 8; dir++ ) { nextSq = sq + vector[byPiece][dir]; if ( IS_SQ(nextSq) && isPiece( byColor, byPiece, nextSq ) ) return 1; } return 0; }
void blockedPieces() { // central pawn blocked, bishop hard to develop if (isPiece(WHITE, BISHOP, C1) && isPiece(WHITE, PAWN, D2) && b.color[D3] != COLOR_EMPTY) v.Blockages[WHITE] -= e.P_BLOCK_CENTRAL_PAWN; if (isPiece(WHITE, BISHOP, F1) && isPiece(WHITE, PAWN, E2) && b.color[E3] != COLOR_EMPTY) v.Blockages[WHITE] -= e.P_BLOCK_CENTRAL_PAWN; if (isPiece(BLACK, BISHOP, C8) && isPiece(BLACK, PAWN, D7) && b.color[D6] != COLOR_EMPTY) v.Blockages[BLACK] -= e.P_BLOCK_CENTRAL_PAWN; if (isPiece(BLACK, BISHOP, F8) && isPiece(BLACK, PAWN, E7) && b.color[E6] != COLOR_EMPTY) v.Blockages[BLACK] -= e.P_BLOCK_CENTRAL_PAWN; // uncastled king blocking own rook if ( ( isPiece(WHITE, KING, F1) || isPiece(WHITE, KING, G1 ) )&& ( isPiece(WHITE, ROOK, H1) || isPiece(WHITE, ROOK, G1 ) ) ) v.Blockages[WHITE] -= e.P_KING_BLOCKS_ROOK; if ( ( isPiece(WHITE, KING, C1) || isPiece(WHITE, KING, B1 ) )&& ( isPiece(WHITE, ROOK, A1) || isPiece(WHITE, ROOK, B1 ) ) ) v.Blockages[WHITE] -= e.P_KING_BLOCKS_ROOK; if ( ( isPiece(BLACK, KING, F8) || isPiece(BLACK, KING, G8 ) )&& ( isPiece(BLACK, ROOK, H8) || isPiece(BLACK, ROOK, G8 ) ) ) v.Blockages[BLACK] -= e.P_KING_BLOCKS_ROOK; if ( ( isPiece(BLACK, KING, C8) || isPiece(BLACK, KING, B8 ) )&& ( isPiece(BLACK, ROOK, A8) || isPiece(BLACK, ROOK, B8 ) ) ) v.Blockages[BLACK] -= e.P_KING_BLOCKS_ROOK; }
int EvalPawn(S8 sq, S8 side) { int result = 0; int flagIsPassed = 1; // we will be trying to disprove that int flagIsWeak = 1; // we will be trying to disprove that int flagIsOpposed = 0; int stepFwd, stepBck; if (side == WHITE) stepFwd = NORTH; else stepFwd = SOUTH; if (side == WHITE) stepBck = SOUTH; else stepBck = NORTH; S8 nextSq = sq + stepFwd; /************************************************************************* * We have only very basic data structures that do not update informa- * * tion about pawns incrementally, so we have to calculate everything * * here. The loop below detects doubled pawns, passed pawns and sets * * a flag on finding that our pawn is opposed by enemy pawn. * *************************************************************************/ while (IS_SQ(nextSq)) { if (b.pieces[nextSq] == PAWN) { // either opposed by enemy pawn or doubled flagIsPassed = 0; if (b.color[nextSq] == side) result -= 20; // doubled pawn penalty else flagIsOpposed = 1; // flag our pawn as opposed } if (IS_SQ(nextSq + WEST) && isPiece(!side, PAWN, nextSq + WEST)) flagIsPassed = 0; if (IS_SQ(nextSq + EAST) && isPiece(!side, PAWN, nextSq + EAST)) flagIsPassed = 0; nextSq += stepFwd; } /************************************************************************* * Another loop, going backwards and checking whether pawn has support. * * Here we can at least break out of it for speed optimization. * *************************************************************************/ nextSq = sq; while (IS_SQ(nextSq)) { if (IS_SQ(nextSq + WEST) && isPiece(side, PAWN, nextSq + WEST)) { flagIsWeak = 0; break; } if (IS_SQ(nextSq + EAST) && isPiece(side, PAWN, nextSq + EAST)) { flagIsWeak = 0; break; } nextSq += stepBck; } /************************************************************************* * Evaluate passed pawns, scoring them higher if they are protected * * or if their advance is supported by friendly pawns * *************************************************************************/ if ( flagIsPassed ) { if ( isPawnSupported(sq, side) ) result += e.protected_passer[side][sq]; else result += e.passed_pawn[side][sq]; } /************************************************************************* * Evaluate weak pawns, increasing the penalty if they are situated * * on a half-open file * *************************************************************************/ if ( flagIsWeak ) { result += e.weak_pawn[side][sq]; if (!flagIsOpposed) result -= 4; } return result; }
int bKingShield() { int result = 0; /* king on the kingside */ if ( COL(b.KingLoc[BLACK]) > COL_E ) { if ( isPiece(BLACK, PAWN, F7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, F6) ) result += e.SHIELD_2; if ( isPiece(BLACK, PAWN, G7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, G6) ) result += e.SHIELD_2; if ( isPiece(BLACK, PAWN, H7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, H6) ) result += e.SHIELD_2; } /* king on the queenside */ else if ( COL(b.KingLoc[BLACK]) < COL_D ) { if ( isPiece(BLACK, PAWN, A7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, A6) ) result += e.SHIELD_2; if ( isPiece(BLACK, PAWN, B7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, B6) ) result += e.SHIELD_2; if ( isPiece(BLACK, PAWN, C7) ) result += e.SHIELD_1; else if ( isPiece(BLACK, PAWN, C6) ) result += e.SHIELD_2; } return result; }
int wKingShield() { int result = 0; /* king on the kingside */ if ( COL(b.KingLoc[WHITE]) > COL_E ) { if ( isPiece(WHITE, PAWN, F2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, F3) ) result += e.SHIELD_2; if ( isPiece(WHITE, PAWN, G2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, G3) ) result += e.SHIELD_2; if ( isPiece(WHITE, PAWN, H2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, H3) ) result += e.SHIELD_2; } /* king on the queenside */ else if ( COL(b.KingLoc[WHITE]) < COL_D ) { if ( isPiece(WHITE, PAWN, A2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, A3) ) result += e.SHIELD_2; if ( isPiece(WHITE, PAWN, B2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, B3) ) result += e.SHIELD_2; if ( isPiece(WHITE, PAWN, C2) ) result += e.SHIELD_1; else if ( isPiece(WHITE, PAWN, C3) ) result += e.SHIELD_2; } return result; }
void EvalBishop(S8 sq, S8 side) { int att = 0; int mob = 0; v.gamePhase += 1; if (side == WHITE) { switch (sq) { case A7: if (isPiece(BLACK, PAWN, B6)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A7; break; case H7: if (isPiece(BLACK, PAWN, G6)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A7; break; case B8: if (isPiece(BLACK, PAWN, C7)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A7; break; case G8: if (isPiece(BLACK, PAWN, F7)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A7; break; case A6: if (isPiece(BLACK, PAWN, B5)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A6; break; case H6: if (isPiece(BLACK, PAWN, G5)) v.Blockages[WHITE] -= e.P_BISHOP_TRAPPED_A6; break; case F1: if (isPiece(WHITE, KING, G1)) v.PositionalThemes[WHITE] += e.RETURNING_BISHOP; break; case C1: if (isPiece(WHITE, KING, B1)) v.PositionalThemes[WHITE] += e.RETURNING_BISHOP; break; } } else { switch (sq) { case A2: if (isPiece(WHITE, PAWN, B3)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A7; break; case H2: if (isPiece(WHITE, PAWN, G3)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A7; break; case B1: if (isPiece(WHITE, PAWN, C2)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A7; break; case G1: if (isPiece(WHITE, PAWN, F2)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A7; break; case A3: if (isPiece(WHITE, PAWN, B4)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A6; break; case H3: if (isPiece(WHITE, PAWN, G4)) v.Blockages[BLACK] -= e.P_BISHOP_TRAPPED_A6; break; case F8: if (isPiece(BLACK, KING, G8)) v.PositionalThemes[BLACK] += e.RETURNING_BISHOP; break; case C8: if (isPiece(BLACK, KING, B8)) v.PositionalThemes[BLACK] += e.RETURNING_BISHOP; break; } } /**************************************************************** * Collect data about mobility and king attacks * ****************************************************************/ for (char dir=0;dir<vectors[BISHOP];dir++) { for (char pos = sq;;) { pos = pos + vector[BISHOP][dir]; if (! IS_SQ(pos)) break; if (b.pieces[pos] == PIECE_EMPTY) { mob++; if ( e.sqNearK[!side] [b.KingLoc[!side] ] [pos] ) ++att; } else if (b.color[pos] != side) { mob++; if ( e.sqNearK[!side] [b.KingLoc[!side] ] [pos] ) ++att; break; } else { break; } } } v.mgMob[side] += 3 * (mob-7); v.egMob[side] += 3 * (mob-7); if (att) { v.attCnt[side]++; v.attWeight[side] += 2*att; } }
void EvalKnight(S8 sq, S8 side) { int att = 0; int mob = 0; int pos; v.gamePhase += 1; if (side == WHITE) { switch (sq) { case A8: if (isPiece(BLACK, PAWN, A7) || isPiece(BLACK, PAWN, C7)) v.Blockages[WHITE] -= e.P_KNIGHT_TRAPPED_A8; break; case H8: if (isPiece(BLACK, PAWN, H7) || isPiece(BLACK, PAWN, F7)) v.Blockages[WHITE] -= e.P_KNIGHT_TRAPPED_A8; break; case A7: if (isPiece(BLACK, PAWN, A6) && isPiece(BLACK, PAWN, B7)) v.Blockages[WHITE] -= e.P_KNIGHT_TRAPPED_A7; break; case H7: if (isPiece(BLACK, PAWN, H6) && isPiece(BLACK, PAWN, G7)) v.Blockages[WHITE] -= e.P_KNIGHT_TRAPPED_A7; break; case C3: if (isPiece(WHITE, PAWN, C2) && isPiece(WHITE, PAWN, D4) && !isPiece(WHITE, PAWN, E4)) v.Blockages[WHITE] -= e.P_C3_KNIGHT; break; } } else { switch (sq) { case A1: if (isPiece(WHITE, PAWN, A2) || isPiece(WHITE, PAWN, C2)) v.Blockages[BLACK] -= e.P_KNIGHT_TRAPPED_A8; break; case H1: if (isPiece(WHITE, PAWN, H2) || isPiece(WHITE, PAWN, F2)) v.Blockages[BLACK] -= e.P_KNIGHT_TRAPPED_A8; break; case A2: if (isPiece(WHITE, PAWN, A3) && isPiece(WHITE, PAWN, B2)) v.Blockages[BLACK] -= e.P_KNIGHT_TRAPPED_A7; break; case H2: if (isPiece(WHITE, PAWN, H3) && isPiece(WHITE, PAWN, G2)) v.Blockages[BLACK] -= e.P_KNIGHT_TRAPPED_A7; break; case C6: if (isPiece(BLACK, PAWN, C7) && isPiece(BLACK, PAWN, D5) && !isPiece(BLACK, PAWN, E5)) v.Blockages[BLACK] -= e.P_C3_KNIGHT; break; } } /*************************************************************** * Material value adjustement based on the no. of own pawns. * * Knights lose value as pawns disappear. * ***************************************************************/ v.MaterialAdjustement[side] += knight_adj[b.PieceCount[side][PAWN]]; /**************************************************************** * Collect data about mobility and king attacks. This resembles * * move generation code, except that we are just incrementing * * the counters instead of adding actual moves. * ****************************************************************/ for (U8 dir=0;dir<8;dir++) { pos = sq + vector[KNIGHT][dir]; if ( IS_SQ(pos) && b.color[pos] != side ) { ++mob; if ( e.sqNearK[!side] [b.KingLoc[!side] ] [pos] ) ++att; // this knight is attacking zone around enemy king } } /**************************************************************** * Evaluate mobility. We try to do it in such a way * * that zero represents average mobility, but our * * formula of doing so is a puer guess. * ****************************************************************/ v.mgMob[side] += 4 * (mob-4); v.egMob[side] += 4 * (mob-4); /**************************************************************** * Save data about king attacks * ****************************************************************/ if (att) { v.attCnt[side]++; v.attWeight[side] += 2 * att; } }
void Board8x8::generateBlackPawnMoves(uint row, uint col, MoveList & moveList) { static const PieceType promotedPieceTypes[] = { BlackQueen, BlackRook, BlackBishop, BlackKnight }; uint sourceIndex = getIndex(row, col); std::list<uint> listMoves = mBlackPawnMoves[sourceIndex]; for (std::list<uint>::iterator itr = listMoves.begin(); itr != listMoves.end(); ++itr) { uint destIndex(*itr); uint destRow = destIndex >> 3; uint destCol = destIndex & 7; if (row == 1) { if (col == destCol) { if (mPieceType[(row-1)*8+col] == NoPiece) { for (int i = 0; i < 4; i++) { Move promoMove(row, col, destRow, destCol, NoPiece, promotedPieceTypes[i]); moveList.addMove(promoMove); } } } else { PieceType otherPiece = mPieceType[destIndex]; if (isPiece(otherPiece) && isWhitePiece(otherPiece)) { for (int i = 0; i < 4; i++) { Move promoMove(row, col, destRow, destCol, otherPiece, promotedPieceTypes[i]); moveList.addMove(promoMove); } } } } else { if (col == destCol) { bool doublePush = false; bool singlePush = mPieceType[(row-1)*8+col] == NoPiece; if (singlePush) doublePush = mPieceType[(row-2)*8+col] == NoPiece; if ( (row-destRow) == 1 && singlePush) { Move newMove(row, col, destRow, destCol); moveList.addMove(newMove); } if ( (row-destRow) == 2 && doublePush) { Move newMove(row, col, destRow, destCol); newMove.setDoublePawnPush(); moveList.addMove(newMove); } } else { PieceType otherPiece = mPieceType[destIndex]; if (isPiece(otherPiece) && isWhitePiece(otherPiece)) { Move newMove(row, col, destRow, destCol, otherPiece); moveList.addMove(newMove); } } } } // Check en-passant if (mBlackEnPassant && row == 3) { if (col != 7) { PieceType pieceType = getPieceType(row, col+1); if (mEnPassantCaptureCol == col + 1 && pieceType == WhitePawn) { Move newMove(row, col, row-1, col+1, WhitePawn); newMove.setEnPassant(); moveList.addMove(newMove); } } if (col != 0) { PieceType pieceType = getPieceType(row, col-1); if (mEnPassantCaptureCol == col - 1 && pieceType == WhitePawn) { Move newMove(row, col, row-1, col-1, WhitePawn); newMove.setEnPassant(); moveList.addMove(newMove); } } } }