Sven, we drift far away from the original thread topic, but in shorty I tried this:
The first step was to ensure there are no opponent pawns attacking my "blocked" pawn. For example after 1.e4 e5 2.d4 I didn't want to consider blacks e5 pawn as a blocked pawn.
Next I tried was to ensure there are no opponent pawns which possibly could attack my blocked pawn in a few moves, because either there are no such pawns on adjacent files or there are none in front of my blocked pawn.
That's all I have tried. Still easy to compute (I hate to makes things complicated too early), but it didn't help for bad bishop evaluation, at least in my tests. So I have canceled further tries with blocked pawns.
Stockfish - material balance/imbalance evaluation
Moderator: Ras
-
- Posts: 408
- Joined: Sat Mar 06, 2010 9:28 am
-
- Posts: 4655
- Joined: Sun Mar 12, 2006 2:40 am
- Full name: Eelco de Groot
Re: Stockfish - material balance/imbalance evaluation
Hi Ralph,Ralph Stoesser wrote:For this test I simply took all pawns (temporarily) blocked by an opponent pawn.Eelco de Groot wrote: ...
I take it you have information about blocked pawns in the dynamic evaluation Ralph? I was wondering if computing the colour of pawnsquares is costly to perform? I do believe I do something like colour detection of passed pawns and Bishops, but not for blocked pawns. And not sure I'm doing it efficiently.
Stockfish may be difficult to improve, but it is always possible! Do you have any plans for making your own version of Stockfish public Ralph![]()
Regards, Eelco
In pawns.cpp, PawnInfoTable::evaluate_pawns(), for every pawn I calculatedMaybe not that efficient, but simple to implement. Then in evaluate() pi->blockedPawns[Us] & WhiteSquaresBB is the bitboard of our white colored blocked pawns, pi->blockedPawns[Us] & BlackSquaresBB are our black colored blocked pawns.Code: Select all
bool blocked = theirPawns & file_bb(f) & rank_bb(r + (Us == WHITE ? 1 : -1)) if (blocked) set_bit(&(pi->blockedPawns[Us]), s);
No I don't plan to make my own version. I just fiddle around with SF code.
Thanks very much for your code example! You don't have to show your code of course, but thanks for the ideas! Blocked pawns is also in Rainbow Serpent, but mainly tried for determining lower chances of a win, at least in theory but there were some bugs as I believe I posted.
For myself I try to not look too much at the Stockfish code for a while because it gets in the way of other things I should be doing. Temporary break, at least that is the deal. But your BlackSquaresBB and WhiteSquaresBB idea looks really cool! There was already a version of blockedPawns in Rainbow Serpent but I have not really tested if everything works. I don't know if my version of pawns.cpp fits in this post, let's try. The inlining looks reasonably okay, and it seems to fit so here is my version. Rainbow Serpent header and some other changes to backward pawns mainly, my version of blockedPawns, different scoring of candidate pawns. I don't expect everything to be bugfree here, sorry for any mistakes, as I am no real programmer there must be some things that can be sped up:
Code: Select all
/*
Rainbow Serpent, a UCI chess playing engine based on Stockfish 1.7.1
which in turn is derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
Copyright source changes from Stockfish 1.7.1 (C) 2010 Eelco de Groot
Rainbow Serpent is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Rainbow Serpent is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
////
//// Includes
////
#include <cassert>
#include <cstring>
#include "bitcount.h"
#include "pawns.h"
#include "position.h"
////
//// Local definitions
////
namespace {
/// Constants and variables
#define S(mg, eg) make_score(mg, eg)
// Doubled pawn penalty by file
const Score DoubledPawnPenalty[8] = {
S(13, 43), S(20, 48), S(23, 48), S(23, 48),
S(23, 48), S(23, 48), S(20, 48), S(13, 43)
};
// Isolated pawn penalty by file
const Score IsolatedPawnPenalty[8] = {
S(25, 30), S(36, 35), S(40, 35), S(40, 35),
S(40, 35), S(40, 35), S(36, 35), S(25, 30)
};
// Backward pawn penalty by file
const Score BackwardPawnPenalty[8] = {
S(20, 35), S(29, 38), S(33, 40), S(33, 40),
S(33, 40), S(33, 40), S(29, 38), S(20, 35)
};
// Pawn chain membership bonus by file
const Score ChainBonus[8] = {
S(11,4), S(13,4), S(13,4), S(14,4),
S(14,4), S(13,4), S(13,4), S(11,4)
};
// Candidate passed pawn bonus by rank
const Score CandidateBonus[8] = {
S( 0, 0), S( 6, 13), S(6,13), S(14,29),
S(34,68), S(80,170), S(0, 0), S( 0, 0)
};
// Pawn storm tables for positions with opposite castling
const int QStormTable[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
-22,-22,-22,-14,-6, 0, 0, 0,
-6,-10,-10,-10,-6, 0, 0, 0,
4, 12, 16, 12, 4, 0, 0, 0,
16, 23, 23, 16, 0, 0, 0, 0,
23, 31, 31, 23, 0, 0, 0, 0,
23, 31, 31, 23, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
const int KStormTable[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,-10,-19,-28,-33,-33,
0, 0, 0,-10,-15,-19,-24,-24,
0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 10, 19, 19,
0, 0, 0, 0, 1, 19, 31, 27,
0, 0, 0, 0, 0, 22, 31, 22,
0, 0, 0, 0, 0, 0, 0, 0
};
// Pawn storm open file bonuses by file
const int16_t KStormOpenFileBonus[8] = { 31, 31, 18, 0, 0, 0, 0, 0 };
const int16_t QStormOpenFileBonus[8] = { 0, 0, 0, 0, 0, 26, 42, 26 };
// Pawn storm lever bonuses by file
const int StormLeverBonus[8] = { -8, -8, -13, 0, 0, -13, -8, -8 };
}
////
//// Functions
////
/// Constructor
PawnInfoTable::PawnInfoTable(unsigned numOfEntries) {
size = numOfEntries;
entries = new PawnInfo[size];
if (!entries)
{
std::cerr << "Failed to allocate " << (numOfEntries * sizeof(PawnInfo))
<< " bytes for pawn hash table." << std::endl;
Application::exit_with_failure();
}
}
/// Destructor
PawnInfoTable::~PawnInfoTable() {
delete [] entries;
}
/// PawnInfo::clear() resets to zero the PawnInfo entry. Note that
/// kingSquares[] is initialized to SQ_NONE instead.
void PawnInfo::clear() {
memset(this, 0, sizeof(PawnInfo));
kingSquares[WHITE] = kingSquares[BLACK] = SQ_NONE;
}
/// PawnInfoTable::get_pawn_info() takes a position object as input, computes
/// a PawnInfo object, and returns a pointer to it. The result is also
/// stored in a hash table, so we don't have to recompute everything when
/// the same pawn structure occurs again.
PawnInfo* PawnInfoTable::get_pawn_info(const Position& pos) {
assert(pos.is_ok());
Key key = pos.get_pawn_key();
int index = int(key & (size - 1));
PawnInfo* pi = entries + index;
// If pi->key matches the position's pawn hash key, it means that we
// have analysed this pawn structure before, and we can simply return
// the information we found the last time instead of recomputing it.
if (pi->key == key)
return pi;
// Clear the PawnInfo object, and set the key
pi->clear();
pi->key = key;
// Calculate pawn attacks
Bitboard whitePawns = pos.pieces(PAWN, WHITE);
Bitboard blackPawns = pos.pieces(PAWN, BLACK);
pi->pawnAttacks[WHITE] = ((whitePawns << 9) & ~FileABB) | ((whitePawns << 7) & ~FileHBB);
pi->pawnAttacks[BLACK] = ((blackPawns >> 7) & ~FileABB) | ((blackPawns >> 9) & ~FileHBB);
// Evaluate pawns for both colors
pi->value = evaluate_pawns<WHITE>(pos, whitePawns, blackPawns, pi)
- evaluate_pawns<BLACK>(pos, blackPawns, whitePawns, pi);
return pi;
}
/// PawnInfoTable::evaluate_pawns() evaluates each pawn of the given color
template<Color Us>
Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
Bitboard theirPawns, PawnInfo* pi) {
Square s;
File f;
Rank r;
bool passed, isolated, doubled, chain, backward, candidate, blocked, indirectlyBlocked, open, attackedBlocksquare;
int bonus, candidatesupportcount;
Score value = make_score(0, 0);
const Square* ptr = pos.piece_list_begin(Us, PAWN);
const Color Them = (Us == WHITE ? BLACK : WHITE);
// Initialize pawn storm scores by giving bonuses for open files
for (f = FILE_A; f <= FILE_H; f++)
if (!(ourPawns & file_bb(f)))
{
pi->ksStormValue[Us] += KStormOpenFileBonus[f];
pi->qsStormValue[Us] += QStormOpenFileBonus[f];
pi->halfOpenFiles[Us] |= (1 << f);
}
// Loop through all pawns of the current color and score each pawn
while ((s = *ptr++) != SQ_NONE)
{
f = square_file(s);
r = square_rank(s);
Square blockSq = s + pawn_push(Us);
assert(pos.piece_on(s) == piece_of_color_and_type(Us, PAWN));
// Pawn blocked by enemy pawn?
blocked = (!pos.square_is_empty(blockSq) && bit_is_set(theirPawns, blockSq));
indirectlyBlocked = blocked;
// Pawn on half-open file?
open = !blocked && !(theirPawns & file_bb(f));
// Passed, isolated or doubled pawn?
passed = open && Position::pawn_is_passed(theirPawns, Us, s);
isolated = Position::pawn_is_isolated(ourPawns, s);
doubled = Position::pawn_is_doubled(ourPawns, Us, s);
// Square in front attacked by enemy pawn?
attackedBlocksquare = pos.attacks_from<PAWN>(blockSq, Us) & theirPawns;
// We calculate kingside and queenside pawn storm
// scores for both colors. These are used when evaluating
// middle game positions with opposite side castling.
//
// Each pawn is given a base score given by a piece square table
// (KStormTable[] or QStormTable[]). Pawns which seem to have good
// chances of creating an open file by exchanging itself against an
// enemy pawn on an adjacent file gets an additional bonus.
// Kingside pawn storms
bonus = KStormTable[relative_square(Us, s)];
if (f >= FILE_F)
{
Bitboard b = outpost_mask(Us, s) & theirPawns & (FileFBB | FileGBB | FileHBB);
while (b)
{
// Give a bonus according to the distance of the nearest enemy pawn
Square s2 = pop_1st_bit(&b);
int v = StormLeverBonus[f] - 2 * square_distance(s, s2);
// If enemy pawn has no pawn beside itself is particularly vulnerable.
// Big bonus, especially against a weakness on the rook file
if (!(theirPawns & neighboring_files_bb(s2) & rank_bb(s2)))
v *= (square_file(s2) == FILE_H ? 4 : 2);
bonus += v;
}
}
pi->ksStormValue[Us] += bonus;
// Queenside pawn storms
bonus = QStormTable[relative_square(Us, s)];
if (f <= FILE_C)
{
Bitboard b = outpost_mask(Us, s) & theirPawns & (FileABB | FileBBB | FileCBB);
while (b)
{
// Give a bonus according to the distance of the nearest enemy pawn
Square s2 = pop_1st_bit(&b);
int v = StormLeverBonus[f] - 4 * square_distance(s, s2);
// If enemy pawn has no pawn beside itself is particularly vulnerable.
// Big bonus, especially against a weakness on the rook file
if (!(theirPawns & neighboring_files_bb(s2) & rank_bb(s2)))
v *= (square_file(s2) == FILE_A ? 4 : 2);
bonus += v;
}
}
pi->qsStormValue[Us] += bonus;
// Member of a pawn chain (but not the backward one)? We could speed up
// the test a little by introducing an array of masks indexed by color
// and square for doing the test, but because everything is hashed,
// it probably won't make any noticeable difference.
chain = ourPawns
& neighboring_files_bb(f)
& (rank_bb(r) | rank_bb(r - (Us == WHITE ? 1 : -1)));
// Test for candidate passed pawn
candidate = false;
candidatesupportcount = 0;
if (!blocked && !passed && open)
{
candidatesupportcount = count_1s_max_15(neighboring_files_bb(f) & (behind_bb(Us, r) | rank_bb(r)) & ourPawns)
- count_1s_max_15(neighboring_files_bb(f) & in_front_bb(Us, r) & theirPawns);
candidate = candidatesupportcount >= 0;
}
// Test for backward pawn
//
// If the pawn is passed, isolated, a candidate or member of a pawn chain
// it cannot be backward. If there are friendly pawns behind on neighboring files
// the pawn can not be backward either.
// [EdG: If the pawn can capture an enemy pawn the situation
// seems unclear to me also because we do not know who has the move,
// at least that is my assumption. I count the pawn backward for now
// so have removed the en prise test]
if ( (passed | candidate | isolated | chain)
|| (ourPawns & behind_bb(Us, r) & neighboring_files_bb(f))
/*|| (pos.attacks_from<PAWN>(s, Us) & theirPawns)*/)
backward = false;
else
{
// We now know that there are no friendly pawns beside or behind this
// pawn on neighboring files. We now check whether the pawn is
// backward by looking in the forward direction on the neighboring
// files, and seeing whether we meet a friendly or an enemy pawn first.
Bitboard b = pos.attacks_from<PAWN>(s, Us);
backward = true;
if (!blocked && (b & ourPawns))
{
if (Us == WHITE)
{
if ((relative_rank(Us, s) >= RANK_4) || !((b | (b << 8)) & theirPawns)) backward = false;
}
else
{
if ((relative_rank(Us, s) >= RANK_4) || !((b | (b >> 8)) & theirPawns)) backward = false;
}
if (backward
&& !open
&& (count_1s_max_15(b & ourPawns) == 2)
&& (count_1s_max_15((Us == WHITE ? (b << 8) : (b >> 8)) & theirPawns) == 2))
indirectlyBlocked = true;
// This is maybe not watertight but just an indicator that
// a breakthrough will be difficult. Expensive calculation
}
}
// In order to prevent doubled passed pawns from receiving a too big
// bonus, only the frontmost passed pawn on each file is considered as
// a true passed pawn.
if (passed && (ourPawns & squares_in_front_of(Us, s)))
passed = false;
// Score this pawn
if (passed)
set_bit(&(pi->passedPawns), s);
if (blocked || indirectlyBlocked)
set_bit(&(pi->blockedPawns), s);
if (isolated)
{
value -= IsolatedPawnPenalty[f];
if (!(theirPawns & file_bb(f)))
{
value -= IsolatedPawnPenalty[f] / 2;
if (doubled)
value -= IsolatedPawnPenalty[f] / 4;
}
}
if (doubled)
value -= DoubledPawnPenalty[f];
if (backward)
{
value -= BackwardPawnPenalty[f];
if (blocked)
value -= make_score(relative_rank(Them, s) * 2, relative_rank(Them, s));
if (open)
value -= (BackwardPawnPenalty[f] / 2) - make_score(0, relative_rank(Us, s) * 2);
}
if (chain)
value += ChainBonus[f];
if (candidate)
{
value += CandidateBonus[relative_rank(Us, s)];
if (!chain && (attackedBlocksquare || (pos.attacks_from<PAWN>(s, Us) & theirPawns)))
value -= CandidateBonus[relative_rank(Us, s)]/4;
if (candidatesupportcount > 0)
{
candidatesupportcount = (candidatesupportcount * relative_rank(Us, s) * 10)
+ ((int(chain) + int(pos.non_pawn_material(Them) == Value(0))) * 4 * relative_rank(Us, s));
value += make_score(candidatesupportcount, candidatesupportcount * 2);
}
}
}
return value;
}
/// PawnInfo::updateShelter calculates and caches king shelter. It is called
/// only when king square changes, about 20% of total get_king_shelter() calls.
int PawnInfo::updateShelter(const Position& pos, Color c, Square ksq) {
unsigned shelter = 0;
Bitboard pawns = pos.pieces(PAWN, c) & this_and_neighboring_files_bb(ksq);
unsigned r = ksq & (7 << 3);
for (int i = 1, k = (c ? -8 : 8); i < 4; i++)
{
r += k;
shelter += BitCount8Bit[(pawns >> r) & 0xFF] * (128 >> i);
}
kingSquares[c] = ksq;
kingShelters[c] = shelter;
return shelter;
}
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan
-
- Posts: 1808
- Joined: Wed Mar 08, 2006 9:19 pm
- Location: Oslo, Norway
Re: Stockfish - material balance/imbalance evaluation
OK, I'll try to explain. It's nothing very fancy, really.Ralph Stoesser wrote:I've read Kaufman's paper about the evaluation of material imbalance, but I wonder what exactly Tord Romstad's polynomial function does.
A material evaluation function is a function of 10 variables; P (the number of white pawns), p (the number of black pawns), N (the number of white knights), n (the number of black pawns, and by now you'll understand the meaning of the remaining variables), B, b, R, r, Q and q.
When we learned to play chess, most of us were taught a material evaluation function which is a linear polynomial in the 10 variables, something like this:
Code: Select all
f(P, p, N, n, B, b, R, r, Q, q) = 1*(P-p) + 3*(N-n) + 3*(B-b) + 4.5*(R-r) + 9*(Q-q)
Code: Select all
0.25 * (B*(B-1) - b*(b-1))
This works because the product B*(B-1) is 0 if there are 0 or 1 white bishops, but 2 if there are 2 bishops.
Similarly, other more complex material evaluation rules like the ones found in Kaufman's paper can also be modeled by second-degree polynomial terms. For instance, assume that we want to increase the value of a knight by 0.05 for each enemy pawn on the board (this is almost certainly not an exact rule from Kaufman's paper, but I'm too lazy to look up the paper now). This would correspond to a term like this:
Code: Select all
0.05 * (N*p - n*P)
We never managed to make it work as well as I hoped, though.
-
- Posts: 1808
- Joined: Wed Mar 08, 2006 9:19 pm
- Location: Oslo, Norway
Re: Stockfish - material balance/imbalance evaluation
As you can probably guess, you are not the first person to experiment with this.Ralph Stoesser wrote:Sven, we drift far away from the original thread topic, but in shorty I tried this:
The first step was to ensure there are no opponent pawns attacking my "blocked" pawn. For example after 1.e4 e5 2.d4 I didn't want to consider blacks e5 pawn as a blocked pawn.
Next I tried was to ensure there are no opponent pawns which possibly could attack my blocked pawn in a few moves, because either there are no such pawns on adjacent files or there are none in front of my blocked pawn.
That's all I have tried. Still easy to compute (I hate to makes things complicated too early), but it didn't help for bad bishop evaluation, at least in my tests. So I have canceled further tries with blocked pawns.
I've tried implementing a bad bishop penalty numerous times, using several different approaches: Counting all pawns on the bishop's color, only the blocked pawns, both blocked and unblocked pawns but with higher weights for blocked pawns, higher weights for pawns on central squares, and so on. I've never managed to make it work. The playing strength has always ended up unchanged or (more often) slightly lower.
This doesn't mean that it's impossible to make it work, of course. Perhaps we just haven't found exactly the right way to do it yet. With some luck, you might be able to do it.

Improving a mature chess program's evaluation function isn't easy. Just going through the code, identifying a missing piece of knowledge and implementing it in the most straightforward way will in most cases fail badly. Implementing it in a less straightforward way will usually fail even worse.
-
- Posts: 89
- Joined: Thu Apr 01, 2010 5:28 am
- Location: Omaha, NE
Re: Stockfish - material balance/imbalance evaluation
I'm curious if anyone has tried evaluating material balance indirectly. An example would be by counting the number of moves each piece has and multiplying it by a coefficient specific to the type of piece. In the end, the side with the most pieces will likely have a higher score, but in the case that a piece is trapped or immobile, its value would be less than 'normal'.
It would then come down to finding the proper equations/coefficients to calculate a value based on the number of moves the piece can make.
It might also have a counter-intuitive result in that a chess engine can search deeper in positions where there are fewer moves... so maybe fewer for both sides is better, as long as its balanced. Could be interesting I think.
It would then come down to finding the proper equations/coefficients to calculate a value based on the number of moves the piece can make.
It might also have a counter-intuitive result in that a chess engine can search deeper in positions where there are fewer moves... so maybe fewer for both sides is better, as long as its balanced. Could be interesting I think.
-
- Posts: 60
- Joined: Thu Nov 05, 2009 9:53 pm
Re: Stockfish - material balance/imbalance evaluation
Is this tuning method described somewhere?Tord Romstad wrote:That so many material evaluation rules can be modeled by polynomials of degree 2 gave me the idea of using a completely general (apart from the obvious symmetry relations) second degree polynomial for evaluating material, and to spend lots of effort trying to tune all the coefficients (this was shortly after Joona had invented a very effective method for tuning evaluation parameters).
We never managed to make it work as well as I hoped, though.
I am in the mood of going all bayesian on it (with monte carlo integration over parameter space and stuff) but it would be nice to see some less computationaly expensive approaches first.
Anyway, I had another question in mind. Is this method using games starting from startposition/book only, or also from selected middlegame/engame positions? You know, some material imbalances are just too rare to encounter. Of course, getting horribly wrong evaluation on rare positions does not cost much elo. But I think more testgames with rare imbalances, averaged in with appropriate lower weights, could produce better evaluation parameter values.
Of course, heavy imbalances might be too much for degree 2 model. For example I think that in this position,
[d]
white would be losing if the knights become centralized, so one queen for two knights looks like good exchange for white (and bad for black).
Oh, but this is not the "rare but worthy of testing" position. I was thinking more like RR vs BNN (with some pawns). Nevermind.
-
- Posts: 408
- Joined: Sat Mar 06, 2010 9:28 am
Re: Stockfish - material balance/imbalance evaluation
Thanks for the detailed explanation, Tord.
Probably I'm cheeky now, but why not try a third degree polynomial next time?
The coefficients would be computed automatically while we sleep...
At some morning, a few months later, maybe you and your team could tell Mr. Kaufman something new about counting pieces.
@Marco: I'll give the bad bishop (w.r.t. blocked pawns of the same square color) evaluation a final try. Maybe after 5000 games @1min per game I could announce +1 or +2 Elo gain. You never know.
Probably I'm cheeky now, but why not try a third degree polynomial next time?
The coefficients would be computed automatically while we sleep...
At some morning, a few months later, maybe you and your team could tell Mr. Kaufman something new about counting pieces.

@Marco: I'll give the bad bishop (w.r.t. blocked pawns of the same square color) evaluation a final try. Maybe after 5000 games @1min per game I could announce +1 or +2 Elo gain. You never know.

-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: Stockfish - material balance/imbalance evaluation
I am not chess player, but I understand that bishop is bad because pawns blocks his mobility, so thatRalph Stoesser wrote: @Marco: I'll give the bad bishop (w.r.t. blocked pawns of the same square color) evaluation a final try. Maybe after 5000 games @1min per game I could announce +1 or +2 Elo gain. You never know.
bad bishop == bishop with small mobility
and this is already taken in account in the "mobility" section in the evaluation.
My impression (but just an impression because I am no chess expert) is that you cannot apply chess rules directly to an engine but you need first to understand _why_ there is that rule, what is the reason that is behind and sometime it is easier for a computer to directly track the source of the rule instead of the rule itself: in this case it is easier for the computer (and also already implemented) to count bishop mobility directly.
-
- Posts: 408
- Joined: Sat Mar 06, 2010 9:28 am
Re: Stockfish - material balance/imbalance evaluation
That's a good point. The idea in evaluating a bad bishop is the following:mcostalba wrote:
I am not chess player, but I understand that bishop is bad because pawns blocks his mobility, so that
bad bishop == bishop with small mobility
and this is already taken in account in the "mobility" section in the evaluation.
My impression (but just an impression because I am no chess expert) is that you cannot apply chess rules directly to an engine but you need first to understand _why_ there is that rule, what is the reason that is behind and sometime it is easier for a computer to directly track the source of the rule instead of the rule itself: in this case it is easier for the computer (and also already implemented) to count bishop mobility directly.
The bad bishop issue is not only a mobility issue, but a long term mobility issue.
An extreme example for a long term mobility issue is the trapped bishop. One could ask why have an extra evaluation for it? A trapped bishop has no mobility, so it is considered bad anyway. But in fact we have a infinite long term mobility issue with a trapped bishop, with the result that a trapped bishop is worth nothing.
By evaluating only the bishop's mobility, the engine has no knowledge about how deep behind the search horizon the mobility issue would be valid. That's why I believe it should work.
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: Stockfish - material balance/imbalance evaluation
In chess engines "long term" is called "search depth"Ralph Stoesser wrote: The bad bishop issue is not only a mobility issue, but a long term mobility issue.
Are you sure ?Ralph Stoesser wrote: By evaluating only the bishop's mobility, the engine has no knowledge about how deep behind the search horizon the mobility issue would be valid.
When we talk of "horizon" we are talking of about 20 moves ahead and counting...
