mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-02-18 18:17:49 +01:00
DroidFish: Better handling of transpositions in ECO classification.
This commit is contained in:
parent
4a9bcb8a21
commit
3292bec55c
|
@ -1954,7 +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 int distToEcoTree = 0;
|
||||||
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;
|
||||||
|
@ -1966,7 +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;
|
distToEcoTree = ti.distToEcoTree;
|
||||||
pvMoves = ti.pvMoves;
|
pvMoves = ti.pvMoves;
|
||||||
bookMoves = ti.bookMoves;
|
bookMoves = ti.bookMoves;
|
||||||
updateThinkingInfo();
|
updateThinkingInfo();
|
||||||
|
@ -1995,7 +1995,9 @@ public class DroidFish extends Activity
|
||||||
}
|
}
|
||||||
thinking.setText(s, TextView.BufferType.SPANNABLE);
|
thinking.setText(s, TextView.BufferType.SPANNABLE);
|
||||||
}
|
}
|
||||||
if ((mEcoHints == ECO_HINTS_ALWAYS || (mEcoHints == ECO_HINTS_AUTO && ecoInTree)) &&
|
int maxDistToEcoTree = 10;
|
||||||
|
if ((mEcoHints == ECO_HINTS_ALWAYS ||
|
||||||
|
(mEcoHints == ECO_HINTS_AUTO && distToEcoTree <= maxDistToEcoTree)) &&
|
||||||
!ecoInfoStr.isEmpty()) {
|
!ecoInfoStr.isEmpty()) {
|
||||||
String s = thinkingEmpty ? "" : "<br>";
|
String s = thinkingEmpty ? "" : "<br>";
|
||||||
s += ecoInfoStr;
|
s += ecoInfoStr;
|
||||||
|
|
|
@ -60,7 +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;
|
public int distToEcoTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update the computer thinking information. */
|
/** Update the computer thinking information. */
|
||||||
|
|
|
@ -49,55 +49,103 @@ public class EcoDb {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get ECO classification for a given tree node. */
|
/** Get ECO classification for a given tree node. Also returns distance in plies to "ECO tree". */
|
||||||
public Pair<String,Boolean> getEco(GameTree gt, GameTree.Node node) {
|
public Pair<String,Integer> getEco(GameTree gt) {
|
||||||
ArrayList<GameTree.Node> gtNodePath = new ArrayList<GameTree.Node>();
|
ArrayList<Integer> treePath = new ArrayList<Integer>(); // Path to restore gt to original node
|
||||||
|
ArrayList<Pair<GameTree.Node,Boolean>> toCache = new ArrayList<Pair<GameTree.Node,Boolean>>();
|
||||||
|
|
||||||
int nodeIdx = -1;
|
int nodeIdx = -1;
|
||||||
boolean inEcoTree = true;
|
int distToEcoTree = 0;
|
||||||
while (node != null) {
|
|
||||||
|
// Find matching node furtherest from root in the ECO tree
|
||||||
|
boolean checkForDup = true;
|
||||||
|
while (true) {
|
||||||
|
GameTree.Node node = gt.currentNode;
|
||||||
CacheEntry e = findNode(node);
|
CacheEntry e = findNode(node);
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
nodeIdx = e.nodeIdx;
|
nodeIdx = e.nodeIdx;
|
||||||
inEcoTree = e.inEcoTree;
|
distToEcoTree = e.distToEcoTree;
|
||||||
|
checkForDup = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node == gt.rootNode) {
|
Short idx = posHashToNodeIdx.get(gt.currentPos.zobristHash());
|
||||||
Short idx = posHashToNodeIdx.get(gt.startPos.zobristHash());
|
boolean inEcoTree = idx != null;
|
||||||
if (idx != null) {
|
toCache.add(new Pair<GameTree.Node,Boolean>(node, inEcoTree));
|
||||||
|
|
||||||
|
if (idx != null) {
|
||||||
|
Node ecoNode = readNode(idx);
|
||||||
|
if (ecoNode.nameIdx != -1) {
|
||||||
nodeIdx = idx;
|
nodeIdx = idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtNodePath.add(node);
|
|
||||||
node = node.getParent();
|
if (node == gt.rootNode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
treePath.add(node.getChildNo());
|
||||||
|
gt.goBack();
|
||||||
}
|
}
|
||||||
if (nodeIdx != -1) {
|
|
||||||
Node ecoNode = readNode(nodeIdx);
|
// Handle duplicates in ECO tree (same position reachable from more than one path)
|
||||||
for (int i = gtNodePath.size() - 1; i >= 0; i--) {
|
if (nodeIdx != -1 && checkForDup && gt.startPos.zobristHash() == startPosHash) {
|
||||||
GameTree.Node gtNode = gtNodePath.get(i);
|
ArrayList<Short> dups = posHashToNodeIdx2.get(gt.currentPos.zobristHash());
|
||||||
int m = gtNode.move.getCompressedMove();
|
if (dups != null) {
|
||||||
int child = inEcoTree ? ecoNode.firstChild : -1;
|
while (gt.currentNode != gt.rootNode) {
|
||||||
while (child != -1) {
|
treePath.add(gt.currentNode.getChildNo());
|
||||||
Node cNode = readNode(child);
|
gt.goBack();
|
||||||
if (cNode.move == m)
|
}
|
||||||
break;
|
|
||||||
child = cNode.nextSibling;
|
int currEcoNode = 0;
|
||||||
|
boolean foundDup = false;
|
||||||
|
while (!treePath.isEmpty()) {
|
||||||
|
gt.goForward(treePath.get(treePath.size() - 1));
|
||||||
|
treePath.remove(treePath.size() - 1);
|
||||||
|
int m = gt.currentNode.move.getCompressedMove();
|
||||||
|
|
||||||
|
Node ecoNode = readNode(currEcoNode);
|
||||||
|
boolean foundChild = false;
|
||||||
|
int child = ecoNode.firstChild;
|
||||||
|
while (child != -1) {
|
||||||
|
ecoNode = readNode(child);
|
||||||
|
if (ecoNode.move == m) {
|
||||||
|
foundChild = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child = ecoNode.nextSibling;
|
||||||
|
}
|
||||||
|
if (!foundChild)
|
||||||
|
break;
|
||||||
|
currEcoNode = child;
|
||||||
|
for (Short dup : dups) {
|
||||||
|
if (dup == currEcoNode) {
|
||||||
|
nodeIdx = currEcoNode;
|
||||||
|
foundDup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundDup)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (child != -1) {
|
|
||||||
nodeIdx = child;
|
|
||||||
ecoNode = readNode(nodeIdx);
|
|
||||||
} else
|
|
||||||
inEcoTree = false;
|
|
||||||
cacheNode(gtNode, nodeIdx, inEcoTree);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = treePath.size() - 1; i >= 0; i--)
|
||||||
|
gt.goForward(treePath.get(i));
|
||||||
|
for (int i = toCache.size() - 1; i >= 0; i--) {
|
||||||
|
Pair<GameTree.Node,Boolean> p = toCache.get(i);
|
||||||
|
distToEcoTree++;
|
||||||
|
if (p.second)
|
||||||
|
distToEcoTree = 0;
|
||||||
|
cacheNode(p.first, nodeIdx, distToEcoTree);
|
||||||
|
}
|
||||||
|
|
||||||
if (nodeIdx != -1) {
|
if (nodeIdx != -1) {
|
||||||
Node n = readNode(nodeIdx);
|
Node n = readNode(nodeIdx);
|
||||||
if (n.nameIdx >= 0)
|
if (n.nameIdx >= 0)
|
||||||
return new Pair<String, Boolean>(ecoNames[n.nameIdx], inEcoTree);
|
return new Pair<String, Integer>(ecoNames[n.nameIdx], distToEcoTree);
|
||||||
}
|
}
|
||||||
return new Pair<String, Boolean>("", false);
|
return new Pair<String, Integer>("", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,13 +159,15 @@ public class EcoDb {
|
||||||
private byte[] nodesBuffer;
|
private byte[] nodesBuffer;
|
||||||
private String[] ecoNames;
|
private String[] ecoNames;
|
||||||
private HashMap<Long, Short> posHashToNodeIdx;
|
private HashMap<Long, Short> posHashToNodeIdx;
|
||||||
|
private HashMap<Long, ArrayList<Short>> posHashToNodeIdx2; // Handles collisions
|
||||||
|
private final long startPosHash; // Zobrist hash for standard starting position
|
||||||
|
|
||||||
private static class CacheEntry {
|
private static class CacheEntry {
|
||||||
final int nodeIdx;
|
final int nodeIdx;
|
||||||
final boolean inEcoTree;
|
final int distToEcoTree;
|
||||||
CacheEntry(int n, boolean i) {
|
CacheEntry(int n, int d) {
|
||||||
nodeIdx = n;
|
nodeIdx = n;
|
||||||
inEcoTree = i;
|
distToEcoTree = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private WeakLRUCache<GameTree.Node, CacheEntry> gtNodeToIdx;
|
private WeakLRUCache<GameTree.Node, CacheEntry> gtNodeToIdx;
|
||||||
|
@ -128,13 +178,14 @@ public class EcoDb {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Store GameTree.Node to Node index in cache. */
|
/** Store GameTree.Node to Node index in cache. */
|
||||||
private void cacheNode(GameTree.Node node, int nodeIdx, boolean inTree) {
|
private void cacheNode(GameTree.Node node, int nodeIdx, int distToEcoTree) {
|
||||||
gtNodeToIdx.put(node, new CacheEntry(nodeIdx, inTree));
|
gtNodeToIdx.put(node, new CacheEntry(nodeIdx, distToEcoTree));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructor. */
|
/** Constructor. */
|
||||||
private EcoDb(Context context) {
|
private EcoDb(Context context) {
|
||||||
posHashToNodeIdx = new HashMap<Long, Short>();
|
posHashToNodeIdx = new HashMap<Long, Short>();
|
||||||
|
posHashToNodeIdx2 = new HashMap<Long, ArrayList<Short>>();
|
||||||
gtNodeToIdx = new WeakLRUCache<GameTree.Node, CacheEntry>(50);
|
gtNodeToIdx = new WeakLRUCache<GameTree.Node, CacheEntry>(50);
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
|
||||||
|
@ -174,19 +225,32 @@ public class EcoDb {
|
||||||
throw new RuntimeException("Can't read ECO database");
|
throw new RuntimeException("Can't read ECO database");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
Position pos = TextIO.readFEN(TextIO.startPosFEN);
|
||||||
|
startPosHash = pos.zobristHash();
|
||||||
if (nodesBuffer.length > 0) {
|
if (nodesBuffer.length > 0) {
|
||||||
Position pos = TextIO.readFEN(TextIO.startPosFEN);
|
|
||||||
populateCache(pos, 0);
|
populateCache(pos, 0);
|
||||||
}
|
}
|
||||||
} catch (ChessParseError e) {
|
} catch (ChessParseError e) {
|
||||||
|
throw new RuntimeException("Internal error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize popHashToNodeIdx. */
|
/** Initialize posHashToNodeIdx. */
|
||||||
private void populateCache(Position pos, int nodeIdx) {
|
private void populateCache(Position pos, int nodeIdx) {
|
||||||
if (posHashToNodeIdx.get(pos.zobristHash()) == null)
|
|
||||||
posHashToNodeIdx.put(pos.zobristHash(), (short)nodeIdx);
|
|
||||||
Node node = readNode(nodeIdx);
|
Node node = readNode(nodeIdx);
|
||||||
|
long hash = pos.zobristHash();
|
||||||
|
if (posHashToNodeIdx.get(hash) == null) {
|
||||||
|
posHashToNodeIdx.put(hash, (short)nodeIdx);
|
||||||
|
} else if (node.nameIdx != -1) {
|
||||||
|
ArrayList<Short> lst = null;
|
||||||
|
if (posHashToNodeIdx2.get(hash) == null) {
|
||||||
|
lst = new ArrayList<Short>();
|
||||||
|
posHashToNodeIdx2.put(hash, lst);
|
||||||
|
} else {
|
||||||
|
lst = posHashToNodeIdx2.get(hash);
|
||||||
|
}
|
||||||
|
lst.add((short)nodeIdx);
|
||||||
|
}
|
||||||
int child = node.firstChild;
|
int child = node.firstChild;
|
||||||
UndoInfo ui = new UndoInfo();
|
UndoInfo ui = new UndoInfo();
|
||||||
while (child != -1) {
|
while (child != -1) {
|
||||||
|
|
|
@ -78,22 +78,10 @@ public class EcoBuilder {
|
||||||
gotMoves |= !isHeader;
|
gotMoves |= !isHeader;
|
||||||
}
|
}
|
||||||
readGame(pgn.toString());
|
readGame(pgn.toString());
|
||||||
setNameIndices(0);
|
|
||||||
|
|
||||||
writeDataFile(ecoDatFile);
|
writeDataFile(ecoDatFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For all tree nodes, if nameIndex not already set,
|
|
||||||
* set it from parent node nameIndex. */
|
|
||||||
private void setNameIndices(int nodeIdx) {
|
|
||||||
Node n = nodes.get(nodeIdx);
|
|
||||||
for (Node c : n.children) {
|
|
||||||
if (c.nameIdx == -1)
|
|
||||||
c.nameIdx = n.nameIdx;
|
|
||||||
setNameIndices(c.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read and process one game. */
|
/** Read and process one game. */
|
||||||
private void readGame(String pgn) throws Throwable {
|
private void readGame(String pgn) throws Throwable {
|
||||||
if (pgn.isEmpty())
|
if (pgn.isEmpty())
|
||||||
|
@ -142,7 +130,7 @@ public class EcoBuilder {
|
||||||
Node node = new Node();
|
Node node = new Node();
|
||||||
node.index = nodes.size();
|
node.index = nodes.size();
|
||||||
node.move = m;
|
node.move = m;
|
||||||
node.nameIdx = parent.nameIdx;
|
node.nameIdx = -1;
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
nodes.add(node);
|
nodes.add(node);
|
||||||
parent.children.add(node);
|
parent.children.add(node);
|
||||||
|
|
|
@ -684,7 +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 int distToEcoTree = 0; // Number of plies since game was in the "ECO tree".
|
||||||
|
|
||||||
private Move ponderMove = null;
|
private Move ponderMove = null;
|
||||||
private ArrayList<PvInfo> pvInfoV = new ArrayList<PvInfo>();
|
private ArrayList<PvInfo> pvInfoV = new ArrayList<PvInfo>();
|
||||||
|
@ -698,7 +698,7 @@ public class DroidChessController {
|
||||||
bookInfo = "";
|
bookInfo = "";
|
||||||
bookMoves = null;
|
bookMoves = null;
|
||||||
eco = "";
|
eco = "";
|
||||||
ecoInTree = false;
|
distToEcoTree = 0;
|
||||||
setSearchInfo(id);
|
setSearchInfo(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,7 +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.distToEcoTree = distToEcoTree;
|
||||||
ti.pvMoves = pvMoves;
|
ti.pvMoves = pvMoves;
|
||||||
ti.bookMoves = bookMoves;
|
ti.bookMoves = bookMoves;
|
||||||
latestThinkingInfo = ti;
|
latestThinkingInfo = ti;
|
||||||
|
@ -863,11 +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, boolean ecoInTree) {
|
String eco, int distToEcoTree) {
|
||||||
this.bookInfo = bookInfo;
|
this.bookInfo = bookInfo;
|
||||||
bookMoves = moveList;
|
bookMoves = moveList;
|
||||||
this.eco = eco;
|
this.eco = eco;
|
||||||
this.ecoInTree = ecoInTree;
|
this.distToEcoTree = distToEcoTree;
|
||||||
setSearchInfo(id);
|
setSearchInfo(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,11 +931,10 @@ public class DroidChessController {
|
||||||
private final void updateBookHints() {
|
private final void updateBookHints() {
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos(), localPt());
|
Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos(), localPt());
|
||||||
Pair<String, Boolean> ecoData =
|
Pair<String, Integer> ecoData =
|
||||||
EcoDb.getInstance(gui.getContext()).getEco(game.tree, game.tree.currentNode);
|
EcoDb.getInstance(gui.getContext()).getEco(game.tree);
|
||||||
String eco = ecoData.first;
|
String eco = ecoData.first;
|
||||||
boolean ecoInTree = ecoData.second;
|
listener.notifyBookInfo(searchId, bi.first, bi.second, eco, ecoData.second);
|
||||||
listener.notifyBookInfo(searchId, bi.first, bi.second, eco, ecoInTree);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,11 +974,10 @@ public class DroidChessController {
|
||||||
computerPlayer.queueAnalyzeRequest(sr);
|
computerPlayer.queueAnalyzeRequest(sr);
|
||||||
} else if (computersTurn || ponder) {
|
} else if (computersTurn || ponder) {
|
||||||
listener.clearSearchInfo(searchId);
|
listener.clearSearchInfo(searchId);
|
||||||
Pair<String, Boolean> ecoData =
|
Pair<String, Integer> ecoData =
|
||||||
EcoDb.getInstance(gui.getContext()).getEco(game.tree, game.tree.currentNode);
|
EcoDb.getInstance(gui.getContext()).getEco(game.tree);
|
||||||
String eco = ecoData.first;
|
String eco = ecoData.first;
|
||||||
boolean ecoInTree = ecoData.second;
|
listener.notifyBookInfo(searchId, "", null, eco, 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();
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class GameTree {
|
||||||
|
|
||||||
public Node rootNode;
|
public Node rootNode;
|
||||||
public Node currentNode;
|
public Node currentNode;
|
||||||
Position currentPos; // Cached value. Computable from "currentNode".
|
public Position currentPos; // Cached value. Computable from "currentNode".
|
||||||
|
|
||||||
private final PgnToken.PgnTokenReceiver gameStateListener;
|
private final PgnToken.PgnTokenReceiver gameStateListener;
|
||||||
|
|
||||||
|
@ -1086,21 +1086,22 @@ public class GameTree {
|
||||||
ArrayList<Integer> ret = new ArrayList<Integer>(64);
|
ArrayList<Integer> ret = new ArrayList<Integer>(64);
|
||||||
Node node = this;
|
Node node = this;
|
||||||
while (node.parent != null) {
|
while (node.parent != null) {
|
||||||
Node p = node.parent;
|
ret.add(node.getChildNo());
|
||||||
int childNo = -1;
|
|
||||||
for (int i = 0; i < p.children.size(); i++)
|
|
||||||
if (p.children.get(i) == node) {
|
|
||||||
childNo = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (childNo == -1) throw new RuntimeException();
|
|
||||||
ret.add(childNo);
|
|
||||||
node = node.parent;
|
node = node.parent;
|
||||||
}
|
}
|
||||||
Collections.reverse(ret);
|
Collections.reverse(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return this node's position in the parent node child list. */
|
||||||
|
public final int getChildNo() {
|
||||||
|
Node p = parent;
|
||||||
|
for (int i = 0; i < p.children.size(); i++)
|
||||||
|
if (p.children.get(i) == this)
|
||||||
|
return i;
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
static final void writeToStream(DataOutputStream dos, Node node) throws IOException {
|
static final void writeToStream(DataOutputStream dos, Node node) throws IOException {
|
||||||
while (true) {
|
while (true) {
|
||||||
dos.writeUTF(node.moveStr);
|
dos.writeUTF(node.moveStr);
|
||||||
|
|
|
@ -72,7 +72,7 @@ public interface SearchListener {
|
||||||
|
|
||||||
/** Report opening book information. */
|
/** Report opening book information. */
|
||||||
public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList,
|
public void notifyBookInfo(int id, String bookInfo, ArrayList<Move> moveList,
|
||||||
String eco, boolean ecoInTree);
|
String eco, int distToEcoTree);
|
||||||
|
|
||||||
/** 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);
|
||||||
|
|
|
@ -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).first;
|
String eco = ecoDb.getEco(gt).first;
|
||||||
assertEquals("", eco);
|
assertEquals("", eco);
|
||||||
|
|
||||||
gt.goForward(0);
|
gt.goForward(0);
|
||||||
eco = ecoDb.getEco(gt, gt.currentNode).first;
|
eco = ecoDb.getEco(gt).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).first;
|
eco = ecoDb.getEco(gt).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).first;
|
eco = ecoDb.getEco(gt).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).first;
|
eco = ecoDb.getEco(gt).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).first;
|
eco = ecoDb.getEco(gt).first;
|
||||||
assertEquals("C60: Ruy Lopez (Spanish opening)", eco);
|
assertEquals("C60: Ruy Lopez (Spanish opening)", eco);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -65,60 +65,85 @@ 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).first;
|
String eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
String eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).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).first;
|
eco = ecoDb.getEco(game.tree).first;
|
||||||
assertEquals("B20: Sicilian defence", eco);
|
assertEquals("B20: Sicilian defence", eco);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
Game game = new Game(null, new TimeControlData());
|
||||||
|
for (String m : new String[]{"d4", "d5", "c4", "c6", "Nf3", "Nf6", "Nc3", "g6"})
|
||||||
|
game.processString(m);
|
||||||
|
String eco = ecoDb.getEco(game.tree).first;
|
||||||
|
assertEquals("D15: QGD Slav, Schlechter variation", eco);
|
||||||
|
assertEquals(0, ecoDb.getEco(game.tree).second.intValue());
|
||||||
|
game.processString("a4");
|
||||||
|
assertEquals("D15: QGD Slav, Schlechter variation", eco);
|
||||||
|
assertEquals(1, ecoDb.getEco(game.tree).second.intValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Game game = new Game(null, new TimeControlData());
|
||||||
|
for (String m : new String[]{"d4", "Nf6", "c4", "g6", "Nc3", "d5", "Nf3", "c6"})
|
||||||
|
game.processString(m);
|
||||||
|
String eco = ecoDb.getEco(game.tree).first;
|
||||||
|
assertEquals("D90: Gruenfeld, Schlechter variation", eco);
|
||||||
|
assertEquals(0, ecoDb.getEco(game.tree).second.intValue());
|
||||||
|
game.processString("h4");
|
||||||
|
assertEquals("D90: Gruenfeld, Schlechter variation", eco);
|
||||||
|
assertEquals(1, ecoDb.getEco(game.tree).second.intValue());
|
||||||
|
game.processString("h5");
|
||||||
|
assertEquals("D90: Gruenfeld, Schlechter variation", eco);
|
||||||
|
assertEquals(2, ecoDb.getEco(game.tree).second.intValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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/4p3/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq - 0 3");
|
||||||
String eco = ecoDb.getEco(gt, gt.currentNode).first;
|
String eco = ecoDb.getEco(gt).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).first;
|
eco = ecoDb.getEco(gt).first;
|
||||||
assertEquals("B06: Robatsch (modern) defence", eco);
|
assertEquals("B06: Robatsch (modern) defence", eco);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user