void SortMoves (int ply) /***************************************************************************** * * Sort criteria is as follows. * 1. The move from the hash table * 2. Captures as above. * 3. Killers. * 4. History. * 5. Moves to the centre. * *****************************************************************************/ { leaf *p; int f, t, m, tovalue; int side, xside; BitBoard enemyP; side = board.side; xside = 1^side; enemyP = board.b[xside][pawn]; for (p = TreePtr[ply]; p < TreePtr[ply+1]; p++) { p->score = -INFINITY; f = FROMSQ (p->move); t = TOSQ (p->move); m = p->move & MOVEMASK; /* Hash table move (highest score) */ if (m == Hashmv[ply]) p->score += HASHSORTSCORE; else if (cboard[t] != 0 || p->move & PROMOTION) { /* ***** SRW My Interpretation of this code ************* * Captures normally in other places but..... * * * * On capture we generally prefer to capture with the * * with the lowest value piece so to chose between * * pieces we should subtract the piece value .... but * * * * The original code was looking at some captures * * last, especially where the piece was worth more * * than the piece captured - KP v K in endgame.epd * * * * So code modified to prefer any capture by adding * * ValueK * ****************************************************** */ tovalue = (Value[cboard[t]] + Value[PROMOTEPIECE (p->move)]); p->score += tovalue + ValueK - Value[cboard[f]]; } /* Killers */ else if (m == killer1[ply] || m == killer2[ply]) p->score += KILLERSORTSCORE; else if (ply > 2 && (m == killer1[ply-2] || m == killer2[ply-2])) p->score += KILLERSORTSCORE; p->score += history[side][(p->move & 0x0FFF)] + taxicab[f][D5] - taxicab[t][E4]; if ( cboard[f] == pawn ) { /* Look at pushing Passed pawns first */ if ( (enemyP & PassedPawnMask[side][t]) == NULLBITBOARD ) p->score +=50; } } }
int SwapOff (int move) /**************************************************************************** * * A Static Exchange Evaluator (or SEE for short). * First determine the target square. Create a bitboard of all squares * attacking the target square for both sides. Using these 2 bitboards, * we take turn making captures from smallest piece to largest piece. * When a sliding piece makes a capture, we check behind it to see if * another attacker piece has been exposed. If so, add this to the bitboard * as well. When performing the "captures", we stop if one side is ahead * and doesn't need to capture, a form of pseudo-minimaxing. * ****************************************************************************/ { int f, t, sq, piece, lastval; int side, xside; int swaplist[MAXPLYDEPTH], n; BitBoard b, c, *d, *e, r; f = FROMSQ (move); t = TOSQ (move); side = ((board.friends[white] & BitPosArray[f]) ? white : black); xside = 1^side; /* Squares attacking t for side and xside */ b = AttackTo (t, side); c = AttackTo (t, xside); CLEARBIT(b, f); if (xray[cboard[f]]) AddXrayPiece (t, f, side, &b, &c); d = board.b[side]; e = board.b[xside]; if (move & PROMOTION) { swaplist[0] = Value[PROMOTEPIECE (move)] - ValueP; lastval = -Value[PROMOTEPIECE (move)]; } else { swaplist[0] = (move & ENPASSANT ? ValueP : Value[cboard[t]]); lastval = -Value[cboard[f]]; } n = 1; while (1) { if (c == NULLBITBOARD) break; for (piece = pawn; piece <= king; piece++) { r = c & e[piece]; if (r) { sq = leadz (r); CLEARBIT (c, sq); if (xray[piece]) AddXrayPiece (t, sq, xside, &c, &b); swaplist[n] = swaplist[n-1] + lastval; n++; lastval = Value[piece]; break; } } if (b == NULLBITBOARD) break; for (piece = pawn; piece <= king; piece++) { r = b & d[piece]; if (r) { sq = leadz (r); CLEARBIT (b, sq); if (xray[piece]) AddXrayPiece (t, sq, side, &b, &c); swaplist[n] = swaplist[n-1] + lastval; n++; lastval = -Value[piece]; break; } } } /**************************************************************************** * * At this stage, we have the swap scores in a list. We just need to * mini-max the scores from the bottom up to the top of the list. * ****************************************************************************/ --n; while (n) { if (n & 1) { if (swaplist[n] <= swaplist[n-1]) swaplist[n-1] = swaplist[n]; } else { if (swaplist[n] >= swaplist[n-1]) swaplist[n-1] = swaplist[n]; } --n; } return (swaplist[0]); }