mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2024-11-23 11:31:33 +01:00
Implement maxNPS UCI option for CuckooChess
This is an alternative way to limit the engine strength. It also has the advantage of reducing heat and battery drain.
This commit is contained in:
parent
29d605af99
commit
67e03495dc
|
@ -73,6 +73,7 @@ public class EngineControl {
|
||||||
|
|
||||||
// Reduced strength variables
|
// Reduced strength variables
|
||||||
private int strength = 1000;
|
private int strength = 1000;
|
||||||
|
private int maxNPS = 0;
|
||||||
private long randomSeed = 0;
|
private long randomSeed = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,7 +227,7 @@ public class EngineControl {
|
||||||
sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
||||||
sc.timeLimit(minTimeLimit, maxTimeLimit);
|
sc.timeLimit(minTimeLimit, maxTimeLimit);
|
||||||
sc.setListener(new SearchListener(os));
|
sc.setListener(new SearchListener(os));
|
||||||
sc.setStrength(strength, randomSeed);
|
sc.setStrength(strength, randomSeed, maxNPS);
|
||||||
MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
|
MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
|
||||||
MoveGen.removeIllegal(pos, moves);
|
MoveGen.removeIllegal(pos, moves);
|
||||||
if ((searchMoves != null) && (searchMoves.size() > 0))
|
if ((searchMoves != null) && (searchMoves.size() > 0))
|
||||||
|
@ -374,6 +375,7 @@ public class EngineControl {
|
||||||
os.printf("option name UCI_EngineAbout type string default %s by Peter Osterlund, see %s%n",
|
os.printf("option name UCI_EngineAbout type string default %s by Peter Osterlund, see %s%n",
|
||||||
ComputerPlayer.engineName, "http://hem.bredband.net/petero2b/javachess/index.html");
|
ComputerPlayer.engineName, "http://hem.bredband.net/petero2b/javachess/index.html");
|
||||||
os.print("option name Strength type spin default 1000 min 0 max 1000\n");
|
os.print("option name Strength type spin default 1000 min 0 max 1000\n");
|
||||||
|
os.print("option name maxNPS type spin default 0 min 0 max 10000000\n");
|
||||||
|
|
||||||
for (String pName : Parameters.instance().getParamNames()) {
|
for (String pName : Parameters.instance().getParamNames()) {
|
||||||
ParamBase p = Parameters.instance().getParam(pName);
|
ParamBase p = Parameters.instance().getParam(pName);
|
||||||
|
@ -424,6 +426,8 @@ public class EngineControl {
|
||||||
analyseMode = Boolean.parseBoolean(optionValue);
|
analyseMode = Boolean.parseBoolean(optionValue);
|
||||||
} else if (optionName.equals("strength")) {
|
} else if (optionName.equals("strength")) {
|
||||||
strength = Integer.parseInt(optionValue);
|
strength = Integer.parseInt(optionValue);
|
||||||
|
} else if (optionName.equals("maxnps")) {
|
||||||
|
maxNPS = Integer.parseInt(optionValue);
|
||||||
} else {
|
} else {
|
||||||
Parameters.instance().set(optionName, optionValue);
|
Parameters.instance().set(optionName, optionValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ public class Search {
|
||||||
|
|
||||||
// Reduced strength variables
|
// Reduced strength variables
|
||||||
private int strength = 1000; // Strength (0-1000)
|
private int strength = 1000; // Strength (0-1000)
|
||||||
|
private int maxNPS = 0; // If > 0, reduce strength by limiting NPS
|
||||||
private boolean weak = false; // Set to strength < 1000
|
private boolean weak = false; // Set to strength < 1000
|
||||||
private long randomSeed = 0;
|
private long randomSeed = 0;
|
||||||
|
|
||||||
|
@ -170,12 +171,16 @@ public class Search {
|
||||||
maxTimeMillis = maxTimeLimit;
|
maxTimeMillis = maxTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
final public void setStrength(int strength, long randomSeed) {
|
final public void setStrength(int strength, long randomSeed, int maxNPS) {
|
||||||
if (strength < 0) strength = 0;
|
if (strength < 0) strength = 0;
|
||||||
if (strength > 1000) strength = 1000;
|
if (strength > 1000) strength = 1000;
|
||||||
this.strength = strength;
|
this.strength = strength;
|
||||||
weak = strength < 1000;
|
weak = strength < 1000;
|
||||||
this.randomSeed = randomSeed;
|
this.randomSeed = randomSeed;
|
||||||
|
this.maxNPS = maxNPS;
|
||||||
|
nodesBetweenTimeCheck = 5000;
|
||||||
|
if (maxNPS > 0)
|
||||||
|
nodesBetweenTimeCheck = Math.min(Math.max(maxNPS / 100, 1), nodesBetweenTimeCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
final public Move iterativeDeepening(MoveGen.MoveList scMovesIn,
|
final public Move iterativeDeepening(MoveGen.MoveList scMovesIn,
|
||||||
|
@ -264,6 +269,9 @@ public class Search {
|
||||||
mi, "-", alpha, beta, "-", "-");
|
mi, "-", alpha, beta, "-", "-");
|
||||||
System.out.printf("%-6s...\n", TextIO.moveToUCIString(m)); */
|
System.out.printf("%-6s...\n", TextIO.moveToUCIString(m)); */
|
||||||
pos.makeMove(m, ui);
|
pos.makeMove(m, ui);
|
||||||
|
nodes++;
|
||||||
|
totalNodes++;
|
||||||
|
nodesToGo--;
|
||||||
SearchTreeInfo sti = searchTreeInfo[0];
|
SearchTreeInfo sti = searchTreeInfo[0];
|
||||||
sti.currentMove = m;
|
sti.currentMove = m;
|
||||||
sti.lmr = lmrS;
|
sti.lmr = lmrS;
|
||||||
|
@ -301,6 +309,9 @@ public class Search {
|
||||||
nodes = qNodes = 0;
|
nodes = qNodes = 0;
|
||||||
posHashList[posHashListSize++] = pos.zobristHash();
|
posHashList[posHashListSize++] = pos.zobristHash();
|
||||||
pos.makeMove(m, ui);
|
pos.makeMove(m, ui);
|
||||||
|
nodes++;
|
||||||
|
totalNodes++;
|
||||||
|
nodesToGo--;
|
||||||
int score2 = -negaScout(-beta, -score, 1, depthS - plyScale, -1, givesCheck);
|
int score2 = -negaScout(-beta, -score, 1, depthS - plyScale, -1, givesCheck);
|
||||||
score = Math.max(score, score2);
|
score = Math.max(score, score2);
|
||||||
nodesThisMove += nodes + qNodes;
|
nodesThisMove += nodes + qNodes;
|
||||||
|
@ -320,6 +331,9 @@ public class Search {
|
||||||
nodes = qNodes = 0;
|
nodes = qNodes = 0;
|
||||||
posHashList[posHashListSize++] = pos.zobristHash();
|
posHashList[posHashListSize++] = pos.zobristHash();
|
||||||
pos.makeMove(m, ui);
|
pos.makeMove(m, ui);
|
||||||
|
nodes++;
|
||||||
|
totalNodes++;
|
||||||
|
nodesToGo--;
|
||||||
score = -negaScout(-score, -alpha, 1, depthS - plyScale, -1, givesCheck);
|
score = -negaScout(-score, -alpha, 1, depthS - plyScale, -1, givesCheck);
|
||||||
nodesThisMove += nodes + qNodes;
|
nodesThisMove += nodes + qNodes;
|
||||||
posHashListSize--;
|
posHashListSize--;
|
||||||
|
@ -459,7 +473,7 @@ public class Search {
|
||||||
long idx = log.logNodeStart(sti.nodeIdx, sti.currentMove, alpha, beta, ply, depth/plyScale);
|
long idx = log.logNodeStart(sti.nodeIdx, sti.currentMove, alpha, beta, ply, depth/plyScale);
|
||||||
searchTreeInfo[ply].nodeIdx = idx;
|
searchTreeInfo[ply].nodeIdx = idx;
|
||||||
}
|
}
|
||||||
if (--nodesToGo <= 0) {
|
if (nodesToGo <= 0) {
|
||||||
nodesToGo = nodesBetweenTimeCheck;
|
nodesToGo = nodesBetweenTimeCheck;
|
||||||
long tNow = System.currentTimeMillis();
|
long tNow = System.currentTimeMillis();
|
||||||
long timeLimit = searchNeedMoreTime ? maxTimeMillis : minTimeMillis;
|
long timeLimit = searchNeedMoreTime ? maxTimeMillis : minTimeMillis;
|
||||||
|
@ -467,6 +481,15 @@ public class Search {
|
||||||
((maxNodes >= 0) && (totalNodes >= maxNodes))) {
|
((maxNodes >= 0) && (totalNodes >= maxNodes))) {
|
||||||
throw new StopSearch();
|
throw new StopSearch();
|
||||||
}
|
}
|
||||||
|
if (maxNPS > 0) {
|
||||||
|
long time = tNow - tStart;
|
||||||
|
if (totalNodes * 1000.0 > maxNPS * Math.max(1, time)) {
|
||||||
|
long wantedTime = totalNodes * 1000 / maxNPS;
|
||||||
|
long sleepTime = wantedTime - time;
|
||||||
|
if (sleepTime > 0)
|
||||||
|
try { Thread.sleep(sleepTime); } catch (InterruptedException ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tNow - tLastStats >= 1000) {
|
if (tNow - tLastStats >= 1000) {
|
||||||
notifyStats();
|
notifyStats();
|
||||||
}
|
}
|
||||||
|
@ -797,6 +820,7 @@ public class Search {
|
||||||
pos.makeMove(m, ui);
|
pos.makeMove(m, ui);
|
||||||
nodes++;
|
nodes++;
|
||||||
totalNodes++;
|
totalNodes++;
|
||||||
|
nodesToGo--;
|
||||||
sti.currentMove = m;
|
sti.currentMove = m;
|
||||||
/* long nodes0 = nodes;
|
/* long nodes0 = nodes;
|
||||||
long qNodes0 = qNodes;
|
long qNodes0 = qNodes;
|
||||||
|
@ -1021,6 +1045,7 @@ public class Search {
|
||||||
pos.makeMove(m, ui);
|
pos.makeMove(m, ui);
|
||||||
qNodes++;
|
qNodes++;
|
||||||
totalNodes++;
|
totalNodes++;
|
||||||
|
nodesToGo--;
|
||||||
score = -quiesce(-beta, -alpha, ply + 1, depth - 1, nextInCheck);
|
score = -quiesce(-beta, -alpha, ply + 1, depth - 1, nextInCheck);
|
||||||
pos.unMakeMove(m, ui);
|
pos.unMakeMove(m, ui);
|
||||||
if (score > bestScore) {
|
if (score > bestScore) {
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class DroidEngineControl {
|
||||||
|
|
||||||
// Reduced strength variables
|
// Reduced strength variables
|
||||||
private int strength = 1000;
|
private int strength = 1000;
|
||||||
|
private int maxNPS = 0;
|
||||||
private long randomSeed = 0;
|
private long randomSeed = 0;
|
||||||
private Random rndGen = new Random();
|
private Random rndGen = new Random();
|
||||||
|
|
||||||
|
@ -224,8 +225,8 @@ public class DroidEngineControl {
|
||||||
sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
sc = new Search(pos, posHashList, posHashListSize, tt, ht);
|
||||||
sc.timeLimit(minTimeLimit, maxTimeLimit);
|
sc.timeLimit(minTimeLimit, maxTimeLimit);
|
||||||
sc.setListener(new SearchListener(os));
|
sc.setListener(new SearchListener(os));
|
||||||
sc.setStrength(strength, randomSeed);
|
sc.setStrength(strength, randomSeed, maxNPS);
|
||||||
sc.nodesBetweenTimeCheck = 500;
|
sc.nodesBetweenTimeCheck = Math.min(500, sc.nodesBetweenTimeCheck);
|
||||||
MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
|
MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
|
||||||
MoveGen.removeIllegal(pos, moves);
|
MoveGen.removeIllegal(pos, moves);
|
||||||
if ((searchMoves != null) && (searchMoves.size() > 0))
|
if ((searchMoves != null) && (searchMoves.size() > 0))
|
||||||
|
@ -367,9 +368,10 @@ public class DroidEngineControl {
|
||||||
os.printLine("option name OwnBook type check default false");
|
os.printLine("option name OwnBook type check default false");
|
||||||
os.printLine("option name Ponder type check default true");
|
os.printLine("option name Ponder type check default true");
|
||||||
os.printLine("option name UCI_AnalyseMode type check default false");
|
os.printLine("option name UCI_AnalyseMode type check default false");
|
||||||
os.printLine("option name UCI_EngineAbout type string default %s by Peter Osterlund, see http://web.comhem.se/petero2home/javachess/index.html",
|
os.printLine("option name UCI_EngineAbout type string default %s by Peter Osterlund, see http://hem.bredband.net/petero2b/javachess/index.html",
|
||||||
ComputerPlayer.engineName);
|
ComputerPlayer.engineName);
|
||||||
os.printLine("option name Strength type spin default 1000 min 0 max 1000");
|
os.printLine("option name Strength type spin default 1000 min 0 max 1000");
|
||||||
|
os.printLine("option name maxNPS type spin default 0 min 0 max 10000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
final void setOption(String optionName, String optionValue) {
|
final void setOption(String optionName, String optionValue) {
|
||||||
|
@ -385,6 +387,8 @@ public class DroidEngineControl {
|
||||||
analyseMode = Boolean.parseBoolean(optionValue);
|
analyseMode = Boolean.parseBoolean(optionValue);
|
||||||
} else if (optionName.equals("strength")) {
|
} else if (optionName.equals("strength")) {
|
||||||
strength = Integer.parseInt(optionValue);
|
strength = Integer.parseInt(optionValue);
|
||||||
|
} else if (optionName.equals("maxnps")) {
|
||||||
|
maxNPS = Integer.parseInt(optionValue);
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException ignore) {
|
} catch (NumberFormatException ignore) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user