mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-03-11 15:58:08 +01:00
DroidFish: Made it possible to change the engine hash table size.
This commit is contained in:
parent
bb3cff5298
commit
04f1225d3e
@ -2,6 +2,7 @@
|
||||
<resources>
|
||||
<string name="app_name">DroidFish</string>
|
||||
<string name="engine_threads_default">1</string>
|
||||
<string name="engine_hash_default">16</string>
|
||||
<string name="moves_per_session_default">60</string>
|
||||
<string name="time_control_default">120000</string>
|
||||
<string name="time_increment_default">0</string>
|
||||
@ -220,6 +221,8 @@ you are not actively using the program.\
|
||||
<string name="prefs_ponderMode_summary">Let engine think while waiting for opponent\'s move. Supported by most engines.</string>
|
||||
<string name="prefs_threads_title">Threads</string>
|
||||
<string name="prefs_threads_summary">Number of engine threads (CPU cores) to use. Not supported by all engines.</string>
|
||||
<string name="prefs_hash_title">Hash Table</string>
|
||||
<string name="prefs_hash_summary">Hash table size in megabytes</string>
|
||||
<string name="prefs_time_control">Time Control</string>
|
||||
<string name="prefs_movesPerSession_title">Moves</string>
|
||||
<string name="prefs_movesPerSession_summary">Number of moves between time controls</string>
|
||||
@ -364,6 +367,18 @@ you are not actively using the program.\
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
</string-array>
|
||||
<string-array name="engine_hash_texts">
|
||||
<item>16 MB</item>
|
||||
<item>32 MB</item>
|
||||
<item>64 MB</item>
|
||||
<item>128 MB</item>
|
||||
</string-array>
|
||||
<string-array name="engine_hash_values">
|
||||
<item>16</item>
|
||||
<item>32</item>
|
||||
<item>64</item>
|
||||
<item>128</item>
|
||||
</string-array>
|
||||
<string-array name="moves_per_session_texts">
|
||||
<item>Whole Game</item>
|
||||
<item>1 move</item>
|
||||
|
@ -44,7 +44,15 @@
|
||||
android:entries="@array/engine_threads_texts"
|
||||
android:defaultValue="@string/engine_threads_default">
|
||||
</ListPreference>
|
||||
</PreferenceCategory>
|
||||
<ListPreference
|
||||
android:key="hashMB"
|
||||
android:title="@string/prefs_hash_title"
|
||||
android:summary="@string/prefs_hash_summary"
|
||||
android:entryValues="@array/engine_hash_values"
|
||||
android:entries="@array/engine_hash_texts"
|
||||
android:defaultValue="@string/engine_hash_default">
|
||||
</ListPreference>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:title="@string/prefs_time_control">
|
||||
<ListPreference
|
||||
|
@ -149,7 +149,6 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
// FIXME!!! Better behavior if engine is terminated. How exactly?
|
||||
// FIXME!!! Handle PGN non-file intents with more than one game.
|
||||
// FIXME!!! File load/save of FEN data
|
||||
// FIXME!!! Make engine hash size configurable.
|
||||
|
||||
private ChessBoard cb;
|
||||
private static DroidChessController ctrl = null;
|
||||
@ -191,7 +190,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
private final static String gtbDefaultDir = "DroidFish" + File.separator + "gtb";
|
||||
private BookOptions bookOptions = new BookOptions();
|
||||
private PGNOptions pgnOptions = new PGNOptions();
|
||||
private EGTBOptions egtbOptions = new EGTBOptions();
|
||||
private EngineOptions engineOptions = new EngineOptions();
|
||||
|
||||
private long lastVisibleMillis; // Time when GUI became invisible. 0 if currently visible.
|
||||
private long lastComputationMillis; // Time when engine last showed that it was computing.
|
||||
@ -783,10 +782,11 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
bookOptions.random = (settings.getInt("bookRandom", 500) - 500) * (3.0 / 500);
|
||||
setBookOptions();
|
||||
|
||||
egtbOptions.hints = settings.getBoolean("tbHints", false);
|
||||
egtbOptions.hintsEdit = settings.getBoolean("tbHintsEdit", false);
|
||||
egtbOptions.rootProbe = settings.getBoolean("tbRootProbe", true);
|
||||
egtbOptions.engineProbe = settings.getBoolean("tbEngineProbe", true);
|
||||
engineOptions.hashMB = getHashMB();
|
||||
engineOptions.hints = settings.getBoolean("tbHints", false);
|
||||
engineOptions.hintsEdit = settings.getBoolean("tbHintsEdit", false);
|
||||
engineOptions.rootProbe = settings.getBoolean("tbRootProbe", true);
|
||||
engineOptions.engineProbe = settings.getBoolean("tbEngineProbe", true);
|
||||
String gtbPath = settings.getString("gtbPath", "");
|
||||
gtbPath = gtbPath.trim();
|
||||
if (gtbPath.length() == 0) {
|
||||
@ -794,8 +794,8 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
String sep = File.separator;
|
||||
gtbPath = extDir.getAbsolutePath() + sep + gtbDefaultDir;
|
||||
}
|
||||
egtbOptions.gtbPath = gtbPath;
|
||||
setEgtbOptions();
|
||||
engineOptions.gtbPath = gtbPath;
|
||||
setEngineOptions();
|
||||
setEgtbHints(cb.getSelectedSquare());
|
||||
|
||||
updateThinkingInfo();
|
||||
@ -820,6 +820,19 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
ctrl.prefsChanged();
|
||||
}
|
||||
|
||||
/** Get hash size in MB from settings, but reduce size to an amount that the device can handle. */
|
||||
private final int getHashMB() {
|
||||
int hashMB = getIntSetting("hashMB", 16);
|
||||
if (hashMB > 16) {
|
||||
int maxMem = (int)(Runtime.getRuntime().maxMemory() / (1024*1024));
|
||||
if (maxMem < 16)
|
||||
maxMem = 16;
|
||||
if (hashMB > maxMem)
|
||||
hashMB = maxMem;
|
||||
}
|
||||
return hashMB;
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
boolean largeButtons = settings.getBoolean("largeButtons", false);
|
||||
Resources r = getResources();
|
||||
@ -918,14 +931,14 @@ public class DroidFish extends Activity implements GUIInterface {
|
||||
|
||||
private boolean egtbForceReload = false;
|
||||
|
||||
private final void setEgtbOptions() {
|
||||
ctrl.setEgtbOptions(new EGTBOptions(egtbOptions));
|
||||
Probe.getInstance().setPath(egtbOptions.gtbPath, egtbForceReload);
|
||||
private final void setEngineOptions() {
|
||||
ctrl.setEngineOptions(new EngineOptions(engineOptions));
|
||||
Probe.getInstance().setPath(engineOptions.gtbPath, egtbForceReload);
|
||||
egtbForceReload = false;
|
||||
}
|
||||
|
||||
private final void setEgtbHints(int sq) {
|
||||
if (!egtbOptions.hints || (sq < 0)) {
|
||||
if (!engineOptions.hints || (sq < 0)) {
|
||||
cb.setSquareDecorations(null);
|
||||
return;
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
package org.petero.droidfish;
|
||||
|
||||
/** Endgame tablebase probing options. */
|
||||
public final class EGTBOptions {
|
||||
/** Engine options, including endgame tablebase probing options. */
|
||||
public final class EngineOptions {
|
||||
public int hashMB; // Engine hash table size in MB
|
||||
public boolean hints; // Hints when playing/analyzing
|
||||
public boolean hintsEdit; // Hints in "edit board" mode
|
||||
public boolean rootProbe; // Only search optimal moves at root
|
||||
public boolean engineProbe; // Let engine use EGTB
|
||||
public String gtbPath; // GTB directory path
|
||||
|
||||
public EGTBOptions() {
|
||||
public EngineOptions() {
|
||||
hashMB = 16;
|
||||
hints = false;
|
||||
hintsEdit = false;
|
||||
rootProbe = false;
|
||||
@ -16,7 +18,8 @@ public final class EGTBOptions {
|
||||
gtbPath = "";
|
||||
}
|
||||
|
||||
public EGTBOptions(EGTBOptions other) {
|
||||
public EngineOptions(EngineOptions other) {
|
||||
hashMB = other.hashMB;
|
||||
hints = other.hints;
|
||||
hintsEdit = other.hintsEdit;
|
||||
rootProbe = other.rootProbe;
|
||||
@ -28,9 +31,10 @@ public final class EGTBOptions {
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || (o.getClass() != this.getClass()))
|
||||
return false;
|
||||
EGTBOptions other = (EGTBOptions)o;
|
||||
EngineOptions other = (EngineOptions)o;
|
||||
|
||||
return ((hints == other.hints) &&
|
||||
return ((hashMB == other.hashMB) &&
|
||||
(hints == other.hints) &&
|
||||
(hintsEdit == other.hintsEdit) &&
|
||||
(rootProbe == other.rootProbe) &&
|
||||
(engineProbe == other.engineProbe) &&
|
@ -23,7 +23,7 @@ import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
import org.petero.droidfish.book.BookOptions;
|
||||
import org.petero.droidfish.book.DroidBook;
|
||||
import org.petero.droidfish.gamelogic.Move;
|
||||
@ -47,7 +47,7 @@ public class DroidComputerPlayer {
|
||||
private final Context context;
|
||||
private final SearchListener listener;
|
||||
private final DroidBook book;
|
||||
private EGTBOptions egtbOptions;
|
||||
private EngineOptions engineOptions;
|
||||
|
||||
/** Set when "ucinewgame" needs to be sent. */
|
||||
private boolean newGame = false;
|
||||
@ -242,7 +242,7 @@ public class DroidComputerPlayer {
|
||||
this.context = context;
|
||||
this.listener = listener;
|
||||
book = DroidBook.getInstance();
|
||||
egtbOptions = new EGTBOptions();
|
||||
engineOptions = new EngineOptions();
|
||||
engineState = new EngineState();
|
||||
searchRequest = null;
|
||||
}
|
||||
@ -270,8 +270,8 @@ public class DroidComputerPlayer {
|
||||
book.setOptions(options);
|
||||
}
|
||||
|
||||
public final void setEgtbOptions(EGTBOptions options) {
|
||||
egtbOptions = options;
|
||||
public final void setEngineOptions(EngineOptions options) {
|
||||
engineOptions = options;
|
||||
}
|
||||
|
||||
/** Return all book moves, both as a formatted string and as a list of moves. */
|
||||
@ -331,7 +331,7 @@ public class DroidComputerPlayer {
|
||||
/** Decide what moves to search. Filters out non-optimal moves if tablebases are used. */
|
||||
private final ArrayList<Move> movesToSearch(SearchRequest sr) {
|
||||
ArrayList<Move> moves = null;
|
||||
if (egtbOptions.rootProbe)
|
||||
if (engineOptions.rootProbe)
|
||||
moves = Probe.getInstance().findOptimal(sr.currPos);
|
||||
if (moves != null) {
|
||||
sr.searchMoves = moves;
|
||||
@ -422,9 +422,14 @@ public class DroidComputerPlayer {
|
||||
}
|
||||
|
||||
private void killOldEngine(String engine) {
|
||||
if (engine.equals(engineState.engine))
|
||||
return;
|
||||
shutdownEngine();
|
||||
boolean needShutDown = !engine.equals(engineState.engine);
|
||||
if (!needShutDown) {
|
||||
UCIEngine uci = uciEngine;
|
||||
if (uci != null)
|
||||
needShutDown = !uci.optionsOk(engineOptions);
|
||||
}
|
||||
if (needShutDown)
|
||||
shutdownEngine();
|
||||
}
|
||||
|
||||
/** Tell engine to stop searching. */
|
||||
@ -662,7 +667,7 @@ public class DroidComputerPlayer {
|
||||
switch (engineState.state) {
|
||||
case READ_OPTIONS: {
|
||||
if (readUCIOption(uci, s)) {
|
||||
uci.initOptions(egtbOptions);
|
||||
uci.initOptions(engineOptions);
|
||||
uci.writeLineToEngine("ucinewgame");
|
||||
uci.writeLineToEngine("isready");
|
||||
engineState.setState(MainState.WAIT_READY);
|
||||
|
@ -27,7 +27,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
import org.petero.droidfish.R;
|
||||
import android.content.Context;
|
||||
|
||||
@ -91,7 +91,9 @@ public class ExternalEngine extends UCIEngineBase {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
engineProc.waitFor();
|
||||
Process ep = engineProc;
|
||||
if (ep != null)
|
||||
ep.waitFor();
|
||||
isRunning = false;
|
||||
if (!startedOk)
|
||||
report.reportError(context.getString(R.string.failed_to_start_engine));
|
||||
@ -161,15 +163,34 @@ public class ExternalEngine extends UCIEngineBase {
|
||||
}
|
||||
}
|
||||
|
||||
private int hashMB = -1;
|
||||
private String gaviotaTbPath = "";
|
||||
private boolean optionsInitialized = false;
|
||||
|
||||
/** @inheritDoc */
|
||||
@Override
|
||||
public void initOptions(EGTBOptions egtbOptions) {
|
||||
super.initOptions(egtbOptions);
|
||||
setOption("Hash", 16);
|
||||
if (egtbOptions.engineProbe) {
|
||||
setOption("GaviotaTbPath", egtbOptions.gtbPath);
|
||||
public void initOptions(EngineOptions engineOptions) {
|
||||
super.initOptions(engineOptions);
|
||||
hashMB = engineOptions.hashMB;
|
||||
setOption("Hash", engineOptions.hashMB);
|
||||
if (engineOptions.engineProbe) {
|
||||
gaviotaTbPath = engineOptions.gtbPath;
|
||||
setOption("GaviotaTbPath", engineOptions.gtbPath);
|
||||
setOption("GaviotaTbCache", 8);
|
||||
}
|
||||
optionsInitialized = true;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
@Override
|
||||
public boolean optionsOk(EngineOptions engineOptions) {
|
||||
if (!optionsInitialized)
|
||||
return true;
|
||||
if (hashMB != engineOptions.hashMB)
|
||||
return false;
|
||||
if (haveOption("gaviotatbpath") && !gaviotaTbPath.equals(engineOptions.gtbPath))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package org.petero.droidfish.engine;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
|
||||
public interface UCIEngine {
|
||||
|
||||
@ -32,7 +32,11 @@ public interface UCIEngine {
|
||||
public void initialize();
|
||||
|
||||
/** Initialize default options. */
|
||||
public void initOptions(EGTBOptions egtbOptions);
|
||||
public void initOptions(EngineOptions engineOptions);
|
||||
|
||||
/** Return true if engine options have correct values.
|
||||
* If false is returned, engine will be restarted. */
|
||||
public boolean optionsOk(EngineOptions engineOptions);
|
||||
|
||||
/** Shut down engine. */
|
||||
public void shutDown();
|
||||
|
@ -21,7 +21,7 @@ package org.petero.droidfish.engine;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
import org.petero.droidfish.engine.cuckoochess.CuckooChessEngine;
|
||||
|
||||
import android.content.Context;
|
||||
@ -62,7 +62,7 @@ public abstract class UCIEngineBase implements UCIEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initOptions(EGTBOptions egtbOptions) {
|
||||
public void initOptions(EngineOptions engineOptions) {
|
||||
isUCI = true;
|
||||
}
|
||||
|
||||
@ -84,6 +84,11 @@ public abstract class UCIEngineBase implements UCIEngine {
|
||||
allOptions.add(optName);
|
||||
}
|
||||
|
||||
/** Return true if engine has option optName. */
|
||||
protected boolean haveOption(String optName) {
|
||||
return allOptions.contains(optName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOption(String name, int value) {
|
||||
setOption(name, String.format("%d", value));
|
||||
|
@ -25,7 +25,7 @@ import chess.Position;
|
||||
import chess.TextIO;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
import org.petero.droidfish.engine.LocalPipe;
|
||||
import org.petero.droidfish.engine.UCIEngineBase;
|
||||
|
||||
@ -74,8 +74,14 @@ public class CuckooChessEngine extends UCIEngineBase {
|
||||
|
||||
/** @inheritDoc */
|
||||
@Override
|
||||
public final void initOptions(EGTBOptions egtbOptions) {
|
||||
super.initOptions(egtbOptions);
|
||||
public final void initOptions(EngineOptions engineOptions) {
|
||||
super.initOptions(engineOptions);
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
@Override
|
||||
public boolean optionsOk(EngineOptions engineOptions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
@ -22,7 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.petero.droidfish.EGTBOptions;
|
||||
import org.petero.droidfish.EngineOptions;
|
||||
import org.petero.droidfish.GUIInterface;
|
||||
import org.petero.droidfish.GameMode;
|
||||
import org.petero.droidfish.PGNOptions;
|
||||
@ -42,7 +42,7 @@ public class DroidChessController {
|
||||
private DroidComputerPlayer computerPlayer = null;
|
||||
private PgnToken.PgnTokenReceiver gameTextListener = null;
|
||||
private BookOptions bookOptions = new BookOptions();
|
||||
private EGTBOptions egtbOptions = new EGTBOptions();
|
||||
private EngineOptions engineOptions = new EngineOptions();
|
||||
private Game game = null;
|
||||
private Move ponderMove = null;
|
||||
private GUIInterface gui;
|
||||
@ -84,7 +84,7 @@ public class DroidChessController {
|
||||
if (computerPlayer == null) {
|
||||
computerPlayer = new DroidComputerPlayer(gui.getContext(), listener);
|
||||
computerPlayer.setBookOptions(bookOptions);
|
||||
computerPlayer.setEgtbOptions(egtbOptions);
|
||||
computerPlayer.setEngineOptions(engineOptions);
|
||||
}
|
||||
computerPlayer.queueStartEngine(searchId, engine);
|
||||
searchId++;
|
||||
@ -152,11 +152,11 @@ public class DroidChessController {
|
||||
}
|
||||
}
|
||||
|
||||
public final synchronized void setEgtbOptions(EGTBOptions options) {
|
||||
if (!egtbOptions.equals(options)) {
|
||||
egtbOptions = options;
|
||||
public final synchronized void setEngineOptions(EngineOptions options) {
|
||||
if (!engineOptions.equals(options)) {
|
||||
engineOptions = options;
|
||||
if (computerPlayer != null)
|
||||
computerPlayer.setEgtbOptions(egtbOptions);
|
||||
computerPlayer.setEngineOptions(engineOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user