Skip to content

Commit

Permalink
Release 3.7c
Browse files Browse the repository at this point in the history
  • Loading branch information
bagaturchess committed May 3, 2023
1 parent 5e76885 commit 21dd9d4
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public class EngineConstants {
// Search reductions
public static final boolean ENABLE_NULL_MOVE = true;
public static final boolean ENABLE_LMR = true;
public static final boolean ENABLE_LMR_STATS = false;
public static final boolean ENABLE_LMR_STATS_DECISION = false;
public static final boolean ENABLE_LMR_STATS = true;
public static final boolean ENABLE_LMR_STATS_DECISION = true;
public static final boolean ENABLE_LMP = true;
public static final boolean ENABLE_LMP_STATS_DECISION = false;
public static final boolean ENABLE_LMP_STATS_DECISION = true;
public static final boolean ENABLE_PVS = true;
public static final boolean ENABLE_MATE_DISTANCE_PRUNING = true;
public static final boolean ENABLE_STATIC_NULL_MOVE = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,31 @@

public final class MoveGenerator {



private static final boolean CLEAR_TABLES_ON_NEW_SEARCH = true;
public static boolean USE_COUNTER_MOVES_COUNTS = true;
public static boolean USE_ContinuationHistory = true;
private static final boolean BUILD_EXACT_STATS = false;

public static final int MOVE_SCORE_SCALE = 100;


private static final int LMR_STAT_MULTIPLIER = 10 * MOVE_SCORE_SCALE;

//LMR_DEVIATION_MULTIPLIER must be between 0 and 2. Values more than 2 actually means that the LMR optimization is always performed. Value 0 means that it is executed in around 50% of the cases.
private static final double LMR_DEVIATION_MULTIPLIER = 2; //1d; //1.5; //2; //1.25; //1.5; //1.75 //1.5 //0 //1.25 //2.5 //1 //4
//Bigger value of LMR_DEVIATION_MULTIPLIER means less LMR skips.
//LMR_DEVIATION_MULTIPLIER is senseful between 0 and 2.
//The value of LMR_DEVIATION_MULTIPLIER equal to 2, leads to skip of LMR reductions for top 5% of the moves sorted by their LMR rate.
//We select 5% in order to keep the skip rate in the frame of the standard deviation.
// Values more than 2 actually means that the LMR optimization is always performed and there are no skips. Value 0 means that it is executed in around 50% of the cases.
private static final double LMR_DEVIATION_MULTIPLIER = 4;

private final long[][] LMR_ALL = new long[2][64 * 64];
private final long[][] LMR_BELOW_ALPHA = new long[2][64 * 64];
private final long[][] LMR_ABOVE_ALPHA = new long[2][64 * 64];
private VarStatistic[] lmrBelowAlphaAVGScores = new VarStatistic[2];
private VarStatistic[] lmrAboveAlphaAVGScores = new VarStatistic[2];

private static final boolean BUILD_EXACT_STATS = false;

private static final double LMR_RATE_THREASHOLD_ABOVE_ALPHA = 0.95; //Top X%
private static final double LMR_RATE_THREASHOLD_BELOW_ALPHA = 0.0001; //Top Y%
private static final long[][] LMR_STATS_COUNTER_ABOVE_ALPHA = new long[2][LMR_STAT_MULTIPLIER + 1];
Expand All @@ -51,11 +61,10 @@ public final class MoveGenerator {
private int currentPly;


private static final boolean CLEAR_TABLES_ON_NEW_SEARCH = false;

private final IBetaCutoffMoves[][] KILLER_MOVES = new IBetaCutoffMoves[2][EngineConstants.MAX_PLIES];
private final IBetaCutoffMoves[][][] COUNTER_MOVES_LASTIN = new IBetaCutoffMoves[2][7][64];

public static boolean USE_COUNTER_MOVES_COUNTS = false;
private final IBetaCutoffMoves[][][] COUNTER_MOVES_COUNTS = new IBetaCutoffMoves[2][7][64];

private final long[][] HH_MOVES = new long[2][64 * 64];
Expand All @@ -64,8 +73,6 @@ public final class MoveGenerator {
private final long[][][] HH_MOVES1 = new long[2][7][64];
private final long[][][] BF_MOVES1 = new long[2][7][64];

public static boolean USE_ContinuationHistory = true;

private final ContinuationHistory[] HH_ContinuationHistory = new ContinuationHistory[2];
private final ContinuationHistory[] BF_ContinuationHistory = new ContinuationHistory[2];

Expand Down Expand Up @@ -132,8 +139,6 @@ public MoveGenerator() {


clearHistoryHeuristics();


}


Expand Down Expand Up @@ -176,19 +181,21 @@ public void clearHistoryHeuristics() {
Arrays.fill(BF_MOVES1[BLACK][QUEEN], 1);
Arrays.fill(BF_MOVES1[BLACK][KING], 1);


if (CLEAR_TABLES_ON_NEW_SEARCH) {

//No sense to clear it as they are last in and will be overided from the new search moves
/*for (int i = 0; i < COUNTER_MOVES_LASTIN.length; i++) {
for (int i = 0; i < COUNTER_MOVES_LASTIN.length; i++) {
for (int j = 0; j < COUNTER_MOVES_LASTIN[i].length; j++) {
for (int j = 0; j < COUNTER_MOVES_LASTIN[i].length; j++) {
for (int k = 0; k < COUNTER_MOVES_LASTIN[i][j].length; k++) {
for (int k = 0; k < COUNTER_MOVES_LASTIN[i][j].length; k++) {

COUNTER_MOVES_LASTIN[i][j][k].clear();
}
COUNTER_MOVES_LASTIN[i][j][k].clear();
}
}

}*/

if (USE_COUNTER_MOVES_COUNTS) {

for (int i = 0; i < COUNTER_MOVES_COUNTS.length; i++) {
Expand All @@ -203,14 +210,15 @@ public void clearHistoryHeuristics() {
}
}

if (USE_ContinuationHistory) {
//Do not clear it, as in version 3.0 which is the strongest this structure is permanent
/*if (USE_ContinuationHistory) {
HH_ContinuationHistory[WHITE].clear();
HH_ContinuationHistory[BLACK].clear();
BF_ContinuationHistory[WHITE].clear();
BF_ContinuationHistory[BLACK].clear();
}
}*/
}

Arrays.fill(LMR_ALL[WHITE], 0);
Expand Down Expand Up @@ -400,12 +408,9 @@ private int getLMR_Rate_internal(final int color, final int fromToIndex) {

if (count_all == 0) {

return 1 * LMR_STAT_MULTIPLIER; //Force search to explorer all moves at least once as fast as possible
return 0;
}


//return (int) (LMR_STAT_MULTIPLIER * (LMR_ABOVE_ALPHA[color][fromToIndex]) / LMR_ALL[color][fromToIndex]);

return (int) ((LMR_STAT_MULTIPLIER * (count_all - LMR_BELOW_ALPHA[color][fromToIndex])) / count_all);
}

Expand All @@ -424,11 +429,11 @@ public int getLMR_ThreasholdPointer_AboveAlpha(int color) {
return lmr_rate_pointer_above_alpha[color];

} else {

if (EngineConstants.ENABLE_LMR_STATS_DECISION || EngineConstants.ENABLE_LMP_STATS_DECISION) {

int pointer_above_alpha = (int) (lmrAboveAlphaAVGScores[color].getEntropy() + LMR_DEVIATION_MULTIPLIER * lmrAboveAlphaAVGScores[color].getDisperse());

//System.out.println("AboveAlpha: color=" + color + ", Entropy=" + lmrAboveAlphaAVGScores[color].getEntropy() + ", Disperse=" + lmrAboveAlphaAVGScores[color].getDisperse());

return pointer_above_alpha;
Expand Down
4 changes: 4 additions & 0 deletions Resources/doc/engine/txt/release_notes_BagaturEngine.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Version 3.7c (1 May 2023)
* Keep Continuation History tables between the searches and not clear them, like in version 3.0.
* Enable again the LMR reduction's skip rate with a high value in order to not affect CPU performance.

Version 3.7b (25 March 2023)
* Less aggressive randomization of move order before sorting.

Expand Down
63 changes: 52 additions & 11 deletions Search/src/bagaturchess/search/impl/alg/impl1/Search_PVS_NWS.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ public class Search_PVS_NWS extends SearchImpl {
//private static final double SQRT_2PI = Math.sqrt(2 * Math.PI);
//private static final double RECIPROCAL_4PI = 1 / (double) (4 * Math.PI);

private long lmr_all;
private long lmr_allowed;
private long lmr_done;


public Search_PVS_NWS(Object[] args) {

Expand Down Expand Up @@ -1055,7 +1059,10 @@ If the engine needs to know the DTZ value (which is only necessary when a TB roo

if (phase == PHASE_QUIET
&& (!EngineConstants.ENABLE_LMP_STATS_DECISION
|| (EngineConstants.ENABLE_LMP_STATS_DECISION && moveGen.getLMR_Rate(cb.colorToMove, move) <= moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMove)))
|| (EngineConstants.ENABLE_LMP_STATS_DECISION
&& moveGen.getLMR_Rate(cb.colorToMove, move) <= moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMove)
)
)
) {

if (EngineConstants.ENABLE_LMP
Expand Down Expand Up @@ -1126,18 +1133,41 @@ If the engine needs to know the DTZ value (which is only necessary when a TB roo
);
*/

boolean doLMR = depth >= 2
&& movesPerformed_attacks + movesPerformed_quiet > 1
//&& !env.getBitboard().getMoveOps().isCaptureOrPromotion(move)
//&& (phase == PHASE_QUIET || phase == PHASE_KILLER_1 || phase == PHASE_KILLER_2)
&& phase == PHASE_QUIET
;

boolean LMR_allowed = moveGen.getLMR_Rate(cb.colorToMoveInverse, move) <= moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMoveInverse);

//System.out.println("lmr_allowed=" + lmr_allowed + ", moveGen.getLMR_Rate(cb.colorToMoveInverse, move)=" + moveGen.getLMR_Rate(cb.colorToMoveInverse, move) + ", moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMoveInverse)=" + moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMoveInverse));

lmr_all++;

if (LMR_allowed) {

lmr_allowed++;
}

boolean doLMR = depth >= 2
&& movesPerformed_attacks + movesPerformed_quiet > 1
//&& !env.getBitboard().getMoveOps().isCaptureOrPromotion(move)
//&& (phase == PHASE_QUIET || phase == PHASE_KILLER_1 || phase == PHASE_KILLER_2)
&& phase == PHASE_QUIET;

int reduction = 1;
if (doLMR
&& (!EngineConstants.ENABLE_LMR_STATS_DECISION
|| EngineConstants.ENABLE_LMR_STATS_DECISION && (Math.random() <= 0.10 || moveGen.getLMR_Rate(cb.colorToMoveInverse, move) <= moveGen.getLMR_ThreasholdPointer_BelowAlpha(cb.colorToMoveInverse)))
) {

if (doLMR &&
(!EngineConstants.ENABLE_LMR_STATS_DECISION
|| (EngineConstants.ENABLE_LMR_STATS_DECISION && LMR_allowed)
)
) {

lmr_done++;

//float lmr_done_rate = lmr_done / (float) lmr_all;
//float lmr_allowed_rate = lmr_allowed / (float) lmr_all;
//System.out.println("lmr_done_rate=" + lmr_done_rate + ", lmr_allowed_rate=" + lmr_allowed_rate);

//TODO: branching factor calculation in this way is an easy approximation, maybe not perfect.
//lmr_done is between 0 and 0.5, because the first move is never reduced by LMR.
//System.out.println("Search branching factor: " + 1f / (lmr_done / (float) lmr_all));

reduction = LMR_TABLE[Math.min(depth, 63)][Math.min(movesPerformed_attacks + movesPerformed_quiet, 63)];

Expand All @@ -1150,6 +1180,17 @@ If the engine needs to know the DTZ value (which is only necessary when a TB roo
reduction += multiCutReduction;

reduction = Math.min(depth - 1, Math.max(reduction, 1));

} else {

if (doLMR && !LMR_allowed) {

//Makes the magic of the controlled LMR skip logic:
//If this code is not here, than step by step the overall LMR rate goes down to 0 and search becomes extremely shallow (without LMR optimization at all).
//It increases the statistics of this move so next time it will be more likely this move to be reduced by LMR
moveGen.addLMR_All(cb.colorToMoveInverse, move, 1);
moveGen.addLMR_BelowAlpha(cb.colorToMoveInverse, move, 1);
}
}

try {
Expand Down
2 changes: 1 addition & 1 deletion UCI/src/bagaturchess/uci/impl/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
public class Protocol {


public static final String COMMAND_TO_GUI_ID_VERSION_STR = "3.7b";
public static final String COMMAND_TO_GUI_ID_VERSION_STR = "3.7c";

public static final String COMMAND_TO_ENGINE_UCI_STR = "uci";
public static final String COMMAND_TO_ENGINE_ISREADY_STR = "isready";
Expand Down

0 comments on commit 21dd9d4

Please sign in to comment.