From d39b22927e432adb9c06c718ce577f6647d5b07d Mon Sep 17 00:00:00 2001 From: jundery Date: Wed, 20 Mar 2013 23:07:25 -0600 Subject: [PATCH 1/4] Use ALL_PIECES value to reference attackedBy No functional change --- src/evaluate.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 3ba405cc..85fac61e 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -40,8 +40,8 @@ namespace { Pawns::Entry* pi; // attackedBy[color][piece type] is a bitboard representing all squares - // attacked by a given color and piece type, attackedBy[color][0] contains - // all squares attacked by the given color. + // attacked by a given color and piece type, attackedBy[color][ALL_PIECES] + // contains all squares attacked by the given color. Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB]; // kingRing[color] is the zone around the king which is considered @@ -693,7 +693,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Undefended minors get penalized even if not under attack undefendedMinors = pos.pieces(Them) & (pos.pieces(BISHOP) | pos.pieces(KNIGHT)) - & ~ei.attackedBy[Them][0]; + & ~ei.attackedBy[Them][ALL_PIECES]; if (undefendedMinors) score += UndefendedMinorPenalty; @@ -701,7 +701,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Enemy pieces not defended by a pawn and under our attack weakEnemies = pos.pieces(Them) & ~ei.attackedBy[Them][PAWN] - & ei.attackedBy[Us][0]; + & ei.attackedBy[Us][ALL_PIECES]; if (!weakEnemies) return score; @@ -740,9 +740,9 @@ Value do_evaluate(const Position& pos, Value& margin) { score += evaluate_pieces(pos, ei, mobility, mobilityArea); // Sum up all attacked squares - ei.attackedBy[Us][0] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] - | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] - | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING]; + ei.attackedBy[Us][ALL_PIECES] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] + | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] + | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING]; return score; } @@ -768,7 +768,7 @@ Value do_evaluate(const Position& pos, Value& margin) { { // Find the attacked squares around the king which has no defenders // apart from the king itself - undefended = ei.attackedBy[Them][0] & ei.attackedBy[Us][KING]; + undefended = ei.attackedBy[Them][ALL_PIECES] & ei.attackedBy[Us][KING]; undefended &= ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]); @@ -816,7 +816,7 @@ Value do_evaluate(const Position& pos, Value& margin) { } // Analyse enemy's safe distance checks for sliders and knights - safe = ~(pos.pieces(Them) | ei.attackedBy[Us][0]); + safe = ~(pos.pieces(Them) | ei.attackedBy[Us][ALL_PIECES]); b1 = pos.attacks_from(ksq) & safe; b2 = pos.attacks_from(ksq) & safe; @@ -903,7 +903,7 @@ Value do_evaluate(const Position& pos, Value& margin) { if (pos.is_empty(blockSq)) { squaresToQueen = forward_bb(Us, s); - defendedSquares = squaresToQueen & ei.attackedBy[Us][0]; + defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES]; // If there is an enemy rook or queen attacking the pawn from behind, // add all X-ray attacks by the rook or queen. Otherwise consider only @@ -912,7 +912,7 @@ Value do_evaluate(const Position& pos, Value& margin) { && (forward_bb(Them, s) & pos.pieces(Them, ROOK, QUEEN) & pos.attacks_from(s))) unsafeSquares = squaresToQueen; else - unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them)); + unsafeSquares = squaresToQueen & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them)); // If there aren't enemy attacks or pieces along the path to queen give // huge bonus. Even bigger if we protect the pawn's path. @@ -989,7 +989,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Compute plies to queening and check direct advancement movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2); oppMovesToGo = square_distance(pos.king_square(~c), queeningSquare) - int(c != pos.side_to_move()); - pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath); + pathDefended = ((ei.attackedBy[c][ALL_PIECES] & queeningPath) == queeningPath); if (movesToGo >= oppMovesToGo && !pathDefended) continue; @@ -1136,7 +1136,7 @@ Value do_evaluate(const Position& pos, Value& margin) { Bitboard safe = SpaceMask[Us] & ~pos.pieces(Us, PAWN) & ~ei.attackedBy[Them][PAWN] - & (ei.attackedBy[Us][0] | ~ei.attackedBy[Them][0]); + & (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]); // Find all squares which are at most three squares behind some friendly pawn Bitboard behind = pos.pieces(Us, PAWN); From 09f1fdf52fe67b500f1a0159da9e53e9e3456679 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Fri, 22 Mar 2013 08:54:03 +0100 Subject: [PATCH 2/4] Fix bogus mate scores in some positions Always before pruning the move, it's important to check that: bestValue > VALUE_MATED_IN_MAX_PLY See example position: 8/2p1p3/P1NpP3/3k4/1P1BN3/2P1P3/2Q5/6K1 w - - 0 1 http://support.stockfishchess.org/discussions/problems/268-wrong-declaring-a-forced-mate-in-3-moves This problem was present in 2.3.1, then it was fixed by my patch. After 24000 games at 15+0.05 ELO: 2.40 +-4.4 (95%) LOS: 95.7% Total: 24000 W: 4774 L: 4608 D: 14618 bench: 4465997 --- src/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 7a06dad9..6dcd9f1d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -856,7 +856,8 @@ split_point_start: // At split points actual search starts from here && !captureOrPromotion && !inCheck && !dangerous - && move != ttMove) + && move != ttMove + && bestValue > VALUE_MATED_IN_MAX_PLY) { // Move count based pruning if ( depth < 16 * ONE_PLY From 0b4ea54da999e591284aaeec702b6239ca219b81 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Fri, 22 Mar 2013 09:52:41 +0100 Subject: [PATCH 3/4] Update bestValue when futility pruning (2) Same idea of 5af8179647b9e80353c in qsearch() but applied to search() After 15500 games at 15+0.05 ELO: 4.48 +-3.4 (95%) LOS: 99.5% Total: 15500 W: 3061 L: 2861 D: 9578 bench: 4985829 --- src/search.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 6dcd9f1d..f99f63be 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -879,9 +879,14 @@ split_point_start: // At split points actual search starts from here if (futilityValue < beta) { - if (SpNode) - splitPoint->mutex.lock(); + bestValue = std::max(bestValue, futilityValue); + if (SpNode) + { + splitPoint->mutex.lock(); + if (bestValue > splitPoint->bestValue) + splitPoint->bestValue = bestValue; + } continue; } From f2638816bf991b9f7524015b740dd107d3186efc Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 25 Mar 2013 20:04:49 +0100 Subject: [PATCH 4/4] Raise Min Split Depth Raise the limit to 12 so to allow people to test on many cores machines. Suggested by Gary and Martin. No functional change. --- src/ucioption.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ucioption.cpp b/src/ucioption.cpp index 099babd4..eada2a43 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -70,7 +70,7 @@ void init(OptionsMap& o) { o["Passed Pawns (Middle Game)"] = Option(100, 0, 200, on_eval); o["Passed Pawns (Endgame)"] = Option(100, 0, 200, on_eval); o["Space"] = Option(100, 0, 200, on_eval); - o["Min Split Depth"] = Option(msd, 4, 7, on_threads); + o["Min Split Depth"] = Option(msd, 4, 12, on_threads); o["Max Threads per Split Point"] = Option(5, 4, 8, on_threads); o["Threads"] = Option(cpus, 1, MAX_THREADS, on_threads); o["Use Sleeping Threads"] = Option(true);