DroidFish: Added setting to control when ECO codes are displayed.

This commit is contained in:
Peter Osterlund 2016-11-13 03:34:02 +01:00
parent 6996bead09
commit 4a9bcb8a21
8 changed files with 72 additions and 29 deletions

View File

@ -282,6 +282,8 @@ you are not actively using the program.\
<string name="prefs_bookHints_summary">Display opening book move hints for human player</string> <string name="prefs_bookHints_summary">Display opening book move hints for human player</string>
<string name="prefs_thinkingArrows_title">Use Arrows</string> <string name="prefs_thinkingArrows_title">Use Arrows</string>
<string name="prefs_thinkingArrows_summary">Use arrows to display moves on chess board</string> <string name="prefs_thinkingArrows_summary">Use arrows to display moves on chess board</string>
<string name="prefs_ecoHints_title">Show ECO codes</string>
<string name="prefs_ecoHints_summary">Show \'Encyclopedia of Chess Openings\' classification of openings</string>
<string name="prefs_user_interface_appearance">Appearance</string> <string name="prefs_user_interface_appearance">Appearance</string>
<string name="prefs_user_interface_behavior">Behavior</string> <string name="prefs_user_interface_behavior">Behavior</string>
<string name="prefs_animateMoves_title">Animate Moves</string> <string name="prefs_animateMoves_title">Animate Moves</string>
@ -590,6 +592,16 @@ you are not actively using the program.\
<item>16</item> <item>16</item>
<item>21</item> <item>21</item>
</string-array> </string-array>
<string-array name="ecoHints_texts">
<item>Off</item>
<item>Auto</item>
<item>Always</item>
</string-array>
<string-array name="ecoHints_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="thinking_arrows_texts"> <string-array name="thinking_arrows_texts">
<item>No arrows</item> <item>No arrows</item>
<item>Max 1 Arrow</item> <item>Max 1 Arrow</item>

View File

@ -71,6 +71,14 @@
android:summary="@string/prefs_bookHints_summary" android:summary="@string/prefs_bookHints_summary"
android:defaultValue="true"> android:defaultValue="true">
</CheckBoxPreference> </CheckBoxPreference>
<ListPreference
android:key="ecoHints"
android:title="@string/prefs_ecoHints_title"
android:summary="@string/prefs_ecoHints_summary"
android:entryValues="@array/ecoHints_values"
android:entries="@array/ecoHints_texts"
android:defaultValue="1">
</ListPreference>
<ListPreference <ListPreference
android:key="thinkingArrows" android:key="thinkingArrows"
android:title="@string/prefs_thinkingArrows_title" android:title="@string/prefs_thinkingArrows_title"

View File

@ -179,6 +179,7 @@ public class DroidFish extends Activity
private int numPV; private int numPV;
private boolean mWhiteBasedScores; private boolean mWhiteBasedScores;
private boolean mShowBookHints; private boolean mShowBookHints;
private int mEcoHints;
private int maxNumArrows; private int maxNumArrows;
private GameMode gameMode; private GameMode gameMode;
private boolean mPonderMode; private boolean mPonderMode;
@ -229,6 +230,10 @@ public class DroidFish extends Activity
} }
private AutoMode autoMode = AutoMode.OFF; private AutoMode autoMode = AutoMode.OFF;
private final int ECO_HINTS_OFF = 0;
private final int ECO_HINTS_AUTO = 1;
private final int ECO_HINTS_ALWAYS = 2;
/** State of requested permissions. */ /** State of requested permissions. */
private static enum PermissionState { private static enum PermissionState {
UNKNOWN, UNKNOWN,
@ -1161,6 +1166,7 @@ public class DroidFish extends Activity
mWhiteBasedScores = settings.getBoolean("whiteBasedScores", false); mWhiteBasedScores = settings.getBoolean("whiteBasedScores", false);
maxNumArrows = getIntSetting("thinkingArrows", 4); maxNumArrows = getIntSetting("thinkingArrows", 4);
mShowBookHints = settings.getBoolean("bookHints", false); mShowBookHints = settings.getBoolean("bookHints", false);
mEcoHints = getIntSetting("ecoHints", ECO_HINTS_AUTO);
String engine = settings.getString("engine", "stockfish"); String engine = settings.getString("engine", "stockfish");
int strength = settings.getInt("strength", 1000); int strength = settings.getInt("strength", 1000);
@ -1948,6 +1954,7 @@ public class DroidFish extends Activity
private String thinkingStr2 = ""; private String thinkingStr2 = "";
private String bookInfoStr = ""; private String bookInfoStr = "";
private String ecoInfoStr = ""; private String ecoInfoStr = "";
private boolean ecoInTree = false;
private String variantStr = ""; private String variantStr = "";
private ArrayList<ArrayList<Move>> pvMoves = new ArrayList<ArrayList<Move>>(); private ArrayList<ArrayList<Move>> pvMoves = new ArrayList<ArrayList<Move>>();
private ArrayList<Move> bookMoves = null; private ArrayList<Move> bookMoves = null;
@ -1959,6 +1966,7 @@ public class DroidFish extends Activity
thinkingStr2 = ti.statStr; thinkingStr2 = ti.statStr;
bookInfoStr = ti.bookInfo; bookInfoStr = ti.bookInfo;
ecoInfoStr = ti.eco; ecoInfoStr = ti.eco;
ecoInTree = ti.ecoInTree;
pvMoves = ti.pvMoves; pvMoves = ti.pvMoves;
bookMoves = ti.bookMoves; bookMoves = ti.bookMoves;
updateThinkingInfo(); updateThinkingInfo();
@ -1987,13 +1995,14 @@ public class DroidFish extends Activity
} }
thinking.setText(s, TextView.BufferType.SPANNABLE); thinking.setText(s, TextView.BufferType.SPANNABLE);
} }
if (mShowBookHints && !ecoInfoStr.isEmpty()) { if ((mEcoHints == ECO_HINTS_ALWAYS || (mEcoHints == ECO_HINTS_AUTO && ecoInTree)) &&
!ecoInfoStr.isEmpty()) {
String s = thinkingEmpty ? "" : "<br>"; String s = thinkingEmpty ? "" : "<br>";
s += ecoInfoStr; s += ecoInfoStr;
thinking.append(Html.fromHtml(s)); thinking.append(Html.fromHtml(s));
thinkingEmpty = false; thinkingEmpty = false;
} }
if (mShowBookHints && !bookInfoStr.isEmpty()) { if (mShowBookHints && !bookInfoStr.isEmpty() && ctrl.humansTurn()) {
String s = thinkingEmpty ? "" : "<br>"; String s = thinkingEmpty ? "" : "<br>";
s += Util.boldStart + getString(R.string.book) + Util.boldStop + bookInfoStr; s += Util.boldStart + getString(R.string.book) + Util.boldStop + bookInfoStr;
thinking.append(Html.fromHtml(s)); thinking.append(Html.fromHtml(s));

View File

@ -60,6 +60,7 @@ public interface GUIInterface {
public ArrayList<ArrayList<Move>> pvMoves; public ArrayList<ArrayList<Move>> pvMoves;
public ArrayList<Move> bookMoves; public ArrayList<Move> bookMoves;
public String eco; public String eco;
public boolean ecoInTree;
} }
/** Update the computer thinking information. */ /** Update the computer thinking information. */

View File

@ -31,6 +31,7 @@ import java.util.WeakHashMap;
import org.petero.droidfish.gamelogic.ChessParseError; import org.petero.droidfish.gamelogic.ChessParseError;
import org.petero.droidfish.gamelogic.GameTree; import org.petero.droidfish.gamelogic.GameTree;
import org.petero.droidfish.gamelogic.Move; import org.petero.droidfish.gamelogic.Move;
import org.petero.droidfish.gamelogic.Pair;
import org.petero.droidfish.gamelogic.Position; import org.petero.droidfish.gamelogic.Position;
import org.petero.droidfish.gamelogic.TextIO; import org.petero.droidfish.gamelogic.TextIO;
import org.petero.droidfish.gamelogic.UndoInfo; import org.petero.droidfish.gamelogic.UndoInfo;
@ -49,7 +50,7 @@ public class EcoDb {
} }
/** Get ECO classification for a given tree node. */ /** Get ECO classification for a given tree node. */
public String getEco(GameTree gt, GameTree.Node node) { public Pair<String,Boolean> getEco(GameTree gt, GameTree.Node node) {
ArrayList<GameTree.Node> gtNodePath = new ArrayList<GameTree.Node>(); ArrayList<GameTree.Node> gtNodePath = new ArrayList<GameTree.Node>();
int nodeIdx = -1; int nodeIdx = -1;
boolean inEcoTree = true; boolean inEcoTree = true;
@ -94,9 +95,9 @@ public class EcoDb {
if (nodeIdx != -1) { if (nodeIdx != -1) {
Node n = readNode(nodeIdx); Node n = readNode(nodeIdx);
if (n.nameIdx >= 0) if (n.nameIdx >= 0)
return ecoNames[n.nameIdx]; return new Pair<String, Boolean>(ecoNames[n.nameIdx], inEcoTree);
} }
return ""; return new Pair<String, Boolean>("", false);
} }

View File

@ -684,6 +684,7 @@ public class DroidChessController {
private String bookInfo = ""; private String bookInfo = "";
private ArrayList<Move> bookMoves = null; private ArrayList<Move> bookMoves = null;
private String eco = ""; // ECO classification private String eco = ""; // ECO classification
private boolean ecoInTree = false; // True if current position is inside the EcoDB tree
private Move ponderMove = null; private Move ponderMove = null;
private ArrayList<PvInfo> pvInfoV = new ArrayList<PvInfo>(); private ArrayList<PvInfo> pvInfoV = new ArrayList<PvInfo>();
@ -697,6 +698,7 @@ public class DroidChessController {
bookInfo = ""; bookInfo = "";
bookMoves = null; bookMoves = null;
eco = ""; eco = "";
ecoInTree = false;
setSearchInfo(id); setSearchInfo(id);
} }
@ -787,6 +789,7 @@ public class DroidChessController {
ti.statStr = statStr; ti.statStr = statStr;
ti.bookInfo = bookInfo; ti.bookInfo = bookInfo;
ti.eco = eco; ti.eco = eco;
ti.ecoInTree = ecoInTree;
ti.pvMoves = pvMoves; ti.pvMoves = pvMoves;
ti.bookMoves = bookMoves; ti.bookMoves = bookMoves;
latestThinkingInfo = ti; latestThinkingInfo = ti;
@ -860,10 +863,11 @@ public class DroidChessController {
@Override @Override
public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList, public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList,
String eco) { String eco, boolean ecoInTree) {
this.bookInfo = bookInfo; this.bookInfo = bookInfo;
bookMoves = moveList; bookMoves = moveList;
this.eco = eco; this.eco = eco;
this.ecoInTree = ecoInTree;
setSearchInfo(id); setSearchInfo(id);
} }
@ -925,10 +929,13 @@ public class DroidChessController {
} }
private final void updateBookHints() { private final void updateBookHints() {
if (humansTurn()) { if (game != null) {
Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos(), localPt()); Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos(), localPt());
String eco = EcoDb.getInstance(gui.getContext()).getEco(game.tree, game.tree.currentNode); Pair<String, Boolean> ecoData =
listener.notifyBookInfo(searchId, bi.first, bi.second, eco); EcoDb.getInstance(gui.getContext()).getEco(game.tree, game.tree.currentNode);
String eco = ecoData.first;
boolean ecoInTree = ecoData.second;
listener.notifyBookInfo(searchId, bi.first, bi.second, eco, ecoInTree);
} }
} }
@ -968,7 +975,11 @@ public class DroidChessController {
computerPlayer.queueAnalyzeRequest(sr); computerPlayer.queueAnalyzeRequest(sr);
} else if (computersTurn || ponder) { } else if (computersTurn || ponder) {
listener.clearSearchInfo(searchId); listener.clearSearchInfo(searchId);
listener.notifyBookInfo(searchId, "", null, ""); Pair<String, Boolean> ecoData =
EcoDb.getInstance(gui.getContext()).getEco(game.tree, game.tree.currentNode);
String eco = ecoData.first;
boolean ecoInTree = ecoData.second;
listener.notifyBookInfo(searchId, "", null, eco, ecoInTree);
final Pair<Position, ArrayList<Move>> ph = game.getUCIHistory(); final Pair<Position, ArrayList<Move>> ph = game.getUCIHistory();
Position currPos = new Position(game.currPos()); Position currPos = new Position(game.currPos());
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();

View File

@ -71,7 +71,8 @@ public interface SearchListener {
public void notifyStats(int id, long nodes, int nps, long tbHits, int hash, int time); public void notifyStats(int id, long nodes, int nps, long tbHits, int hash, int time);
/** Report opening book information. */ /** Report opening book information. */
public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList, String eco); public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList,
String eco, boolean ecoInTree);
/** Report move (or command, such as "resign") played by the engine. */ /** Report move (or command, such as "resign") played by the engine. */
public void notifySearchResult(int id, String cmd, Move ponder); public void notifySearchResult(int id, String cmd, Move ponder);

View File

@ -36,27 +36,27 @@ public class EcoTest extends AndroidTestCase {
{ {
String pgn = "e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1"; String pgn = "e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1";
GameTree gt = readPGN(pgn); GameTree gt = readPGN(pgn);
String eco = ecoDb.getEco(gt, gt.currentNode); String eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("", eco); assertEquals("", eco);
gt.goForward(0); gt.goForward(0);
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("B00: King's pawn opening", eco); assertEquals("B00: King's pawn opening", eco);
gt.goForward(0); gt.goForward(0);
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("C20: King's pawn game", eco); assertEquals("C20: King's pawn game", eco);
gt.goForward(0); gt.goForward(0);
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("C40: King's knight opening", eco); assertEquals("C40: King's knight opening", eco);
gt.goForward(0); gt.goForward(0);
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("C44: King's pawn game", eco); assertEquals("C44: King's pawn game", eco);
gt.goForward(0); gt.goForward(0);
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("C60: Ruy Lopez (Spanish opening)", eco); assertEquals("C60: Ruy Lopez (Spanish opening)", eco);
} }
{ {
@ -65,48 +65,48 @@ public class EcoTest extends AndroidTestCase {
game.processString("e5"); game.processString("e5");
game.processString("Nf3"); game.processString("Nf3");
game.processString("Nf6"); game.processString("Nf6");
String eco = ecoDb.getEco(game.tree, game.tree.currentNode); String eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov's defence", eco); assertEquals("C42: Petrov's defence", eco);
game.processString("Nxe5"); game.processString("Nxe5");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov's defence", eco); assertEquals("C42: Petrov's defence", eco);
game.processString("d6"); game.processString("d6");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov's defence", eco); assertEquals("C42: Petrov's defence", eco);
game.processString("Nxf7"); game.processString("Nxf7");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov, Cochrane gambit", eco); assertEquals("C42: Petrov, Cochrane gambit", eco);
game.undoMove(); game.undoMove();
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov's defence", eco); assertEquals("C42: Petrov's defence", eco);
game.processString("Nf3"); game.processString("Nf3");
game.processString("Nxe4"); game.processString("Nxe4");
game.processString("d4"); game.processString("d4");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("C42: Petrov, classical attack", eco); assertEquals("C42: Petrov, classical attack", eco);
} }
{ {
Game game = new Game(null, new TimeControlData()); Game game = new Game(null, new TimeControlData());
game.processString("e4"); game.processString("e4");
game.processString("c5"); game.processString("c5");
String eco = ecoDb.getEco(game.tree, game.tree.currentNode); String eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("B20: Sicilian defence", eco); assertEquals("B20: Sicilian defence", eco);
game.processString("h3"); game.processString("h3");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("B20: Sicilian defence", eco); assertEquals("B20: Sicilian defence", eco);
game.processString("Nc6"); game.processString("Nc6");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("B20: Sicilian defence", eco); assertEquals("B20: Sicilian defence", eco);
game.processString("g3"); game.processString("g3");
eco = ecoDb.getEco(game.tree, game.tree.currentNode); eco = ecoDb.getEco(game.tree, game.tree.currentNode).first;
assertEquals("B20: Sicilian defence", eco); assertEquals("B20: Sicilian defence", eco);
} }
} }
@ -114,11 +114,11 @@ public class EcoTest extends AndroidTestCase {
public void testEcoFromFEN() throws Throwable { public void testEcoFromFEN() throws Throwable {
EcoDb ecoDb = EcoDb.getInstance(getContext()); EcoDb ecoDb = EcoDb.getInstance(getContext());
GameTree gt = gtFromFEN("rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq - 0 4"); GameTree gt = gtFromFEN("rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq - 0 4");
String eco = ecoDb.getEco(gt, gt.currentNode); String eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("C01: French, exchange variation", eco); assertEquals("C01: French, exchange variation", eco);
gt = gtFromFEN("rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq - 1 3"); gt = gtFromFEN("rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq - 1 3");
eco = ecoDb.getEco(gt, gt.currentNode); eco = ecoDb.getEco(gt, gt.currentNode).first;
assertEquals("B06: Robatsch (modern) defence", eco); assertEquals("B06: Robatsch (modern) defence", eco);
} }