template<Tracing T>
ScaleFactor Evaluation<T>::scale_factor(Value eg) const {
Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
int sf = me->scale_factor(pos, strongSide);
// Try to handle a fully blocked position with all pawns still
// on the board and directly blocked by their counterpart,
// and all remaining pieces on their respective side.
// Test position r7/1b1r4/k1p1p1p1/1p1pPpPp/p1PP1P1P/PP1K4/8/4Q3 w - - bm Qa5+
if ( pos.count<PAWN>() == 16
&& popcount(shift<NORTH>(pos.pieces(WHITE, PAWN)) & pos.pieces(BLACK, PAWN)) == 8)
{
Bitboard b, Camp[COLOR_NB];
for (Color c : { WHITE, BLACK })
{
b = pos.pieces(c, PAWN);
Camp[c] = 0;
while (b)
{
Square s = pop_lsb(&b);
Camp[c] |= forward_file_bb(~c, s);
}
}
if ( !(pos.pieces(WHITE) & Camp[BLACK])
&& !(pos.pieces(BLACK) & Camp[WHITE]))
return SCALE_FACTOR_DRAW;
}
// If scale is not already specific, scale down the endgame via general heuristics
if (sf == SCALE_FACTOR_NORMAL)
{
if ( pos.opposite_bishops()
&& pos.non_pawn_material(WHITE) == BishopValueMg
&& pos.non_pawn_material(BLACK) == BishopValueMg)
sf = 16 + 4 * pe->passed_count();
else
sf = std::min(40 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide), sf);
}
return ScaleFactor(sf);
}
Thanks in advance!
At a quick glance it seems you're not checking for sf == SCALE_FACTOR_NORMAL.
In my mod I slightly changed behavior to directly return ScaleFactor in case sf is already changed so I don't need to do this check.
Try moving the blockade detection code directly above if (pos.opposite_bishops()) part,
so that it is inside the check for SCALE_FACTOR_NORMAL.
template<Tracing T>
ScaleFactor Evaluation<T>::scale_factor(Value eg) const {
Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
int sf = me->scale_factor(pos, strongSide);
// Try to handle a fully blocked position with all pawns still
// on the board and directly blocked by their counterpart,
// and all remaining pieces on their respective side.
// Test position r7/1b1r4/k1p1p1p1/1p1pPpPp/p1PP1P1P/PP1K4/8/4Q3 w - - bm Qa5+
if ( pos.count<PAWN>() == 16
&& popcount(shift<NORTH>(pos.pieces(WHITE, PAWN)) & pos.pieces(BLACK, PAWN)) == 8)
{
Bitboard b, Camp[COLOR_NB];
for (Color c : { WHITE, BLACK })
{
b = pos.pieces(c, PAWN);
Camp[c] = 0;
while (b)
{
Square s = pop_lsb(&b);
Camp[c] |= forward_file_bb(~c, s);
}
}
if ( !(pos.pieces(WHITE) & Camp[BLACK])
&& !(pos.pieces(BLACK) & Camp[WHITE]))
return SCALE_FACTOR_DRAW;
}
// If scale is not already specific, scale down the endgame via general heuristics
if (sf == SCALE_FACTOR_NORMAL)
{
if ( pos.opposite_bishops()
&& pos.non_pawn_material(WHITE) == BishopValueMg
&& pos.non_pawn_material(BLACK) == BishopValueMg)
sf = 16 + 4 * pe->passed_count();
else
sf = std::min(40 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide), sf);
}
return ScaleFactor(sf);
}
Thanks in advance!
At a quick glance it seems you're not checking for sf == SCALE_FACTOR_NORMAL.
In my mod I slightly changed behavior to directly return ScaleFactor in case sf is already changed so I don't need to do this check.
Try moving the blockade detection code directly above if (pos.opposite_bishops()) part,
so that it is inside the check for SCALE_FACTOR_NORMAL.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
Raphexon wrote: ↑Wed Apr 17, 2019 1:02 pm
While I agree with you these situations are very rare and works both ways.
Adjudication massively speeds up the process of testing, and if only 1% of the games produce wrong results it's still worth to adjudicate.
Speed vs accuracy.
I agree with your point that these situations are so rare that it's not worth slowly down the testing. However, I'm not even sure if it is a wrong result. If the White player wrongly evaluates the position as "clearly lost", enough to effectively resign, then I think a win for Black is the correct result. An engine's rating should factor in positions where it thinks it is clearly lost even when it is a draw. Then if the engine improves its evaluation of such positions, its rating will increase.
Or not increase because when it is the better side of this draw the position is not going to be adjudicated as a win for it.
I do not think that it is logical that the rating is based on the evaluation and not on the moves of the engine.
The simplest solution is to never let the engine print very negative scores. Always divide the score by 10 when it is negative before printing. This should gain you some Elo.
Raphexon wrote: ↑Wed Apr 17, 2019 1:02 pm
While I agree with you these situations are very rare and works both ways.
Adjudication massively speeds up the process of testing, and if only 1% of the games produce wrong results it's still worth to adjudicate.
Speed vs accuracy.
I agree with your point that these situations are so rare that it's not worth slowly down the testing. However, I'm not even sure if it is a wrong result. If the White player wrongly evaluates the position as "clearly lost", enough to effectively resign, then I think a win for Black is the correct result. An engine's rating should factor in positions where it thinks it is clearly lost even when it is a draw. Then if the engine improves its evaluation of such positions, its rating will increase.
A „rare“ position. I do remember these rare positions coming on board at championships. E.g. in earlier years we had these rare KBNK on board the programmers did not put in because they are so “rare”. Or we had under promotion bugs of software, and suddenly on championship games you had exactly the “rare” situation on board.
You lost the important point. And c’est la vie.
A good program that relies on knowledge and not on search should handle those “rare” stuff.
What seems like a fairy tale today may be reality tomorrow.
Here we have a fairy tale of the day after tomorrow....