From 167fcd599aa92524de709ce82ab9c41a3a77f463 Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Fri, 1 Apr 2016 09:58:58 -0400 Subject: [PATCH 1/6] BSG2_20160401 Running SG idea as a simplification no functional change over his test bench: 7874373 master: 8880041 --- src/pawns.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index 9239bface2e..8963e6dfca3 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -100,9 +100,9 @@ namespace { const Square Right = (Us == WHITE ? DELTA_NE : DELTA_SW); const Square Left = (Us == WHITE ? DELTA_NW : DELTA_SE); - Bitboard b, neighbours, doubled, supported, phalanx; + Bitboard b, neighbours, stoppers, doubled, supported, phalanx; Square s; - bool passed, isolated, opposed, backward, lever, connected; + bool isolated, opposed, lever, connected, backward; Score score = SCORE_ZERO; const Square* pl = pos.squares(Us); const Bitboard* pawnAttacksBB = StepAttacksBB[make_piece(Us, PAWN)]; @@ -131,7 +131,7 @@ namespace { neighbours = ourPawns & adjacent_files_bb(f); doubled = ourPawns & forward_bb(Us, s); opposed = theirPawns & forward_bb(Us, s); - passed = !(theirPawns & passed_pawn_mask(Us, s)); + stoppers = theirPawns & passed_pawn_mask(Us, s); lever = theirPawns & pawnAttacksBB[s]; phalanx = neighbours & rank_bb(s); supported = neighbours & rank_bb(s - Up); @@ -142,7 +142,7 @@ namespace { // If the pawn is passed, isolated, lever or connected it cannot be // backward. If there are friendly pawns behind on adjacent files // or if it is sufficiently advanced, it cannot be backward either. - if ( (passed | isolated | lever | connected) + if ( (!stoppers | isolated | lever | connected) || (ourPawns & pawn_attack_span(Them, s)) || (relative_rank(Us, s) >= RANK_5)) backward = false; @@ -151,21 +151,21 @@ namespace { // We now know there are no friendly pawns beside or behind this // pawn on adjacent files. We now check whether the pawn is // backward by looking in the forward direction on the adjacent - // files, and picking the closest pawn there. - b = pawn_attack_span(Us, s) & (ourPawns | theirPawns); - b = pawn_attack_span(Us, s) & rank_bb(backmost_sq(Us, b)); + // files and the front file, and picking the closest pawn there. + b = rank_bb(backmost_sq(Us, neighbours | stoppers)); // If we have an enemy pawn in the same or next rank, the pawn is - // backward because it cannot advance without being captured. - backward = (b | shift_bb(b)) & theirPawns; + // backward because it is opposed or it can be captured before + // making a phalanx with closest neighbour. + backward = (b | shift_bb(b & adjacent_files_bb(f))) & stoppers; } - assert(opposed | passed | (pawn_attack_span(Us, s) & theirPawns)); + assert(opposed | !stoppers | (pawn_attack_span(Us, s) & theirPawns)); // Passed pawns will be properly scored in evaluation because we need // full attack info to evaluate them. Only the frontmost passed // pawn on each file is considered a true passed pawn. - if (passed && !doubled) + if (!(stoppers | doubled)) e->passedPawns[Us] |= s; // Score this pawn From 35b5762dee2bc34c52aae303745027abc35c48c3 Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Sun, 3 Apr 2016 20:14:36 -0400 Subject: [PATCH 2/6] BSG2_20160403_1 Simplified a bit more, no functional change, same bench. Updated comments. --- src/pawns.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index 8963e6dfca3..f338bd4659b 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -139,24 +139,16 @@ namespace { isolated = !neighbours; // Test for backward pawn. - // If the pawn is passed, isolated, lever or connected it cannot be - // backward. If there are friendly pawns behind on adjacent files - // or if it is sufficiently advanced, it cannot be backward either. - if ( (!stoppers | isolated | lever | connected) - || (ourPawns & pawn_attack_span(Them, s)) - || (relative_rank(Us, s) >= RANK_5)) + if ( (isolated | lever | connected) || (relative_rank(Us, s) >= RANK_5)) backward = false; else { - // We now know there are no friendly pawns beside or behind this - // pawn on adjacent files. We now check whether the pawn is - // backward by looking in the forward direction on the adjacent - // files and the front file, and picking the closest pawn there. + // Find the backmost rank with neighbours or stoppers b = rank_bb(backmost_sq(Us, neighbours | stoppers)); - // If we have an enemy pawn in the same or next rank, the pawn is - // backward because it is opposed or it can be captured before - // making a phalanx with closest neighbour. + // The pawn is backward when it cannot safely progress to that rank: + // either there is a stopper in the way on this rank, + // or there is a stopper on adjacent file which control the way to that rank backward = (b | shift_bb(b & adjacent_files_bb(f))) & stoppers; } From c4c68fb4bbd5349157f270ffe2005b473a13009f Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Mon, 4 Apr 2016 07:52:47 -0400 Subject: [PATCH 3/6] BSG2_20160404_1 Marco's style --- src/pawns.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index f338bd4659b..6dd2fa1c907 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -102,7 +102,7 @@ namespace { Bitboard b, neighbours, stoppers, doubled, supported, phalanx; Square s; - bool isolated, opposed, lever, connected, backward; + bool opposed, lever, connected, backward; Score score = SCORE_ZERO; const Square* pl = pos.squares(Us); const Bitboard* pawnAttacksBB = StepAttacksBB[make_piece(Us, PAWN)]; @@ -128,18 +128,18 @@ namespace { e->pawnAttacksSpan[Us] |= pawn_attack_span(Us, s); // Flag the pawn - neighbours = ourPawns & adjacent_files_bb(f); - doubled = ourPawns & forward_bb(Us, s); opposed = theirPawns & forward_bb(Us, s); stoppers = theirPawns & passed_pawn_mask(Us, s); lever = theirPawns & pawnAttacksBB[s]; + doubled = ourPawns & forward_bb(Us, s); + neighbours = ourPawns & adjacent_files_bb(f); phalanx = neighbours & rank_bb(s); supported = neighbours & rank_bb(s - Up); connected = supported | phalanx; - isolated = !neighbours; - // Test for backward pawn. - if ( (isolated | lever | connected) || (relative_rank(Us, s) >= RANK_5)) + // A pawn is backward when is behind all pawns of the same color on the + // adjacent files and cannot be safely advanced. + if (!neighbours || lever || connected || relative_rank(Us, s) >= RANK_5) backward = false; else { @@ -147,13 +147,11 @@ namespace { b = rank_bb(backmost_sq(Us, neighbours | stoppers)); // The pawn is backward when it cannot safely progress to that rank: - // either there is a stopper in the way on this rank, - // or there is a stopper on adjacent file which control the way to that rank + // either there is a stopper in the way on this rank, or there is a + // stopper on adjacent file which control the way to that rank. backward = (b | shift_bb(b & adjacent_files_bb(f))) & stoppers; } - assert(opposed | !stoppers | (pawn_attack_span(Us, s) & theirPawns)); - // Passed pawns will be properly scored in evaluation because we need // full attack info to evaluate them. Only the frontmost passed // pawn on each file is considered a true passed pawn. @@ -161,7 +159,7 @@ namespace { e->passedPawns[Us] |= s; // Score this pawn - if (isolated) + if (!neighbours) score -= Isolated[opposed][f]; else if (backward) From d9001776bc24e20dcba1567c1e8cf23be274757c Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Mon, 4 Apr 2016 14:52:19 -0400 Subject: [PATCH 4/6] BSG2_20160404_2 Fixed indent, order of the 4 conditions, and one use of pawnAttacksBB[s] instead of rank(s + Up) since it is less expensive. Connected is 72%, iso 19%, and once those 2 are covered, the remaining 9 % can be split between relative rank (84%) and lever (only 50%) Once we get in the else, "stoppers" is non empty 98% of the time, so there is no need to test for this. Bench under latest master is still 7525245 --- src/pawns.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index 6dd2fa1c907..e4cd687bc85 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -128,18 +128,18 @@ namespace { e->pawnAttacksSpan[Us] |= pawn_attack_span(Us, s); // Flag the pawn - opposed = theirPawns & forward_bb(Us, s); - stoppers = theirPawns & passed_pawn_mask(Us, s); - lever = theirPawns & pawnAttacksBB[s]; + opposed = theirPawns & forward_bb(Us, s); + stoppers = theirPawns & passed_pawn_mask(Us, s); + lever = theirPawns & pawnAttacksBB[s]; doubled = ourPawns & forward_bb(Us, s); neighbours = ourPawns & adjacent_files_bb(f); - phalanx = neighbours & rank_bb(s); - supported = neighbours & rank_bb(s - Up); - connected = supported | phalanx; + phalanx = neighbours & rank_bb(s); + supported = neighbours & rank_bb(s - Up); + connected = supported | phalanx; - // A pawn is backward when is behind all pawns of the same color on the + // A pawn is backward when it is behind all pawns of the same color on the // adjacent files and cannot be safely advanced. - if (!neighbours || lever || connected || relative_rank(Us, s) >= RANK_5) + if (connected || !neighbours || relative_rank(Us, s) >= RANK_5 || lever) backward = false; else { @@ -148,7 +148,7 @@ namespace { // The pawn is backward when it cannot safely progress to that rank: // either there is a stopper in the way on this rank, or there is a - // stopper on adjacent file which control the way to that rank. + // stopper on adjacent file which controls the way to that rank. backward = (b | shift_bb(b & adjacent_files_bb(f))) & stoppers; } @@ -166,7 +166,7 @@ namespace { score -= Backward[opposed]; else if (!supported) - score -= Unsupported[more_than_one(neighbours & rank_bb(s + Up))]; + score -= Unsupported[more_than_one(neighbours & pawnAttacksBB[s])]; if (connected) score += Connected[opposed][!!phalanx][more_than_one(supported)][relative_rank(Us, s)]; From 6c1c1f3a6d5ba7ae6df73245c01a1a22e6e5b2b3 Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Mon, 4 Apr 2016 15:44:47 -0400 Subject: [PATCH 5/6] BSG2_20160404_3 Reorder last condition. --- src/pawns.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index e4cd687bc85..7a4d7814def 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -139,7 +139,7 @@ namespace { // A pawn is backward when it is behind all pawns of the same color on the // adjacent files and cannot be safely advanced. - if (connected || !neighbours || relative_rank(Us, s) >= RANK_5 || lever) + if (connected || !neighbours || lever || relative_rank(Us, s) >= RANK_5) backward = false; else { From 0cdd1b2b80ea7b66d2fb802f2c7aa6880f2df302 Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Tue, 5 Apr 2016 11:25:30 -0400 Subject: [PATCH 6/6] BSG2_20160405_1 Remove the connected condition ! Same bench, no funcitonal change. And added an assert to make clear that when a pawn is backward, there is no neighbours on same rank or behind. --- src/pawns.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index 7a4d7814def..cc62053a425 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -139,7 +139,7 @@ namespace { // A pawn is backward when it is behind all pawns of the same color on the // adjacent files and cannot be safely advanced. - if (connected || !neighbours || lever || relative_rank(Us, s) >= RANK_5) + if (!neighbours || lever || relative_rank(Us, s) >= RANK_5) backward = false; else { @@ -150,6 +150,8 @@ namespace { // either there is a stopper in the way on this rank, or there is a // stopper on adjacent file which controls the way to that rank. backward = (b | shift_bb(b & adjacent_files_bb(f))) & stoppers; + + assert(!backward || !(pawn_attack_span(Them, s + Up) & neighbours)); } // Passed pawns will be properly scored in evaluation because we need