DroidFish: Use the SearchListener interface to communicate the search result (best move + ponder move) back to the DroidChessController.

This commit is contained in:
Peter Osterlund
2011-12-28 20:11:48 +00:00
parent 6165005464
commit 9d7d30b293
3 changed files with 87 additions and 74 deletions

View File

@@ -25,6 +25,7 @@ import java.util.ArrayList;
import org.petero.droidfish.BookOptions; import org.petero.droidfish.BookOptions;
import org.petero.droidfish.engine.cuckoochess.CuckooChessEngine; import org.petero.droidfish.engine.cuckoochess.CuckooChessEngine;
import org.petero.droidfish.gamelogic.Game;
import org.petero.droidfish.gamelogic.Move; import org.petero.droidfish.gamelogic.Move;
import org.petero.droidfish.gamelogic.MoveGen; import org.petero.droidfish.gamelogic.MoveGen;
import org.petero.droidfish.gamelogic.Pair; import org.petero.droidfish.gamelogic.Pair;
@@ -63,33 +64,11 @@ public class DroidComputerPlayer {
book = DroidBook.getInstance(); book = DroidBook.getInstance();
} }
/** Set engine and engine strength.
* @param engine Name of engine.
* @param strength Engine strength, 0 - 1000. */
public final synchronized void setEngineStrength(String engine, int strength) {
if (!engine.equals(this.engine)) {
shutdownEngine();
this.engine = engine;
startEngine();
}
this.strength = strength;
if (uciEngine != null)
uciEngine.setStrength(strength);
}
/** Return maximum number of PVs supported by engine. */ /** Return maximum number of PVs supported by engine. */
public final synchronized int getMaxPV() { public final synchronized int getMaxPV() {
return maxPV; return maxPV;
} }
/** Set engine multi-PV mode. */
public final synchronized void setNumPV(int numPV) {
if ((uciEngine != null) && (maxPV > 1)) {
int num = Math.min(maxPV, numPV);
uciEngine.setOption("MultiPV", num);
}
}
/** Set opening book options. */ /** Set opening book options. */
public final void setBookOptions(BookOptions options) { public final void setBookOptions(BookOptions options) {
book.setOptions(options); book.setOptions(options);
@@ -141,15 +120,18 @@ public class DroidComputerPlayer {
* @param ponderEnabled True if pondering is enabled in the GUI. Can affect time management. * @param ponderEnabled True if pondering is enabled in the GUI. Can affect time management.
* @param ponderMove Move to ponder, or null for non-ponder search. * @param ponderMove Move to ponder, or null for non-ponder search.
* @param engineThreads Number of engine threads to use, if supported by engine. * @param engineThreads Number of engine threads to use, if supported by engine.
* @return The computer player command, and the next ponder move. * @param engine Chess engine to use for searching.
* @param strength Engine strength setting.
*/ */
public final Pair<String,Move> doSearch(Position prevPos, ArrayList<Move> mList, public final void doSearch(Position prevPos, ArrayList<Move> mList,
Position currPos, boolean drawOffer, Position currPos, boolean drawOffer,
int wTime, int bTime, int inc, int movesToGo, int wTime, int bTime, int inc, int movesToGo,
boolean ponderEnabled, Move ponderMove, boolean ponderEnabled, Move ponderMove,
int engineThreads) { int engineThreads,
if (listener != null) String engine, int strength, Game g) {
listener.notifyBookInfo("", null); setEngineStrength(engine, strength);
setNumPV(1);
listener.notifyBookInfo("", null);
if (ponderMove != null) if (ponderMove != null)
mList.add(ponderMove); mList.add(ponderMove);
@@ -171,7 +153,8 @@ public class DroidComputerPlayer {
Move bookMove = book.getBookMove(currPos); Move bookMove = book.getBookMove(currPos);
if (bookMove != null) { if (bookMove != null) {
if (canClaimDraw(currPos, posHashList, posHashListSize, bookMove) == "") { if (canClaimDraw(currPos, posHashList, posHashListSize, bookMove) == "") {
return new Pair<String,Move>(TextIO.moveToString(currPos, bookMove, false), null); listener.notifySearchResult(g, TextIO.moveToString(currPos, bookMove, false), null);
return;
} }
} }
@@ -179,12 +162,14 @@ public class DroidComputerPlayer {
ArrayList<Move> moves = new MoveGen().pseudoLegalMoves(currPos); ArrayList<Move> moves = new MoveGen().pseudoLegalMoves(currPos);
moves = MoveGen.removeIllegal(currPos, moves); moves = MoveGen.removeIllegal(currPos, moves);
if (moves.size() == 0) { if (moves.size() == 0) {
return new Pair<String,Move>("", null); // User set up a position where computer has no valid moves. listener.notifySearchResult(g, "", null); // User set up a position where computer has no valid moves.
return;
} }
if (moves.size() == 1) { if (moves.size() == 1) {
Move bestMove = moves.get(0); Move bestMove = moves.get(0);
if (canClaimDraw(currPos, posHashList, posHashListSize, bestMove) == "") { if (canClaimDraw(currPos, posHashList, posHashListSize, bestMove) == "") {
return new Pair<String,Move>(TextIO.moveToUCIString(bestMove), null); listener.notifySearchResult(g, TextIO.moveToUCIString(bestMove), null);
return;
} }
} }
} }
@@ -231,7 +216,7 @@ public class DroidComputerPlayer {
if (drawOffer && !statIsMate && (statScore <= -300)) { if (drawOffer && !statIsMate && (statScore <= -300)) {
bestMove = "draw accept"; bestMove = "draw accept";
} }
return new Pair<String,Move>(bestMove, nextPonderMove); listener.notifySearchResult(g, bestMove, nextPonderMove);
} }
public boolean shouldStop = false; public boolean shouldStop = false;
@@ -250,16 +235,21 @@ public class DroidComputerPlayer {
* @param currPos Position to analyze. * @param currPos Position to analyze.
* @param drawOffer True if other side have offered draw. * @param drawOffer True if other side have offered draw.
* @param engineThreads Number of threads to use, or 0 for default value. * @param engineThreads Number of threads to use, or 0 for default value.
* @param engine Chess engine to use for searching
* @param numPV Multi-PV mode.
*/ */
public final void analyze(Position prevPos, ArrayList<Move> mList, Position currPos, public final void analyze(Position prevPos, ArrayList<Move> mList, Position currPos,
boolean drawOffer, int engineThreads) { boolean drawOffer, int engineThreads,
String engine, int numPV) {
setEngineStrength(engine, 1000);
setNumPV(numPV);
if (shouldStop) if (shouldStop)
return; return;
if (listener != null) { {
Pair<String, ArrayList<Move>> bi = getBookHints(currPos); Pair<String, ArrayList<Move>> bi = getBookHints(currPos);
listener.notifyBookInfo(bi.first, bi.second); listener.notifyBookInfo(bi.first, bi.second);
} }
// If no legal moves, there is nothing to analyze // If no legal moves, there is nothing to analyze
ArrayList<Move> moves = new MoveGen().pseudoLegalMoves(currPos); ArrayList<Move> moves = new MoveGen().pseudoLegalMoves(currPos);
moves = MoveGen.removeIllegal(currPos, moves); moves = MoveGen.removeIllegal(currPos, moves);
@@ -287,6 +277,28 @@ public class DroidComputerPlayer {
monitorEngine(currPos, null); monitorEngine(currPos, null);
} }
/** Set engine and engine strength.
* @param engine Name of engine.
* @param strength Engine strength, 0 - 1000. */
private final synchronized void setEngineStrength(String engine, int strength) {
if (!engine.equals(this.engine)) {
shutdownEngine();
this.engine = engine;
startEngine();
}
this.strength = strength;
if (uciEngine != null)
uciEngine.setStrength(strength);
}
/** Set engine multi-PV mode. */
private final synchronized void setNumPV(int numPV) {
if ((uciEngine != null) && (maxPV > 1)) {
int num = Math.min(maxPV, numPV);
uciEngine.setOption("MultiPV", num);
}
}
private final synchronized void startEngine() { private final synchronized void startEngine() {
boolean useCuckoo = engine.equals("cuckoochess"); boolean useCuckoo = engine.equals("cuckoochess");
if (uciEngine == null) { if (uciEngine == null) {
@@ -572,8 +584,6 @@ public class DroidComputerPlayer {
/** Notify GUI about search statistics. */ /** Notify GUI about search statistics. */
private final synchronized void notifyGUI(Position pos, Move ponderMove) { private final synchronized void notifyGUI(Position pos, Move ponderMove) {
if (listener == null)
return;
if (depthModified) { if (depthModified) {
listener.notifyDepth(statCurrDepth); listener.notifyDepth(statCurrDepth);
depthModified = false; depthModified = false;

View File

@@ -713,6 +713,11 @@ public class DroidChessController {
public void prefsChanged() { public void prefsChanged() {
setSearchInfo(); setSearchInfo();
} }
@Override
public void notifySearchResult(Game g, String cmd, Move ponder) {
makeComputerMove(g, cmd, ponder);
}
} }
private final void updateBookHints() { private final void updateBookHints() {
@@ -927,36 +932,11 @@ public class DroidChessController {
final Move fPonderMove = ponder ? ponderMove : null; final Move fPonderMove = ponder ? ponderMove : null;
computerThread = new Thread(new Runnable() { computerThread = new Thread(new Runnable() {
public void run() { public void run() {
computerPlayer.setEngineStrength(engine, strength); computerPlayer.doSearch(ph.first, ph.second, currPos, haveDrawOffer,
computerPlayer.setNumPV(1); wTime, bTime, inc, fMovesToGo,
final Pair<String,Move> pair = gui.ponderMode(), fPonderMove,
computerPlayer.doSearch(ph.first, ph.second, currPos, haveDrawOffer, gui.engineThreads(),
wTime, bTime, inc, fMovesToGo, engine, strength, g);
gui.ponderMode(), fPonderMove,
gui.engineThreads());
final String cmd = pair.first;
final Move ponder = pair.second;
final SearchStatus localSS = ss;
gui.runOnUIThread(new Runnable() {
public void run() {
synchronized (shutdownEngineLock) {
if (!localSS.searchResultWanted)
return;
Position oldPos = new Position(g.currPos());
g.processString(cmd);
ponderMove = ponder;
updateGameMode();
gui.computerMoveMade();
listener.clearSearchInfo();
stopComputerThinking();
stopAnalysis(); // To force analysis to restart for new position
updateComputeThreads(true);
setSelection();
setAnimMove(oldPos, g.getLastMove(), true);
updateGUI();
}
}
});
} }
}); });
listener.clearSearchInfo(); listener.clearSearchInfo();
@@ -965,6 +945,30 @@ public class DroidChessController {
} }
} }
private final void makeComputerMove(final Game g, final String cmd, final Move ponder) {
final SearchStatus localSS = ss;
gui.runOnUIThread(new Runnable() {
public void run() {
synchronized (shutdownEngineLock) {
if (!localSS.searchResultWanted)
return;
Position oldPos = new Position(g.currPos());
g.processString(cmd);
ponderMove = ponder;
updateGameMode();
gui.computerMoveMade();
listener.clearSearchInfo();
stopComputerThinking();
stopAnalysis(); // To force analysis to restart for new position
updateComputeThreads(true);
setSelection();
setAnimMove(oldPos, g.getLastMove(), true);
updateGUI();
}
}
});
}
private final synchronized boolean stopComputerThinking() { private final synchronized boolean stopComputerThinking() {
if (computerThread != null) { if (computerThread != null) {
computerPlayer.stopSearch(); computerPlayer.stopSearch();
@@ -990,12 +994,9 @@ public class DroidChessController {
final boolean alive = game.tree.getGameState() == GameState.ALIVE; final boolean alive = game.tree.getGameState() == GameState.ALIVE;
analysisThread = new Thread(new Runnable() { analysisThread = new Thread(new Runnable() {
public void run() { public void run() {
if (alive) { if (alive)
computerPlayer.setEngineStrength(engine, 1000);
computerPlayer.setNumPV(numPV);
computerPlayer.analyze(ph.first, ph.second, currPos, haveDrawOffer, computerPlayer.analyze(ph.first, ph.second, currPos, haveDrawOffer,
gui.engineThreads()); gui.engineThreads(), engine, numPV);
}
} }
}); });
listener.clearSearchInfo(); listener.clearSearchInfo();

View File

@@ -77,4 +77,6 @@ public interface SearchListener {
public void notifyPV(Position pos, ArrayList<PvInfo> pvInfo, boolean isPonder); public void notifyPV(Position pos, ArrayList<PvInfo> pvInfo, boolean isPonder);
public void notifyStats(int nodes, int nps, int time); public void notifyStats(int nodes, int nps, int time);
public void notifyBookInfo(String bookInfo, List<Move> moveList); public void notifyBookInfo(String bookInfo, List<Move> moveList);
public void notifySearchResult(Game g, String cmd, Move ponder);
} }