From eeadd98fc40a371001a318da36d5b316edcf8805 Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Sun, 20 Nov 2016 14:14:41 +0100 Subject: [PATCH] DroidFish: Made it possible to use the ECO database as an opening book. --- DroidFish/res/values/strings.xml | 1 + .../src/org/petero/droidfish/DroidFish.java | 17 ++++++--- .../org/petero/droidfish/book/DroidBook.java | 6 ++- .../org/petero/droidfish/book/EcoBook.java | 38 +++++++++++++++++++ .../src/org/petero/droidfish/book/EcoDb.java | 31 +++++++++++++++ .../petero/droidfish/book/InternalBook.java | 8 ++-- 6 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 DroidFish/src/org/petero/droidfish/book/EcoBook.java diff --git a/DroidFish/res/values/strings.xml b/DroidFish/res/values/strings.xml index 375afa6..70b5ebb 100644 --- a/DroidFish/res/values/strings.xml +++ b/DroidFish/res/values/strings.xml @@ -72,6 +72,7 @@ you are not actively using the program.\ Select En Passant File Edit Move Counters <Internal Book> + <ECO Book> Select opening book file Select Chess Engine Open PGN file diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java index c7eeddc..8007ac1 100644 --- a/DroidFish/src/org/petero/droidfish/DroidFish.java +++ b/DroidFish/src/org/petero/droidfish/DroidFish.java @@ -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(); diff --git a/DroidFish/src/org/petero/droidfish/book/DroidBook.java b/DroidFish/src/org/petero/droidfish/book/DroidBook.java index 83cc9f6..ce8c025 100644 --- a/DroidFish/src/org/petero/droidfish/book/DroidBook.java +++ b/DroidFish/src/org/petero/droidfish/book/DroidBook.java @@ -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 bookMoves = getBook().getBookEntries(pos); - if (bookMoves == null) + if (bookMoves == null || bookMoves.isEmpty()) return null; ArrayList 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; } diff --git a/DroidFish/src/org/petero/droidfish/book/EcoBook.java b/DroidFish/src/org/petero/droidfish/book/EcoBook.java new file mode 100644 index 0000000..37d238c --- /dev/null +++ b/DroidFish/src/org/petero/droidfish/book/EcoBook.java @@ -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 getBookEntries(Position pos) { + ArrayList moves = EcoDb.getInstance().getMoves(pos); + ArrayList entries = new ArrayList(); + for (int i = 0; i < moves.size(); i++) { + BookEntry be = new BookEntry(moves.get(i)); + be.weight = 10000 - i; + entries.add(be); + } + return entries; + } +} diff --git a/DroidFish/src/org/petero/droidfish/book/EcoDb.java b/DroidFish/src/org/petero/droidfish/book/EcoDb.java index 5a586aa..2138fbe 100644 --- a/DroidFish/src/org/petero/droidfish/book/EcoDb.java +++ b/DroidFish/src/org/petero/droidfish/book/EcoDb.java @@ -148,6 +148,37 @@ public class EcoDb { return new Pair("", 0); } + /** Get all moves in the ECO tree from a given position. */ + public ArrayList getMoves(Position pos) { + ArrayList moves = new ArrayList(); + 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 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 diff --git a/DroidFish/src/org/petero/droidfish/book/InternalBook.java b/DroidFish/src/org/petero/droidfish/book/InternalBook.java index eb63205..1098816 100644 --- a/DroidFish/src/org/petero/droidfish/book/InternalBook.java +++ b/DroidFish/src/org/petero/droidfish/book/InternalBook.java @@ -38,6 +38,7 @@ import android.annotation.SuppressLint; final class InternalBook implements IOpeningBook { private static HashMap> 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() {