DroidFish: Made it possible to use the ECO database as an opening book.

This commit is contained in:
Peter Osterlund
2016-11-20 14:14:41 +01:00
parent f7dc507f21
commit eeadd98fc4
6 changed files with 90 additions and 11 deletions

View File

@@ -72,6 +72,7 @@ you are not actively using the program.\
<string name="select_en_passant_file">Select En Passant File</string>
<string name="edit_move_counters">Edit Move Counters</string>
<string name="internal_book">&lt;Internal Book&gt;</string>
<string name="eco_book">&lt;ECO Book&gt;</string>
<string name="select_opening_book_file">Select opening book file</string>
<string name="select_chess_engine">Select Chess Engine</string>
<string name="select_pgn_file">Open PGN file</string>

View File

@@ -1430,7 +1430,9 @@ public class DroidFish extends Activity
private final void setBookOptions() {
BookOptions options = new BookOptions(bookOptions);
if (options.filename.length() > 0) {
if (options.filename.isEmpty())
options.filename = "internal:";
if (!options.filename.equals("internal:") && !options.filename.equals("eco:")) {
String sep = File.separator;
if (!options.filename.startsWith(sep)) {
File extDir = Environment.getExternalStorageDirectory();
@@ -2376,12 +2378,13 @@ public class DroidFish extends Activity
}
});
final int numFiles = fileNames.length;
CharSequence[] items = new CharSequence[numFiles + 1];
CharSequence[] items = new CharSequence[numFiles + 2];
for (int i = 0; i < numFiles; i++)
items[i] = fileNames[i];
items[numFiles] = getString(R.string.internal_book);
items[numFiles + 1] = getString(R.string.eco_book);
final CharSequence[] finalItems = items;
int defaultItem = numFiles;
int defaultItem = bookOptions.filename.equals("eco:") ? numFiles + 1 : numFiles;
for (int i = 0; i < numFiles; i++) {
if (bookOptions.filename.equals(items[i])) {
defaultItem = i;
@@ -2393,8 +2396,12 @@ public class DroidFish extends Activity
builder.setSingleChoiceItems(items, defaultItem, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Editor editor = settings.edit();
String bookFile = "";
if (item < numFiles)
final String bookFile;
if (item == numFiles)
bookFile = "internal:";
else if (item == numFiles + 1)
bookFile = "eco:";
else
bookFile = finalItems[item].toString();
editor.putString("bookFile", bookFile);
editor.commit();

View File

@@ -54,6 +54,7 @@ public final class DroidBook {
private Random rndGen = new SecureRandom();
private IOpeningBook externalBook = new NullBook();
private IOpeningBook ecoBook = new EcoBook();
private IOpeningBook internalBook = new InternalBook();
private BookOptions options = null;
@@ -78,6 +79,7 @@ public final class DroidBook {
else
externalBook = new NullBook();
externalBook.setOptions(options);
ecoBook.setOptions(options);
internalBook.setOptions(options);
}
@@ -86,7 +88,7 @@ public final class DroidBook {
if ((options != null) && (pos.fullMoveCounter > options.maxLength))
return null;
List<BookEntry> bookMoves = getBook().getBookEntries(pos);
if (bookMoves == null)
if (bookMoves == null || bookMoves.isEmpty())
return null;
ArrayList<Move> legalMoves = new MoveGen().legalMoves(pos);
@@ -178,6 +180,8 @@ public final class DroidBook {
private final IOpeningBook getBook() {
if (externalBook.enabled()) {
return externalBook;
} else if (ecoBook.enabled()) {
return ecoBook;
} else {
return internalBook;
}

View File

@@ -0,0 +1,38 @@
package org.petero.droidfish.book;
import java.util.ArrayList;
import org.petero.droidfish.book.DroidBook.BookEntry;
import org.petero.droidfish.gamelogic.Move;
import org.petero.droidfish.gamelogic.Position;
/** Opening book containing all moves that define the ECO opening classifications. */
public class EcoBook implements IOpeningBook {
private boolean enabled = false;
/** Constructor. */
EcoBook() {
}
@Override
public boolean enabled() {
return enabled;
}
@Override
public void setOptions(BookOptions options) {
enabled = options.filename.equals("eco:");
}
@Override
public ArrayList<BookEntry> getBookEntries(Position pos) {
ArrayList<Move> moves = EcoDb.getInstance().getMoves(pos);
ArrayList<BookEntry> entries = new ArrayList<BookEntry>();
for (int i = 0; i < moves.size(); i++) {
BookEntry be = new BookEntry(moves.get(i));
be.weight = 10000 - i;
entries.add(be);
}
return entries;
}
}

View File

@@ -148,6 +148,37 @@ public class EcoDb {
return new Pair<String, Integer>("", 0);
}
/** Get all moves in the ECO tree from a given position. */
public ArrayList<Move> getMoves(Position pos) {
ArrayList<Move> moves = new ArrayList<Move>();
long hash = pos.zobristHash();
Short idx = posHashToNodeIdx.get(hash);
if (idx != null) {
Node node = readNode(idx);
int child = node.firstChild;
while (child != -1) {
node = readNode(child);
moves.add(Move.fromCompressed(node.move));
child = node.nextSibling;
}
ArrayList<Short> lst = posHashToNodeIdx2.get(hash);
if (lst != null) {
for (Short idx2 : lst) {
node = readNode(idx2);
child = node.firstChild;
while (child != -1) {
node = readNode(child);
Move m = Move.fromCompressed(node.move);
if (!moves.contains(m))
moves.add(m);
child = node.nextSibling;
}
}
}
}
return moves;
}
private static class Node {
int move; // Move (compressed) leading to the position corresponding to this node

View File

@@ -38,6 +38,7 @@ import android.annotation.SuppressLint;
final class InternalBook implements IOpeningBook {
private static HashMap<Long, ArrayList<BookEntry>> bookMap;
private static int numBookMoves = -1;
private boolean enabled = false;
InternalBook() {
Thread t = new Thread(new Runnable() {
@@ -50,13 +51,9 @@ final class InternalBook implements IOpeningBook {
t.start();
}
static boolean canHandle(String filename) {
return filename.length() == 0;
}
@Override
public boolean enabled() {
return true;
return enabled;
}
@Override
@@ -76,6 +73,7 @@ final class InternalBook implements IOpeningBook {
@Override
public void setOptions(BookOptions options) {
enabled = options.filename.equals("internal:");
}
private synchronized final void initInternalBook() {