Skip to content

Commit

Permalink
Do not assume that enum are signed
Browse files Browse the repository at this point in the history
Clang 3.5 issues warning on constructs like: abs(f1 - f2). The thing is that
f1 and f2 are enum types, and the range given (all positive) allows the
compiler to choose an unsigned type (efficiency being one reason to prefer
unsigned arithmetic). If f1 < f2 are unsigned, then f1 - f2 wraps around zero
and the abs() becomes a no-op. It's the reinterpretation of the unsigned
result (large value) as a signed int that happens to give the correct result,
thanks to 2's complement. This is all tricky and dangerous!

In the spirit of the standard, we assume nothing on the signedness of enums,
and simply calculate the rank and file distances as:
- rank_dist(r1, r2) = r1 < r2 ? r2 - r1 : r1 - r2
- file_dist(f1, f2) = f1 < f2 ? f2 - f1 : f1 - f2
this logic can in fact be applied to any enum we may use, so for better
generality and to avoid code duplication, we use a template function diff()
here.

No functional change.

Resolves #95
  • Loading branch information
lucasart authored and glinscott committed Nov 3, 2014
1 parent 8ab9c25 commit d123784
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/bitboard.h
Expand Up @@ -119,11 +119,11 @@ inline int square_distance(Square s1, Square s2) {
}

inline int file_distance(Square s1, Square s2) {
return abs(file_of(s1) - file_of(s2));
return dist(file_of(s1), file_of(s2));
}

inline int rank_distance(Square s1, Square s2) {
return abs(rank_of(s1) - rank_of(s2));
return dist(rank_of(s1), rank_of(s2));
}


Expand Down
6 changes: 3 additions & 3 deletions src/endgame.cpp
Expand Up @@ -479,7 +479,7 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
if ( r == RANK_6
&& square_distance(bksq, queeningSq) <= 1
&& rank_of(wksq) + tempo <= RANK_6
&& (rank_of(brsq) == RANK_1 || (!tempo && abs(file_of(brsq) - f) >= 3)))
&& (rank_of(brsq) == RANK_1 || (!tempo && dist(file_of(brsq), f) >= 3)))
return SCALE_FACTOR_DRAW;

if ( r >= RANK_6
Expand Down Expand Up @@ -535,7 +535,7 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
{
if (file_of(bksq) == file_of(wpsq))
return ScaleFactor(10);
if ( abs(file_of(bksq) - file_of(wpsq)) == 1
if ( dist(file_of(bksq), file_of(wpsq)) == 1
&& square_distance(wksq, bksq) > 2)
return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
}
Expand Down Expand Up @@ -749,7 +749,7 @@ ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
&& opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq2
|| (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakSide, BISHOP))
|| abs(r1 - r2) >= 2))
|| dist(r1, r2) >= 2))
return SCALE_FACTOR_DRAW;

else if ( ksq == blockSq2
Expand Down
1 change: 1 addition & 0 deletions src/types.h
Expand Up @@ -254,6 +254,7 @@ enum Rank {
RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_NB
};

template <typename T> inline T dist(T x, T y) { return x < y ? y - x : x - y; }

/// The Score enum stores a middlegame and an endgame value in a single integer
/// (enum). The least significant 16 bits are used to store the endgame value
Expand Down

0 comments on commit d123784

Please sign in to comment.