diff --git a/DroidFish/.classpath b/DroidFish/.classpath
new file mode 100644
index 0000000..b068c94
--- /dev/null
+++ b/DroidFish/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/DroidFish/.externalToolBuilders/Native_Builder.launch b/DroidFish/.externalToolBuilders/Native_Builder.launch
new file mode 100644
index 0000000..a474d0c
--- /dev/null
+++ b/DroidFish/.externalToolBuilders/Native_Builder.launch
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/.project b/DroidFish/.project
new file mode 100644
index 0000000..62325d0
--- /dev/null
+++ b/DroidFish/.project
@@ -0,0 +1,43 @@
+
+
+ DroidFish
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ auto,full,incremental,
+
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/Native_Builder.launch
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/DroidFish/.settings/org.eclipse.jdt.core.prefs b/DroidFish/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1add5a0
--- /dev/null
+++ b/DroidFish/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Jul 09 17:18:36 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/DroidFish/AndroidManifest.xml b/DroidFish/AndroidManifest.xml
new file mode 100644
index 0000000..018aaac
--- /dev/null
+++ b/DroidFish/AndroidManifest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/assets/ChessCases.ttf b/DroidFish/assets/ChessCases.ttf
new file mode 100644
index 0000000..b5a7a93
Binary files /dev/null and b/DroidFish/assets/ChessCases.ttf differ
diff --git a/DroidFish/jni/Android.mk b/DroidFish/jni/Android.mk
new file mode 100644
index 0000000..9a19626
--- /dev/null
+++ b/DroidFish/jni/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := jni
+LOCAL_SRC_FILES := jni.cpp
+
+LOCAL_CFLAGS := \
+ -mandroid \
+ -DTARGET_OS=android -D__ANDROID__ \
+ -isystem $(SYSROOT)/usr/include
+
+LOCAL_STATIC_LIBRARIES := stockfish
+
+include $(BUILD_SHARED_LIBRARY)
+
+include jni/stockfish/Android.mk
diff --git a/DroidFish/jni/Application.mk b/DroidFish/jni/Application.mk
new file mode 100644
index 0000000..e5d3191
--- /dev/null
+++ b/DroidFish/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_STL := stlport_static
diff --git a/DroidFish/jni/jni.cpp b/DroidFish/jni/jni.cpp
new file mode 100644
index 0000000..0ad5e7c
--- /dev/null
+++ b/DroidFish/jni/jni.cpp
@@ -0,0 +1,169 @@
+/*
+ DroidFish - An Android chess program.
+ Copyright (C) 2011 Peter Österlund, peterosterlund2@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+int main(int argc, char* argv[]);
+
+static int fdFromChild = -1;
+static int fdToChild = -1;
+
+/*
+ * Class: org_petero_droidfish_engine_NativePipedProcess
+ * Method: startProcess
+ * Signature: ()V
+ */
+extern "C" JNIEXPORT void JNICALL Java_org_petero_droidfish_engine_NativePipedProcess_startProcess
+ (JNIEnv* env, jobject obj)
+{
+ int fd1[2]; /* parent -> child */
+ int fd2[2]; /* child -> parent */
+ if (pipe(fd1) < 0)
+ exit(1);
+ if (pipe(fd2) < 0)
+ exit(1);
+ int childpid = fork();
+ if (childpid == -1) {
+ exit(1);
+ }
+ if (childpid == 0) {
+ close(fd1[1]);
+ close(fd2[0]);
+ close(0); dup(fd1[0]); close(fd1[0]);
+ close(1); dup(fd2[1]); close(fd2[1]);
+ close(2); dup(1);
+ static char* argv[] = {(char*)"stockfish", NULL};
+ nice(10);
+ main(1, argv);
+ _exit(0);
+ } else {
+ close(fd1[0]);
+ close(fd2[1]);
+ fdFromChild = fd2[0];
+ fdToChild = fd1[1];
+ fcntl(fdFromChild, F_SETFL, O_NONBLOCK);
+ }
+}
+
+
+static std::deque inBuf;
+
+static bool getNextChar(int& c, int timeoutMillis) {
+ if (inBuf.empty()) {
+ fd_set readfds, writefds;
+ FD_ZERO(&readfds);
+ FD_SET(fdFromChild, &readfds);
+ struct timeval tv;
+ tv.tv_sec = timeoutMillis / 1000;
+ tv.tv_usec = (timeoutMillis % 1000) * 1000;
+ int ret = select(fdFromChild + 1, &readfds, NULL, NULL, &tv);
+ if (ret < 0)
+ return false;
+
+ static char buf[4096];
+ int len = read(fdFromChild, &buf[0], sizeof(buf));
+ for (int i = 0; i < len; i++)
+ inBuf.push_back(buf[i]);
+ }
+ if (inBuf.empty()) {
+ c = -1;
+ return true;
+ }
+ c = inBuf.front();
+ inBuf.pop_front();
+ return true;
+}
+
+static std::vector lineBuf;
+/*
+ * Class: org_petero_droidfish_engine_NativePipedProcess
+ * Method: readFromProcess
+ * Signature: (I)Ljava/lang/String;
+ */
+extern "C" JNIEXPORT jstring JNICALL Java_org_petero_droidfish_engine_NativePipedProcess_readFromProcess
+ (JNIEnv* env, jobject obj, jint timeoutMillis)
+{
+ struct timeval tv0, tv1;
+ while (true) {
+ int c;
+ gettimeofday(&tv0, NULL);
+ if (!getNextChar(c, timeoutMillis))
+ return 0; // Error
+ gettimeofday(&tv1, NULL);
+ int elapsedMillis = (tv1.tv_sec - tv0.tv_sec) * 1000 + (tv1.tv_usec - tv0.tv_usec) / 1000;
+ if (elapsedMillis > 0) {
+ timeoutMillis -= elapsedMillis;
+ if (timeoutMillis < 0) timeoutMillis = 0;
+ }
+ if (c == -1) { // Timeout
+ static char emptyString = 0;
+ return (*env).NewStringUTF(&emptyString);
+ }
+ if (c == '\n' || (c == '\r')) {
+ if (lineBuf.size() > 0) {
+ lineBuf.push_back(0);
+ jstring ret = (*env).NewStringUTF(&lineBuf[0]);
+ lineBuf.clear();
+ return ret;
+ }
+ } else {
+ lineBuf.push_back((char)c);
+ }
+ }
+}
+
+/*
+ * Class: org_petero_droidfish_engine_NativePipedProcess
+ * Method: writeToProcess
+ * Signature: (Ljava/lang/String;)V
+ */
+extern "C" JNIEXPORT void JNICALL Java_org_petero_droidfish_engine_NativePipedProcess_writeToProcess
+ (JNIEnv* env, jobject obj, jstring msg)
+{
+ const char* str = (*env).GetStringUTFChars(msg, NULL);
+ if (str) {
+ int len = strlen(str);
+ int written = 0;
+ while (written < len) {
+ int n = write(fdToChild, &str[written], len - written);
+ if (n <= 0)
+ break;
+ written += n;
+ }
+ (*env).ReleaseStringUTFChars(msg, str);
+ }
+}
+
+/*
+ * Class: org_petero_droidfish_engine_NativePipedProcess
+ * Method: getNPhysicalProcessors
+ * Signature: ()I
+ */
+extern "C" JNIEXPORT jint JNICALL Java_org_petero_droidfish_engine_NativePipedProcess_getNPhysicalProcessors
+ (JNIEnv *, jclass)
+{
+ return sysconf(_SC_NPROCESSORS_ONLN);
+}
diff --git a/DroidFish/jni/stockfish/Android.mk b/DroidFish/jni/stockfish/Android.mk
new file mode 100644
index 0000000..474f5e0
--- /dev/null
+++ b/DroidFish/jni/stockfish/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := stockfish
+LOCAL_SRC_FILES := \
+ evaluate.cpp move.cpp search.cpp \
+ benchmark.cpp movegen.cpp tt.cpp \
+ bitbase.cpp main.cpp movepick.cpp uci.cpp \
+ bitboard.cpp pawns.cpp ucioption.cpp \
+ book.cpp material.cpp position.cpp \
+ endgame.cpp misc.cpp timeman.cpp thread.cpp
+
+LOCAL_CFLAGS := -I$(LOCAL_PATH)/../stlport/stlport \
+ -mandroid \
+ -DTARGET_OS=android -D__ANDROID__ \
+ -isystem $(SYSROOT)/usr/include \
+ -DNO_PREFETCH=1
+
+LOCAL_STATIC_LIBRARIES := stlport
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/DroidFish/jni/stockfish/Copying.txt b/DroidFish/jni/stockfish/Copying.txt
new file mode 100644
index 0000000..818433e
--- /dev/null
+++ b/DroidFish/jni/stockfish/Copying.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/DroidFish/jni/stockfish/benchmark.cpp b/DroidFish/jni/stockfish/benchmark.cpp
new file mode 100644
index 0000000..df49787
--- /dev/null
+++ b/DroidFish/jni/stockfish/benchmark.cpp
@@ -0,0 +1,153 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+
+#include "position.h"
+#include "search.h"
+#include "ucioption.h"
+
+using namespace std;
+
+static const string Defaults[] = {
+ "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
+ "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -",
+ "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -",
+ "4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19",
+ "rq3rk1/ppp2ppp/1bnpb3/3N2B1/3NP3/7P/PPPQ1PP1/2KR3R w - - 7 14",
+ "r1bq1r1k/1pp1n1pp/1p1p4/4p2Q/4Pp2/1BNP4/PPP2PPP/3R1RK1 w - - 2 14",
+ "r3r1k1/2p2ppp/p1p1bn2/8/1q2P3/2NPQN2/PPP3PP/R4RK1 b - - 2 15",
+ "r1bbk1nr/pp3p1p/2n5/1N4p1/2Np1B2/8/PPP2PPP/2KR1B1R w kq - 0 13",
+ "r1bq1rk1/ppp1nppp/4n3/3p3Q/3P4/1BP1B3/PP1N2PP/R4RK1 w - - 1 16",
+ "4r1k1/r1q2ppp/ppp2n2/4P3/5Rb1/1N1BQ3/PPP3PP/R5K1 w - - 1 17",
+ "2rqkb1r/ppp2p2/2npb1p1/1N1Nn2p/2P1PP2/8/PP2B1PP/R1BQK2R b KQ - 0 11",
+ "r1bq1r1k/b1p1npp1/p2p3p/1p6/3PP3/1B2NN2/PP3PPP/R2Q1RK1 w - - 1 16",
+ "3r1rk1/p5pp/bpp1pp2/8/q1PP1P2/b3P3/P2NQRPP/1R2B1K1 b - - 6 22",
+ "r1q2rk1/2p1bppp/2Pp4/p6b/Q1PNp3/4B3/PP1R1PPP/2K4R w - - 2 18",
+ "4k2r/1pb2ppp/1p2p3/1R1p4/3P4/2r1PN2/P4PPP/1R4K1 b - - 3 22",
+ "3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - 4 26",
+ ""
+};
+
+
+/// benchmark() runs a simple benchmark by letting Stockfish analyze a set
+/// of positions for a given limit each. There are five parameters; the
+/// transposition table size, the number of search threads that should
+/// be used, the limit value spent for each position (optional, default
+/// is ply 12), an optional file name where to look for positions in fen
+/// format (default are the BenchmarkPositions defined above) and the type
+/// of the limit value: depth (default), time in secs or number of nodes.
+/// The analysis is written to a file named bench.txt.
+
+void benchmark(int argc, char* argv[]) {
+
+ vector fenList;
+ SearchLimits limits;
+ int64_t totalNodes;
+ int time;
+
+ // Load default positions
+ for (int i = 0; !Defaults[i].empty(); i++)
+ fenList.push_back(Defaults[i]);
+
+ // Assign default values to missing arguments
+ string ttSize = argc > 2 ? argv[2] : "128";
+ string threads = argc > 3 ? argv[3] : "1";
+ string valStr = argc > 4 ? argv[4] : "12";
+ string fenFile = argc > 5 ? argv[5] : "default";
+ string valType = argc > 6 ? argv[6] : "depth";
+
+ Options["Hash"].set_value(ttSize);
+ Options["Threads"].set_value(threads);
+ Options["OwnBook"].set_value("false");
+
+ // Search should be limited by nodes, time or depth ?
+ if (valType == "nodes")
+ limits.maxNodes = atoi(valStr.c_str());
+ else if (valType == "time")
+ limits.maxTime = 1000 * atoi(valStr.c_str()); // maxTime is in ms
+ else
+ limits.maxDepth = atoi(valStr.c_str());
+
+ // Do we need to load positions from a given FEN file ?
+ if (fenFile != "default")
+ {
+ string fen;
+ ifstream f(fenFile.c_str());
+
+ if (f.is_open())
+ {
+ fenList.clear();
+
+ while (getline(f, fen))
+ if (!fen.empty())
+ fenList.push_back(fen);
+
+ f.close();
+ }
+ else
+ {
+ cerr << "Unable to open FEN file " << fenFile << endl;
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ // Ok, let's start the benchmark !
+ totalNodes = 0;
+ time = get_system_time();
+
+ for (size_t i = 0; i < fenList.size(); i++)
+ {
+ Move moves[] = { MOVE_NONE };
+ Position pos(fenList[i], false, 0);
+
+ cerr << "\nBench position: " << i + 1 << '/' << fenList.size() << endl;
+
+ if (valType == "perft")
+ {
+ int64_t cnt = perft(pos, limits.maxDepth * ONE_PLY);
+ totalNodes += cnt;
+
+ cerr << "\nPerft " << limits.maxDepth << " nodes counted: " << cnt << endl;
+ }
+ else
+ {
+ if (!think(pos, limits, moves))
+ break;
+
+ totalNodes += pos.nodes_searched();
+ }
+ }
+
+ time = get_system_time() - time;
+
+ cerr << "\n==============================="
+ << "\nTotal time (ms) : " << time
+ << "\nNodes searched : " << totalNodes
+ << "\nNodes/second : " << (int)(totalNodes / (time / 1000.0)) << endl << endl;
+
+ // MS Visual C++ debug window always unconditionally closes when program
+ // exits, this is bad because we want to read results before.
+ #if (defined(WINDOWS) || defined(WIN32) || defined(WIN64))
+ cerr << "Press any key to exit" << endl;
+ cin >> time;
+ #endif
+}
diff --git a/DroidFish/jni/stockfish/bitbase.cpp b/DroidFish/jni/stockfish/bitbase.cpp
new file mode 100644
index 0000000..d623839
--- /dev/null
+++ b/DroidFish/jni/stockfish/bitbase.cpp
@@ -0,0 +1,284 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+
+#include "bitboard.h"
+#include "types.h"
+
+namespace {
+
+ enum Result {
+ RESULT_UNKNOWN,
+ RESULT_INVALID,
+ RESULT_WIN,
+ RESULT_LOSS,
+ RESULT_DRAW
+ };
+
+ struct KPKPosition {
+ void from_index(int index);
+ bool is_legal() const;
+ bool is_immediate_draw() const;
+ bool is_immediate_win() const;
+ Bitboard wk_attacks() const { return StepAttacksBB[WK][whiteKingSquare]; }
+ Bitboard bk_attacks() const { return StepAttacksBB[BK][blackKingSquare]; }
+ Bitboard pawn_attacks() const { return StepAttacksBB[WP][pawnSquare]; }
+
+ Square whiteKingSquare, blackKingSquare, pawnSquare;
+ Color sideToMove;
+ };
+
+ // The possible pawns squares are 24, the first 4 files and ranks from 2 to 7
+ const int IndexMax = 2 * 24 * 64 * 64; // color * wp_sq * wk_sq * bk_sq
+
+ // Each uint32_t stores results of 32 positions, one per bit
+ uint32_t KPKBitbase[IndexMax / 32];
+
+ Result classify_wtm(const KPKPosition& pos, const Result bb[]);
+ Result classify_btm(const KPKPosition& pos, const Result bb[]);
+ int compute_index(Square wksq, Square bksq, Square wpsq, Color stm);
+}
+
+
+uint32_t probe_kpk_bitbase(Square wksq, Square wpsq, Square bksq, Color stm) {
+
+ int index = compute_index(wksq, bksq, wpsq, stm);
+
+ return KPKBitbase[index / 32] & (1 << (index & 31));
+}
+
+
+void init_kpk_bitbase() {
+
+ Result bb[IndexMax];
+ KPKPosition pos;
+ bool repeat;
+
+ // Initialize table
+ for (int i = 0; i < IndexMax; i++)
+ {
+ pos.from_index(i);
+ bb[i] = !pos.is_legal() ? RESULT_INVALID
+ : pos.is_immediate_draw() ? RESULT_DRAW
+ : pos.is_immediate_win() ? RESULT_WIN : RESULT_UNKNOWN;
+ }
+
+ // Iterate until all positions are classified (30 cycles needed)
+ do {
+ repeat = false;
+
+ for (int i = 0; i < IndexMax; i++)
+ if (bb[i] == RESULT_UNKNOWN)
+ {
+ pos.from_index(i);
+
+ bb[i] = (pos.sideToMove == WHITE) ? classify_wtm(pos, bb)
+ : classify_btm(pos, bb);
+ if (bb[i] != RESULT_UNKNOWN)
+ repeat = true;
+ }
+
+ } while (repeat);
+
+ // Map 32 position results into one KPKBitbase[] entry
+ for (int i = 0; i < IndexMax / 32; i++)
+ for (int j = 0; j < 32; j++)
+ if (bb[32 * i + j] == RESULT_WIN || bb[32 * i + j] == RESULT_LOSS)
+ KPKBitbase[i] |= (1 << j);
+}
+
+
+namespace {
+
+ // A KPK bitbase index is an integer in [0, IndexMax] range
+ //
+ // Information is mapped in this way
+ //
+ // bit 0: side to move (WHITE or BLACK)
+ // bit 1- 6: black king square (from SQ_A1 to SQ_H8)
+ // bit 7-12: white king square (from SQ_A1 to SQ_H8)
+ // bit 13-14: white pawn file (from FILE_A to FILE_D)
+ // bit 15-17: white pawn rank - 1 (from RANK_2 - 1 to RANK_7 - 1)
+
+ int compute_index(Square wksq, Square bksq, Square wpsq, Color stm) {
+
+ assert(square_file(wpsq) <= FILE_D);
+
+ int p = int(square_file(wpsq)) + 4 * int(square_rank(wpsq) - 1);
+ int r = int(stm) + 2 * int(bksq) + 128 * int(wksq) + 8192 * p;
+
+ assert(r >= 0 && r < IndexMax);
+
+ return r;
+ }
+
+ void KPKPosition::from_index(int index) {
+
+ int s = (index / 8192) % 24;
+
+ sideToMove = Color(index % 2);
+ blackKingSquare = Square((index / 2) % 64);
+ whiteKingSquare = Square((index / 128) % 64);
+ pawnSquare = make_square(File(s % 4), Rank(s / 4 + 1));
+ }
+
+ bool KPKPosition::is_legal() const {
+
+ if ( whiteKingSquare == pawnSquare
+ || whiteKingSquare == blackKingSquare
+ || blackKingSquare == pawnSquare)
+ return false;
+
+ if (sideToMove == WHITE)
+ {
+ if ( bit_is_set(wk_attacks(), blackKingSquare)
+ || bit_is_set(pawn_attacks(), blackKingSquare))
+ return false;
+ }
+ else if (bit_is_set(bk_attacks(), whiteKingSquare))
+ return false;
+
+ return true;
+ }
+
+ bool KPKPosition::is_immediate_draw() const {
+
+ if (sideToMove == BLACK)
+ {
+ Bitboard wka = wk_attacks();
+ Bitboard bka = bk_attacks();
+
+ // Case 1: Stalemate
+ if ((bka & ~(wka | pawn_attacks())) == EmptyBoardBB)
+ return true;
+
+ // Case 2: King can capture pawn
+ if (bit_is_set(bka, pawnSquare) && !bit_is_set(wka, pawnSquare))
+ return true;
+ }
+ else
+ {
+ // Case 1: Stalemate (possible pawn files are only from A to D)
+ if ( whiteKingSquare == SQ_A8
+ && pawnSquare == SQ_A7
+ && (blackKingSquare == SQ_C7 || blackKingSquare == SQ_C8))
+ return true;
+ }
+ return false;
+ }
+
+ bool KPKPosition::is_immediate_win() const {
+
+ // The position is an immediate win if it is white to move and the
+ // white pawn can be promoted without getting captured.
+ return sideToMove == WHITE
+ && square_rank(pawnSquare) == RANK_7
+ && whiteKingSquare != pawnSquare + DELTA_N
+ && ( square_distance(blackKingSquare, pawnSquare + DELTA_N) > 1
+ || bit_is_set(wk_attacks(), pawnSquare + DELTA_N));
+ }
+
+ Result classify_wtm(const KPKPosition& pos, const Result bb[]) {
+
+ // If one move leads to a position classified as RESULT_LOSS, the result
+ // of the current position is RESULT_WIN. If all moves lead to positions
+ // classified as RESULT_DRAW, the current position is classified RESULT_DRAW
+ // otherwise the current position is classified as RESULT_UNKNOWN.
+
+ bool unknownFound = false;
+ Bitboard b;
+ Square s;
+ Result r;
+
+ // King moves
+ b = pos.wk_attacks();
+ while (b)
+ {
+ s = pop_1st_bit(&b);
+ r = bb[compute_index(s, pos.blackKingSquare, pos.pawnSquare, BLACK)];
+
+ if (r == RESULT_LOSS)
+ return RESULT_WIN;
+
+ if (r == RESULT_UNKNOWN)
+ unknownFound = true;
+ }
+
+ // Pawn moves
+ if (square_rank(pos.pawnSquare) < RANK_7)
+ {
+ s = pos.pawnSquare + DELTA_N;
+ r = bb[compute_index(pos.whiteKingSquare, pos.blackKingSquare, s, BLACK)];
+
+ if (r == RESULT_LOSS)
+ return RESULT_WIN;
+
+ if (r == RESULT_UNKNOWN)
+ unknownFound = true;
+
+ // Double pawn push
+ if ( square_rank(s) == RANK_3
+ && s != pos.whiteKingSquare
+ && s != pos.blackKingSquare)
+ {
+ s += DELTA_N;
+ r = bb[compute_index(pos.whiteKingSquare, pos.blackKingSquare, s, BLACK)];
+
+ if (r == RESULT_LOSS)
+ return RESULT_WIN;
+
+ if (r == RESULT_UNKNOWN)
+ unknownFound = true;
+ }
+ }
+ return unknownFound ? RESULT_UNKNOWN : RESULT_DRAW;
+ }
+
+
+ Result classify_btm(const KPKPosition& pos, const Result bb[]) {
+
+ // If one move leads to a position classified as RESULT_DRAW, the result
+ // of the current position is RESULT_DRAW. If all moves lead to positions
+ // classified as RESULT_WIN, the current position is classified as
+ // RESULT_LOSS. Otherwise, the current position is classified as
+ // RESULT_UNKNOWN.
+
+ bool unknownFound = false;
+ Bitboard b;
+ Square s;
+ Result r;
+
+ // King moves
+ b = pos.bk_attacks();
+ while (b)
+ {
+ s = pop_1st_bit(&b);
+ r = bb[compute_index(pos.whiteKingSquare, s, pos.pawnSquare, WHITE)];
+
+ if (r == RESULT_DRAW)
+ return RESULT_DRAW;
+
+ if (r == RESULT_UNKNOWN)
+ unknownFound = true;
+ }
+ return unknownFound ? RESULT_UNKNOWN : RESULT_LOSS;
+ }
+
+}
diff --git a/DroidFish/jni/stockfish/bitboard.cpp b/DroidFish/jni/stockfish/bitboard.cpp
new file mode 100644
index 0000000..110609d
--- /dev/null
+++ b/DroidFish/jni/stockfish/bitboard.cpp
@@ -0,0 +1,486 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+
+#include "bitboard.h"
+#include "bitcount.h"
+
+#if defined(IS_64BIT)
+
+const uint64_t BMult[64] = {
+ 0x0440049104032280ULL, 0x1021023C82008040ULL, 0x0404040082000048ULL,
+ 0x48C4440084048090ULL, 0x2801104026490000ULL, 0x4100880442040800ULL,
+ 0x0181011002E06040ULL, 0x9101004104200E00ULL, 0x1240848848310401ULL,
+ 0x2000142828050024ULL, 0x00001004024D5000ULL, 0x0102044400800200ULL,
+ 0x8108108820112000ULL, 0xA880818210C00046ULL, 0x4008008801082000ULL,
+ 0x0060882404049400ULL, 0x0104402004240810ULL, 0x000A002084250200ULL,
+ 0x00100B0880801100ULL, 0x0004080201220101ULL, 0x0044008080A00000ULL,
+ 0x0000202200842000ULL, 0x5006004882D00808ULL, 0x0000200045080802ULL,
+ 0x0086100020200601ULL, 0xA802080A20112C02ULL, 0x0080411218080900ULL,
+ 0x000200A0880080A0ULL, 0x9A01010000104000ULL, 0x0028008003100080ULL,
+ 0x0211021004480417ULL, 0x0401004188220806ULL, 0x00825051400C2006ULL,
+ 0x00140C0210943000ULL, 0x0000242800300080ULL, 0x00C2208120080200ULL,
+ 0x2430008200002200ULL, 0x1010100112008040ULL, 0x8141050100020842ULL,
+ 0x0000822081014405ULL, 0x800C049E40400804ULL, 0x4A0404028A000820ULL,
+ 0x0022060201041200ULL, 0x0360904200840801ULL, 0x0881A08208800400ULL,
+ 0x0060202C00400420ULL, 0x1204440086061400ULL, 0x0008184042804040ULL,
+ 0x0064040315300400ULL, 0x0C01008801090A00ULL, 0x0808010401140C00ULL,
+ 0x04004830C2020040ULL, 0x0080005002020054ULL, 0x40000C14481A0490ULL,
+ 0x0010500101042048ULL, 0x1010100200424000ULL, 0x0000640901901040ULL,
+ 0x00000A0201014840ULL, 0x00840082AA011002ULL, 0x010010840084240AULL,
+ 0x0420400810420608ULL, 0x8D40230408102100ULL, 0x4A00200612222409ULL,
+ 0x0A08520292120600ULL
+};
+
+const uint64_t RMult[64] = {
+ 0x0A8002C000108020ULL, 0x4440200140003000ULL, 0x8080200010011880ULL,
+ 0x0380180080141000ULL, 0x1A00060008211044ULL, 0x410001000A0C0008ULL,
+ 0x9500060004008100ULL, 0x0100024284A20700ULL, 0x0000802140008000ULL,
+ 0x0080C01002A00840ULL, 0x0402004282011020ULL, 0x9862000820420050ULL,
+ 0x0001001448011100ULL, 0x6432800200800400ULL, 0x040100010002000CULL,
+ 0x0002800D0010C080ULL, 0x90C0008000803042ULL, 0x4010004000200041ULL,
+ 0x0003010010200040ULL, 0x0A40828028001000ULL, 0x0123010008000430ULL,
+ 0x0024008004020080ULL, 0x0060040001104802ULL, 0x00582200028400D1ULL,
+ 0x4000802080044000ULL, 0x0408208200420308ULL, 0x0610038080102000ULL,
+ 0x3601000900100020ULL, 0x0000080080040180ULL, 0x00C2020080040080ULL,
+ 0x0080084400100102ULL, 0x4022408200014401ULL, 0x0040052040800082ULL,
+ 0x0B08200280804000ULL, 0x008A80A008801000ULL, 0x4000480080801000ULL,
+ 0x0911808800801401ULL, 0x822A003002001894ULL, 0x401068091400108AULL,
+ 0x000004A10A00004CULL, 0x2000800640008024ULL, 0x1486408102020020ULL,
+ 0x000100A000D50041ULL, 0x00810050020B0020ULL, 0x0204000800808004ULL,
+ 0x00020048100A000CULL, 0x0112000831020004ULL, 0x0009000040810002ULL,
+ 0x0440490200208200ULL, 0x8910401000200040ULL, 0x6404200050008480ULL,
+ 0x4B824A2010010100ULL, 0x04080801810C0080ULL, 0x00000400802A0080ULL,
+ 0x8224080110026400ULL, 0x40002C4104088200ULL, 0x01002100104A0282ULL,
+ 0x1208400811048021ULL, 0x3201014A40D02001ULL, 0x0005100019200501ULL,
+ 0x0101000208001005ULL, 0x0002008450080702ULL, 0x001002080301D00CULL,
+ 0x410201CE5C030092ULL
+};
+
+const int BShift[64] = {
+ 58, 59, 59, 59, 59, 59, 59, 58, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 57, 57, 57, 57, 59, 59, 59, 59, 57, 55, 55, 57, 59, 59,
+ 59, 59, 57, 55, 55, 57, 59, 59, 59, 59, 57, 57, 57, 57, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 58, 59, 59, 59, 59, 59, 59, 58
+};
+
+const int RShift[64] = {
+ 52, 53, 53, 53, 53, 53, 53, 52, 53, 54, 54, 54, 54, 54, 54, 53,
+ 53, 54, 54, 54, 54, 54, 54, 53, 53, 54, 54, 54, 54, 54, 54, 53,
+ 53, 54, 54, 54, 54, 54, 54, 53, 53, 54, 54, 54, 54, 54, 54, 53,
+ 53, 54, 54, 54, 54, 54, 54, 53, 52, 53, 53, 53, 53, 53, 53, 52
+};
+
+#else // if !defined(IS_64BIT)
+
+const uint64_t BMult[64] = {
+ 0x54142844C6A22981ULL, 0x710358A6EA25C19EULL, 0x704F746D63A4A8DCULL,
+ 0xBFED1A0B80F838C5ULL, 0x90561D5631E62110ULL, 0x2804260376E60944ULL,
+ 0x84A656409AA76871ULL, 0xF0267F64C28B6197ULL, 0x70764EBB762F0585ULL,
+ 0x92AA09E0CFE161DEULL, 0x41EE1F6BB266F60EULL, 0xDDCBF04F6039C444ULL,
+ 0x5A3FAB7BAC0D988AULL, 0xD3727877FA4EAA03ULL, 0xD988402D868DDAAEULL,
+ 0x812B291AFA075C7CULL, 0x94FAF987B685A932ULL, 0x3ED867D8470D08DBULL,
+ 0x92517660B8901DE8ULL, 0x2D97E43E058814B4ULL, 0x880A10C220B25582ULL,
+ 0xC7C6520D1F1A0477ULL, 0xDBFC7FBCD7656AA6ULL, 0x78B1B9BFB1A2B84FULL,
+ 0x2F20037F112A0BC1ULL, 0x657171EA2269A916ULL, 0xC08302B07142210EULL,
+ 0x0880A4403064080BULL, 0x3602420842208C00ULL, 0x852800DC7E0B6602ULL,
+ 0x595A3FBBAA0F03B2ULL, 0x9F01411558159D5EULL, 0x2B4A4A5F88B394F2ULL,
+ 0x4AFCBFFC292DD03AULL, 0x4A4094A3B3F10522ULL, 0xB06F00B491F30048ULL,
+ 0xD5B3820280D77004ULL, 0x8B2E01E7C8E57A75ULL, 0x2D342794E886C2E6ULL,
+ 0xC302C410CDE21461ULL, 0x111F426F1379C274ULL, 0xE0569220ABB31588ULL,
+ 0x5026D3064D453324ULL, 0xE2076040C343CD8AULL, 0x93EFD1E1738021EEULL,
+ 0xB680804BED143132ULL, 0x44E361B21986944CULL, 0x44C60170EF5C598CULL,
+ 0xF4DA475C195C9C94ULL, 0xA3AFBB5F72060B1DULL, 0xBC75F410E41C4FFCULL,
+ 0xB51C099390520922ULL, 0x902C011F8F8EC368ULL, 0x950B56B3D6F5490AULL,
+ 0x3909E0635BF202D0ULL, 0x5744F90206EC10CCULL, 0xDC59FD76317ABBC1ULL,
+ 0x881C7C67FCBFC4F6ULL, 0x47CA41E7E440D423ULL, 0xEB0C88112048D004ULL,
+ 0x51C60E04359AEF1AULL, 0x1AA1FE0E957A5554ULL, 0xDD9448DB4F5E3104ULL,
+ 0xDC01F6DCA4BEBBDCULL,
+};
+
+const uint64_t RMult[64] = {
+ 0xD7445CDEC88002C0ULL, 0xD0A505C1F2001722ULL, 0xE065D1C896002182ULL,
+ 0x9A8C41E75A000892ULL, 0x8900B10C89002AA8ULL, 0x9B28D1C1D60005A2ULL,
+ 0x015D6C88DE002D9AULL, 0xB1DBFC802E8016A9ULL, 0x149A1042D9D60029ULL,
+ 0xB9C08050599E002FULL, 0x132208C3AF300403ULL, 0xC1000CE2E9C50070ULL,
+ 0x9D9AA13C99020012ULL, 0xB6B078DAF71E0046ULL, 0x9D880182FB6E002EULL,
+ 0x52889F467E850037ULL, 0xDA6DC008D19A8480ULL, 0x468286034F902420ULL,
+ 0x7140AC09DC54C020ULL, 0xD76FFFFA39548808ULL, 0xEA901C4141500808ULL,
+ 0xC91004093F953A02ULL, 0x02882AFA8F6BB402ULL, 0xAEBE335692442C01ULL,
+ 0x0E904A22079FB91EULL, 0x13A514851055F606ULL, 0x76C782018C8FE632ULL,
+ 0x1DC012A9D116DA06ULL, 0x3C9E0037264FFFA6ULL, 0x2036002853C6E4A2ULL,
+ 0xE3FE08500AFB47D4ULL, 0xF38AF25C86B025C2ULL, 0xC0800E2182CF9A40ULL,
+ 0x72002480D1F60673ULL, 0x2500200BAE6E9B53ULL, 0xC60018C1EEFCA252ULL,
+ 0x0600590473E3608AULL, 0x46002C4AB3FE51B2ULL, 0xA200011486BCC8D2ULL,
+ 0xB680078095784C63ULL, 0x2742002639BF11AEULL, 0xC7D60021A5BDB142ULL,
+ 0xC8C04016BB83D820ULL, 0xBD520028123B4842ULL, 0x9D1600344AC2A832ULL,
+ 0x6A808005631C8A05ULL, 0x604600A148D5389AULL, 0xE2E40103D40DEA65ULL,
+ 0x945B5A0087C62A81ULL, 0x012DC200CD82D28EULL, 0x2431C600B5F9EF76ULL,
+ 0xFB142A006A9B314AULL, 0x06870E00A1C97D62ULL, 0x2A9DB2004A2689A2ULL,
+ 0xD3594600CAF5D1A2ULL, 0xEE0E4900439344A7ULL, 0x89C4D266CA25007AULL,
+ 0x3E0013A2743F97E3ULL, 0x0180E31A0431378AULL, 0x3A9E465A4D42A512ULL,
+ 0x98D0A11A0C0D9CC2ULL, 0x8E711C1ABA19B01EULL, 0x8DCDC836DD201142ULL,
+ 0x5AC08A4735370479ULL,
+};
+
+const int BShift[64] = {
+ 26, 27, 27, 27, 27, 27, 27, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 25, 23, 23, 25, 27, 27,
+ 27, 27, 25, 23, 23, 25, 27, 27, 27, 27, 25, 25, 25, 25, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 26, 27, 27, 27, 27, 27, 27, 26
+};
+
+const int RShift[64] = {
+ 20, 21, 21, 21, 21, 21, 21, 20, 21, 22, 22, 22, 22, 22, 22, 21,
+ 21, 22, 22, 22, 22, 22, 22, 21, 21, 22, 22, 22, 22, 22, 22, 21,
+ 21, 22, 22, 22, 22, 22, 22, 21, 21, 22, 22, 22, 22, 22, 22, 21,
+ 21, 22, 22, 22, 22, 22, 22, 21, 20, 21, 21, 21, 21, 21, 21, 20
+};
+
+#endif // defined(IS_64BIT)
+
+// Global bitboards definitions with static storage duration are
+// automatically set to zero before enter main().
+Bitboard RMask[64];
+int RAttackIndex[64];
+Bitboard RAttacks[0x19000];
+
+Bitboard BMask[64];
+int BAttackIndex[64];
+Bitboard BAttacks[0x1480];
+
+Bitboard SetMaskBB[65];
+Bitboard ClearMaskBB[65];
+
+Bitboard SquaresByColorBB[2];
+Bitboard FileBB[8];
+Bitboard RankBB[8];
+Bitboard NeighboringFilesBB[8];
+Bitboard ThisAndNeighboringFilesBB[8];
+Bitboard InFrontBB[2][8];
+Bitboard StepAttacksBB[16][64];
+Bitboard BetweenBB[64][64];
+Bitboard SquaresInFrontMask[2][64];
+Bitboard PassedPawnMask[2][64];
+Bitboard AttackSpanMask[2][64];
+
+Bitboard BishopPseudoAttacks[64];
+Bitboard RookPseudoAttacks[64];
+Bitboard QueenPseudoAttacks[64];
+
+uint8_t BitCount8Bit[256];
+
+
+namespace {
+
+ void init_masks();
+ void init_step_attacks();
+ void init_pseudo_attacks();
+ void init_between_bitboards();
+ Bitboard index_to_bitboard(int index, Bitboard mask);
+ Bitboard sliding_attacks(int sq, Bitboard occupied, int deltas[][2],
+ int fmin, int fmax, int rmin, int rmax);
+ void init_sliding_attacks(Bitboard attacks[], int attackIndex[], Bitboard mask[],
+ const int shift[], const Bitboard mult[], int deltas[][2]);
+}
+
+
+/// print_bitboard() prints a bitboard in an easily readable format to the
+/// standard output. This is sometimes useful for debugging.
+
+void print_bitboard(Bitboard b) {
+
+ for (Rank r = RANK_8; r >= RANK_1; r--)
+ {
+ std::cout << "+---+---+---+---+---+---+---+---+" << '\n';
+ for (File f = FILE_A; f <= FILE_H; f++)
+ std::cout << "| " << (bit_is_set(b, make_square(f, r)) ? 'X' : ' ') << ' ';
+
+ std::cout << "|\n";
+ }
+ std::cout << "+---+---+---+---+---+---+---+---+" << std::endl;
+}
+
+
+/// first_1() finds the least significant nonzero bit in a nonzero bitboard.
+/// pop_1st_bit() finds and clears the least significant nonzero bit in a
+/// nonzero bitboard.
+
+#if defined(IS_64BIT) && !defined(USE_BSFQ)
+
+static CACHE_LINE_ALIGNMENT
+const int BitTable[64] = {
+ 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40, 5, 17, 26,
+ 38, 15, 46, 29, 48, 10, 31, 35, 54, 21, 50, 41, 57, 63, 6, 12, 18, 24, 27,
+ 33, 39, 16, 37, 45, 47, 30, 53, 49, 56, 62, 11, 23, 32, 36, 44, 52, 55, 61,
+ 22, 43, 51, 60, 42, 59, 58
+};
+
+Square first_1(Bitboard b) {
+ return Square(BitTable[((b & -b) * 0x218a392cd3d5dbfULL) >> 58]);
+}
+
+Square pop_1st_bit(Bitboard* b) {
+ Bitboard bb = *b;
+ *b &= (*b - 1);
+ return Square(BitTable[((bb & -bb) * 0x218a392cd3d5dbfULL) >> 58]);
+}
+
+#elif !defined(USE_BSFQ)
+
+static CACHE_LINE_ALIGNMENT
+const int BitTable[64] = {
+ 63, 30, 3, 32, 25, 41, 22, 33, 15, 50, 42, 13, 11, 53, 19, 34, 61, 29, 2,
+ 51, 21, 43, 45, 10, 18, 47, 1, 54, 9, 57, 0, 35, 62, 31, 40, 4, 49, 5,
+ 52, 26, 60, 6, 23, 44, 46, 27, 56, 16, 7, 39, 48, 24, 59, 14, 12, 55, 38,
+ 28, 58, 20, 37, 17, 36, 8
+};
+
+Square first_1(Bitboard b) {
+
+ b ^= (b - 1);
+ uint32_t fold = int(b) ^ int(b >> 32);
+ return Square(BitTable[(fold * 0x783a9b23) >> 26]);
+}
+
+// Use type-punning
+union b_union {
+
+ Bitboard b;
+ struct {
+#if defined (BIGENDIAN)
+ uint32_t h;
+ uint32_t l;
+#else
+ uint32_t l;
+ uint32_t h;
+#endif
+ } dw;
+};
+
+Square pop_1st_bit(Bitboard* bb) {
+
+ b_union u;
+ Square ret;
+
+ u.b = *bb;
+
+ if (u.dw.l)
+ {
+ ret = Square(BitTable[((u.dw.l ^ (u.dw.l - 1)) * 0x783a9b23) >> 26]);
+ u.dw.l &= (u.dw.l - 1);
+ *bb = u.b;
+ return ret;
+ }
+ ret = Square(BitTable[((~(u.dw.h ^ (u.dw.h - 1))) * 0x783a9b23) >> 26]);
+ u.dw.h &= (u.dw.h - 1);
+ *bb = u.b;
+ return ret;
+}
+
+#endif // !defined(USE_BSFQ)
+
+
+/// init_bitboards() initializes various bitboard arrays. It is called during
+/// program initialization.
+
+void init_bitboards() {
+
+ int rookDeltas[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
+ int bishopDeltas[4][2] = {{1,1},{-1,1},{1,-1},{-1,-1}};
+
+ init_masks();
+ init_step_attacks();
+ init_sliding_attacks(RAttacks, RAttackIndex, RMask, RShift, RMult, rookDeltas);
+ init_sliding_attacks(BAttacks, BAttackIndex, BMask, BShift, BMult, bishopDeltas);
+ init_pseudo_attacks();
+ init_between_bitboards();
+}
+
+namespace {
+
+ // All functions below are used to precompute various bitboards during
+ // program initialization. Some of the functions may be difficult to
+ // understand, but they all seem to work correctly, and it should never
+ // be necessary to touch any of them.
+
+ void init_masks() {
+
+ SquaresByColorBB[DARK] = 0xAA55AA55AA55AA55ULL;
+ SquaresByColorBB[LIGHT] = ~SquaresByColorBB[DARK];
+
+ FileBB[FILE_A] = FileABB;
+ RankBB[RANK_1] = Rank1BB;
+
+ for (int f = FILE_B; f <= FILE_H; f++)
+ {
+ FileBB[f] = FileBB[f - 1] << 1;
+ RankBB[f] = RankBB[f - 1] << 8;
+ }
+
+ for (int f = FILE_A; f <= FILE_H; f++)
+ {
+ NeighboringFilesBB[f] = (f > FILE_A ? FileBB[f - 1] : 0) | (f < FILE_H ? FileBB[f + 1] : 0);
+ ThisAndNeighboringFilesBB[f] = FileBB[f] | NeighboringFilesBB[f];
+ }
+
+ for (int rw = RANK_7, rb = RANK_2; rw >= RANK_1; rw--, rb++)
+ {
+ InFrontBB[WHITE][rw] = InFrontBB[WHITE][rw + 1] | RankBB[rw + 1];
+ InFrontBB[BLACK][rb] = InFrontBB[BLACK][rb - 1] | RankBB[rb - 1];
+ }
+
+ SetMaskBB[SQ_NONE] = EmptyBoardBB;
+ ClearMaskBB[SQ_NONE] = ~SetMaskBB[SQ_NONE];
+
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ {
+ SetMaskBB[s] = (1ULL << s);
+ ClearMaskBB[s] = ~SetMaskBB[s];
+ }
+
+ for (Color c = WHITE; c <= BLACK; c++)
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ {
+ SquaresInFrontMask[c][s] = in_front_bb(c, s) & file_bb(s);
+ PassedPawnMask[c][s] = in_front_bb(c, s) & this_and_neighboring_files_bb(s);
+ AttackSpanMask[c][s] = in_front_bb(c, s) & neighboring_files_bb(s);
+ }
+
+ for (Bitboard b = 0; b < 256; b++)
+ BitCount8Bit[b] = (uint8_t)count_1s(b);
+ }
+
+ void init_step_attacks() {
+
+ const int step[][9] = {
+ {0},
+ {7,9,0}, {17,15,10,6,-6,-10,-15,-17,0}, {0}, {0}, {0},
+ {9,7,-7,-9,8,1,-1,-8,0}, {0}, {0},
+ {-7,-9,0}, {17,15,10,6,-6,-10,-15,-17,0}, {0}, {0}, {0},
+ {9,7,-7,-9,8,1,-1,-8,0}
+ };
+
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ for (Piece pc = WP; pc <= BK; pc++)
+ for (int k = 0; step[pc][k] != 0; k++)
+ {
+ Square to = s + Square(step[pc][k]);
+
+ if (square_is_ok(to) && square_distance(s, to) < 3)
+ set_bit(&StepAttacksBB[pc][s], to);
+ }
+ }
+
+ Bitboard sliding_attacks(int sq, Bitboard occupied, int deltas[][2],
+ int fmin, int fmax, int rmin, int rmax) {
+ int dx, dy, f, r;
+ int rk = sq / 8;
+ int fl = sq % 8;
+ Bitboard attacks = EmptyBoardBB;
+
+ for (int i = 0; i < 4; i++)
+ {
+ dx = deltas[i][0];
+ dy = deltas[i][1];
+ f = fl + dx;
+ r = rk + dy;
+
+ while ( (dx == 0 || (f >= fmin && f <= fmax))
+ && (dy == 0 || (r >= rmin && r <= rmax)))
+ {
+ attacks |= (1ULL << (f + r * 8));
+
+ if (occupied & (1ULL << (f + r * 8)))
+ break;
+
+ f += dx;
+ r += dy;
+ }
+ }
+ return attacks;
+ }
+
+ Bitboard index_to_bitboard(int index, Bitboard mask) {
+
+ Bitboard result = EmptyBoardBB;
+ int sq, cnt = 0;
+
+ while (mask)
+ {
+ sq = pop_1st_bit(&mask);
+
+ if (index & (1 << cnt++))
+ result |= (1ULL << sq);
+ }
+ return result;
+ }
+
+ void init_sliding_attacks(Bitboard attacks[], int attackIndex[], Bitboard mask[],
+ const int shift[], const Bitboard mult[], int deltas[][2]) {
+ Bitboard b, v;
+ int i, j, index;
+
+ for (i = index = 0; i < 64; i++)
+ {
+ attackIndex[i] = index;
+ mask[i] = sliding_attacks(i, 0, deltas, 1, 6, 1, 6);
+ j = 1 << ((CpuIs64Bit ? 64 : 32) - shift[i]);
+
+ for (int k = 0; k < j; k++)
+ {
+ b = index_to_bitboard(k, mask[i]);
+ v = CpuIs64Bit ? b * mult[i] : unsigned(b * mult[i] ^ (b >> 32) * (mult[i] >> 32));
+ attacks[index + (v >> shift[i])] = sliding_attacks(i, b, deltas, 0, 7, 0, 7);
+ }
+ index += j;
+ }
+ }
+
+ void init_pseudo_attacks() {
+
+ for (Square s = SQ_A1; s <= SQ_H8; s++)
+ {
+ BishopPseudoAttacks[s] = bishop_attacks_bb(s, EmptyBoardBB);
+ RookPseudoAttacks[s] = rook_attacks_bb(s, EmptyBoardBB);
+ QueenPseudoAttacks[s] = queen_attacks_bb(s, EmptyBoardBB);
+ }
+ }
+
+ void init_between_bitboards() {
+
+ Square s1, s2, s3, d;
+ int f, r;
+
+ for (s1 = SQ_A1; s1 <= SQ_H8; s1++)
+ for (s2 = SQ_A1; s2 <= SQ_H8; s2++)
+ if (bit_is_set(QueenPseudoAttacks[s1], s2))
+ {
+ f = file_distance(s1, s2);
+ r = rank_distance(s1, s2);
+
+ d = (s2 - s1) / Max(f, r);
+
+ for (s3 = s1 + d; s3 != s2; s3 += d)
+ set_bit(&(BetweenBB[s1][s2]), s3);
+ }
+ }
+
+}
diff --git a/DroidFish/jni/stockfish/bitboard.h b/DroidFish/jni/stockfish/bitboard.h
new file mode 100644
index 0000000..9704839
--- /dev/null
+++ b/DroidFish/jni/stockfish/bitboard.h
@@ -0,0 +1,295 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#if !defined(BITBOARD_H_INCLUDED)
+#define BITBOARD_H_INCLUDED
+
+#include "types.h"
+
+const Bitboard EmptyBoardBB = 0;
+
+const Bitboard FileABB = 0x0101010101010101ULL;
+const Bitboard FileBBB = FileABB << 1;
+const Bitboard FileCBB = FileABB << 2;
+const Bitboard FileDBB = FileABB << 3;
+const Bitboard FileEBB = FileABB << 4;
+const Bitboard FileFBB = FileABB << 5;
+const Bitboard FileGBB = FileABB << 6;
+const Bitboard FileHBB = FileABB << 7;
+
+const Bitboard Rank1BB = 0xFF;
+const Bitboard Rank2BB = Rank1BB << (8 * 1);
+const Bitboard Rank3BB = Rank1BB << (8 * 2);
+const Bitboard Rank4BB = Rank1BB << (8 * 3);
+const Bitboard Rank5BB = Rank1BB << (8 * 4);
+const Bitboard Rank6BB = Rank1BB << (8 * 5);
+const Bitboard Rank7BB = Rank1BB << (8 * 6);
+const Bitboard Rank8BB = Rank1BB << (8 * 7);
+
+extern Bitboard SquaresByColorBB[2];
+extern Bitboard FileBB[8];
+extern Bitboard NeighboringFilesBB[8];
+extern Bitboard ThisAndNeighboringFilesBB[8];
+extern Bitboard RankBB[8];
+extern Bitboard InFrontBB[2][8];
+
+extern Bitboard SetMaskBB[65];
+extern Bitboard ClearMaskBB[65];
+
+extern Bitboard StepAttacksBB[16][64];
+extern Bitboard BetweenBB[64][64];
+
+extern Bitboard SquaresInFrontMask[2][64];
+extern Bitboard PassedPawnMask[2][64];
+extern Bitboard AttackSpanMask[2][64];
+
+extern const uint64_t RMult[64];
+extern const int RShift[64];
+extern Bitboard RMask[64];
+extern int RAttackIndex[64];
+extern Bitboard RAttacks[0x19000];
+
+extern const uint64_t BMult[64];
+extern const int BShift[64];
+extern Bitboard BMask[64];
+extern int BAttackIndex[64];
+extern Bitboard BAttacks[0x1480];
+
+extern Bitboard BishopPseudoAttacks[64];
+extern Bitboard RookPseudoAttacks[64];
+extern Bitboard QueenPseudoAttacks[64];
+
+extern uint8_t BitCount8Bit[256];
+
+
+/// Functions for testing whether a given bit is set in a bitboard, and for
+/// setting and clearing bits.
+
+inline Bitboard bit_is_set(Bitboard b, Square s) {
+ return b & SetMaskBB[s];
+}
+
+inline void set_bit(Bitboard *b, Square s) {
+ *b |= SetMaskBB[s];
+}
+
+inline void clear_bit(Bitboard *b, Square s) {
+ *b &= ClearMaskBB[s];
+}
+
+
+/// Functions used to update a bitboard after a move. This is faster
+/// then calling a sequence of clear_bit() + set_bit()
+
+inline Bitboard make_move_bb(Square from, Square to) {
+ return SetMaskBB[from] | SetMaskBB[to];
+}
+
+inline void do_move_bb(Bitboard *b, Bitboard move_bb) {
+ *b ^= move_bb;
+}
+
+
+/// rank_bb() and file_bb() take a file or a square as input and return
+/// a bitboard representing all squares on the given file or rank.
+
+inline Bitboard rank_bb(Rank r) {
+ return RankBB[r];
+}
+
+inline Bitboard rank_bb(Square s) {
+ return RankBB[square_rank(s)];
+}
+
+inline Bitboard file_bb(File f) {
+ return FileBB[f];
+}
+
+inline Bitboard file_bb(Square s) {
+ return FileBB[square_file(s)];
+}
+
+
+/// neighboring_files_bb takes a file or a square as input and returns a
+/// bitboard representing all squares on the neighboring files.
+
+inline Bitboard neighboring_files_bb(File f) {
+ return NeighboringFilesBB[f];
+}
+
+inline Bitboard neighboring_files_bb(Square s) {
+ return NeighboringFilesBB[square_file(s)];
+}
+
+
+/// this_and_neighboring_files_bb takes a file or a square as input and returns
+/// a bitboard representing all squares on the given and neighboring files.
+
+inline Bitboard this_and_neighboring_files_bb(File f) {
+ return ThisAndNeighboringFilesBB[f];
+}
+
+inline Bitboard this_and_neighboring_files_bb(Square s) {
+ return ThisAndNeighboringFilesBB[square_file(s)];
+}
+
+
+/// in_front_bb() takes a color and a rank or square as input, and returns a
+/// bitboard representing all the squares on all ranks in front of the rank
+/// (or square), from the given color's point of view. For instance,
+/// in_front_bb(WHITE, RANK_5) will give all squares on ranks 6, 7 and 8, while
+/// in_front_bb(BLACK, SQ_D3) will give all squares on ranks 1 and 2.
+
+inline Bitboard in_front_bb(Color c, Rank r) {
+ return InFrontBB[c][r];
+}
+
+inline Bitboard in_front_bb(Color c, Square s) {
+ return InFrontBB[c][square_rank(s)];
+}
+
+
+/// Functions for computing sliding attack bitboards. rook_attacks_bb(),
+/// bishop_attacks_bb() and queen_attacks_bb() all take a square and a
+/// bitboard of occupied squares as input, and return a bitboard representing
+/// all squares attacked by a rook, bishop or queen on the given square.
+
+#if defined(IS_64BIT)
+
+inline Bitboard rook_attacks_bb(Square s, Bitboard blockers) {
+ Bitboard b = blockers & RMask[s];
+ return RAttacks[RAttackIndex[s] + ((b * RMult[s]) >> RShift[s])];
+}
+
+inline Bitboard bishop_attacks_bb(Square s, Bitboard blockers) {
+ Bitboard b = blockers & BMask[s];
+ return BAttacks[BAttackIndex[s] + ((b * BMult[s]) >> BShift[s])];
+}
+
+#else // if !defined(IS_64BIT)
+
+inline Bitboard rook_attacks_bb(Square s, Bitboard blockers) {
+ Bitboard b = blockers & RMask[s];
+ return RAttacks[RAttackIndex[s] +
+ (unsigned(int(b) * int(RMult[s]) ^ int(b >> 32) * int(RMult[s] >> 32)) >> RShift[s])];
+}
+
+inline Bitboard bishop_attacks_bb(Square s, Bitboard blockers) {
+ Bitboard b = blockers & BMask[s];
+ return BAttacks[BAttackIndex[s] +
+ (unsigned(int(b) * int(BMult[s]) ^ int(b >> 32) * int(BMult[s] >> 32)) >> BShift[s])];
+}
+
+#endif
+
+inline Bitboard queen_attacks_bb(Square s, Bitboard blockers) {
+ return rook_attacks_bb(s, blockers) | bishop_attacks_bb(s, blockers);
+}
+
+
+/// squares_between returns a bitboard representing all squares between
+/// two squares. For instance, squares_between(SQ_C4, SQ_F7) returns a
+/// bitboard with the bits for square d5 and e6 set. If s1 and s2 are not
+/// on the same line, file or diagonal, EmptyBoardBB is returned.
+
+inline Bitboard squares_between(Square s1, Square s2) {
+ return BetweenBB[s1][s2];
+}
+
+
+/// squares_in_front_of takes a color and a square as input, and returns a
+/// bitboard representing all squares along the line in front of the square,
+/// from the point of view of the given color. Definition of the table is:
+/// SquaresInFrontOf[c][s] = in_front_bb(c, s) & file_bb(s)
+
+inline Bitboard squares_in_front_of(Color c, Square s) {
+ return SquaresInFrontMask[c][s];
+}
+
+
+/// passed_pawn_mask takes a color and a square as input, and returns a
+/// bitboard mask which can be used to test if a pawn of the given color on
+/// the given square is a passed pawn. Definition of the table is:
+/// PassedPawnMask[c][s] = in_front_bb(c, s) & this_and_neighboring_files_bb(s)
+
+inline Bitboard passed_pawn_mask(Color c, Square s) {
+ return PassedPawnMask[c][s];
+}
+
+
+/// attack_span_mask takes a color and a square as input, and returns a bitboard
+/// representing all squares that can be attacked by a pawn of the given color
+/// when it moves along its file starting from the given square. Definition is:
+/// AttackSpanMask[c][s] = in_front_bb(c, s) & neighboring_files_bb(s);
+
+inline Bitboard attack_span_mask(Color c, Square s) {
+ return AttackSpanMask[c][s];
+}
+
+
+/// squares_aligned returns true if the squares s1, s2 and s3 are aligned
+/// either on a straight or on a diagonal line.
+
+inline bool squares_aligned(Square s1, Square s2, Square s3) {
+ return (BetweenBB[s1][s2] | BetweenBB[s1][s3] | BetweenBB[s2][s3])
+ & ((1ULL << s1) | (1ULL << s2) | (1ULL << s3));
+}
+
+
+/// first_1() finds the least significant nonzero bit in a nonzero bitboard.
+/// pop_1st_bit() finds and clears the least significant nonzero bit in a
+/// nonzero bitboard.
+
+#if defined(USE_BSFQ)
+
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+
+FORCE_INLINE Square first_1(Bitboard b) {
+ unsigned long index;
+ _BitScanForward64(&index, b);
+ return (Square) index;
+}
+#else
+
+FORCE_INLINE Square first_1(Bitboard b) { // Assembly code by Heinz van Saanen
+ Bitboard dummy;
+ __asm__("bsfq %1, %0": "=r"(dummy): "rm"(b) );
+ return (Square) dummy;
+}
+#endif
+
+FORCE_INLINE Square pop_1st_bit(Bitboard* b) {
+ const Square s = first_1(*b);
+ *b &= ~(1ULL<.
+*/
+
+#if !defined(BITCOUNT_H_INCLUDED)
+#define BITCOUNT_H_INCLUDED
+
+#include "types.h"
+
+enum BitCountType {
+ CNT64,
+ CNT64_MAX15,
+ CNT32,
+ CNT32_MAX15,
+ CNT_POPCNT
+};
+
+/// count_1s() counts the number of nonzero bits in a bitboard.
+/// We have different optimized versions according if platform
+/// is 32 or 64 bits, and to the maximum number of nonzero bits.
+/// We also support hardware popcnt instruction. See Readme.txt
+/// on how to pgo compile with popcnt support.
+template inline int count_1s(Bitboard);
+
+template<>
+inline int count_1s(Bitboard b) {
+ b -= ((b>>1) & 0x5555555555555555ULL);
+ b = ((b>>2) & 0x3333333333333333ULL) + (b & 0x3333333333333333ULL);
+ b = ((b>>4) + b) & 0x0F0F0F0F0F0F0F0FULL;
+ b *= 0x0101010101010101ULL;
+ return int(b >> 56);
+}
+
+template<>
+inline int count_1s(Bitboard b) {
+ b -= (b>>1) & 0x5555555555555555ULL;
+ b = ((b>>2) & 0x3333333333333333ULL) + (b & 0x3333333333333333ULL);
+ b *= 0x1111111111111111ULL;
+ return int(b >> 60);
+}
+
+template<>
+inline int count_1s(Bitboard b) {
+ unsigned w = unsigned(b >> 32), v = unsigned(b);
+ v -= (v >> 1) & 0x55555555; // 0-2 in 2 bits
+ w -= (w >> 1) & 0x55555555;
+ v = ((v >> 2) & 0x33333333) + (v & 0x33333333); // 0-4 in 4 bits
+ w = ((w >> 2) & 0x33333333) + (w & 0x33333333);
+ v = ((v >> 4) + v) & 0x0F0F0F0F; // 0-8 in 8 bits
+ v += (((w >> 4) + w) & 0x0F0F0F0F); // 0-16 in 8 bits
+ v *= 0x01010101; // mul is fast on amd procs
+ return int(v >> 24);
+}
+
+template<>
+inline int count_1s(Bitboard b) {
+ unsigned w = unsigned(b >> 32), v = unsigned(b);
+ v -= (v >> 1) & 0x55555555; // 0-2 in 2 bits
+ w -= (w >> 1) & 0x55555555;
+ v = ((v >> 2) & 0x33333333) + (v & 0x33333333); // 0-4 in 4 bits
+ w = ((w >> 2) & 0x33333333) + (w & 0x33333333);
+ v += w; // 0-8 in 4 bits
+ v *= 0x11111111;
+ return int(v >> 28);
+}
+
+template<>
+inline int count_1s(Bitboard b) {
+#if !defined(USE_POPCNT)
+ return int(b != 0); // Avoid 'b not used' warning
+#elif defined(_MSC_VER) && defined(__INTEL_COMPILER)
+ return _mm_popcnt_u64(b);
+#elif defined(_MSC_VER)
+ return (int)__popcnt64(b);
+#elif defined(__GNUC__)
+ unsigned long ret;
+ __asm__("popcnt %1, %0" : "=r" (ret) : "r" (b));
+ return ret;
+#endif
+}
+
+#endif // !defined(BITCOUNT_H_INCLUDED)
diff --git a/DroidFish/jni/stockfish/book.cpp b/DroidFish/jni/stockfish/book.cpp
new file mode 100644
index 0000000..8c7cd52
--- /dev/null
+++ b/DroidFish/jni/stockfish/book.cpp
@@ -0,0 +1,525 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+
+/*
+ The code in this file is based on the opening book code in PolyGlot
+ by Fabien Letouzey. PolyGlot is available under the GNU General
+ Public License, and can be downloaded from http://wbec-ridderkerk.nl
+*/
+
+#include
+#include
+
+#include "book.h"
+#include "movegen.h"
+
+using namespace std;
+
+namespace {
+
+ // Random numbers from PolyGlot, used to compute book hash keys
+ const uint64_t Random64[781] = {
+ 0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL,
+ 0x9C15F73E62A76AE2ULL, 0x75834465489C0C89ULL, 0x3290AC3A203001BFULL,
+ 0x0FBBAD1F61042279ULL, 0xE83A908FF2FB60CAULL, 0x0D7E765D58755C10ULL,
+ 0x1A083822CEAFE02DULL, 0x9605D5F0E25EC3B0ULL, 0xD021FF5CD13A2ED5ULL,
+ 0x40BDF15D4A672E32ULL, 0x011355146FD56395ULL, 0x5DB4832046F3D9E5ULL,
+ 0x239F8B2D7FF719CCULL, 0x05D1A1AE85B49AA1ULL, 0x679F848F6E8FC971ULL,
+ 0x7449BBFF801FED0BULL, 0x7D11CDB1C3B7ADF0ULL, 0x82C7709E781EB7CCULL,
+ 0xF3218F1C9510786CULL, 0x331478F3AF51BBE6ULL, 0x4BB38DE5E7219443ULL,
+ 0xAA649C6EBCFD50FCULL, 0x8DBD98A352AFD40BULL, 0x87D2074B81D79217ULL,
+ 0x19F3C751D3E92AE1ULL, 0xB4AB30F062B19ABFULL, 0x7B0500AC42047AC4ULL,
+ 0xC9452CA81A09D85DULL, 0x24AA6C514DA27500ULL, 0x4C9F34427501B447ULL,
+ 0x14A68FD73C910841ULL, 0xA71B9B83461CBD93ULL, 0x03488B95B0F1850FULL,
+ 0x637B2B34FF93C040ULL, 0x09D1BC9A3DD90A94ULL, 0x3575668334A1DD3BULL,
+ 0x735E2B97A4C45A23ULL, 0x18727070F1BD400BULL, 0x1FCBACD259BF02E7ULL,
+ 0xD310A7C2CE9B6555ULL, 0xBF983FE0FE5D8244ULL, 0x9F74D14F7454A824ULL,
+ 0x51EBDC4AB9BA3035ULL, 0x5C82C505DB9AB0FAULL, 0xFCF7FE8A3430B241ULL,
+ 0x3253A729B9BA3DDEULL, 0x8C74C368081B3075ULL, 0xB9BC6C87167C33E7ULL,
+ 0x7EF48F2B83024E20ULL, 0x11D505D4C351BD7FULL, 0x6568FCA92C76A243ULL,
+ 0x4DE0B0F40F32A7B8ULL, 0x96D693460CC37E5DULL, 0x42E240CB63689F2FULL,
+ 0x6D2BDCDAE2919661ULL, 0x42880B0236E4D951ULL, 0x5F0F4A5898171BB6ULL,
+ 0x39F890F579F92F88ULL, 0x93C5B5F47356388BULL, 0x63DC359D8D231B78ULL,
+ 0xEC16CA8AEA98AD76ULL, 0x5355F900C2A82DC7ULL, 0x07FB9F855A997142ULL,
+ 0x5093417AA8A7ED5EULL, 0x7BCBC38DA25A7F3CULL, 0x19FC8A768CF4B6D4ULL,
+ 0x637A7780DECFC0D9ULL, 0x8249A47AEE0E41F7ULL, 0x79AD695501E7D1E8ULL,
+ 0x14ACBAF4777D5776ULL, 0xF145B6BECCDEA195ULL, 0xDABF2AC8201752FCULL,
+ 0x24C3C94DF9C8D3F6ULL, 0xBB6E2924F03912EAULL, 0x0CE26C0B95C980D9ULL,
+ 0xA49CD132BFBF7CC4ULL, 0xE99D662AF4243939ULL, 0x27E6AD7891165C3FULL,
+ 0x8535F040B9744FF1ULL, 0x54B3F4FA5F40D873ULL, 0x72B12C32127FED2BULL,
+ 0xEE954D3C7B411F47ULL, 0x9A85AC909A24EAA1ULL, 0x70AC4CD9F04F21F5ULL,
+ 0xF9B89D3E99A075C2ULL, 0x87B3E2B2B5C907B1ULL, 0xA366E5B8C54F48B8ULL,
+ 0xAE4A9346CC3F7CF2ULL, 0x1920C04D47267BBDULL, 0x87BF02C6B49E2AE9ULL,
+ 0x092237AC237F3859ULL, 0xFF07F64EF8ED14D0ULL, 0x8DE8DCA9F03CC54EULL,
+ 0x9C1633264DB49C89ULL, 0xB3F22C3D0B0B38EDULL, 0x390E5FB44D01144BULL,
+ 0x5BFEA5B4712768E9ULL, 0x1E1032911FA78984ULL, 0x9A74ACB964E78CB3ULL,
+ 0x4F80F7A035DAFB04ULL, 0x6304D09A0B3738C4ULL, 0x2171E64683023A08ULL,
+ 0x5B9B63EB9CEFF80CULL, 0x506AACF489889342ULL, 0x1881AFC9A3A701D6ULL,
+ 0x6503080440750644ULL, 0xDFD395339CDBF4A7ULL, 0xEF927DBCF00C20F2ULL,
+ 0x7B32F7D1E03680ECULL, 0xB9FD7620E7316243ULL, 0x05A7E8A57DB91B77ULL,
+ 0xB5889C6E15630A75ULL, 0x4A750A09CE9573F7ULL, 0xCF464CEC899A2F8AULL,
+ 0xF538639CE705B824ULL, 0x3C79A0FF5580EF7FULL, 0xEDE6C87F8477609DULL,
+ 0x799E81F05BC93F31ULL, 0x86536B8CF3428A8CULL, 0x97D7374C60087B73ULL,
+ 0xA246637CFF328532ULL, 0x043FCAE60CC0EBA0ULL, 0x920E449535DD359EULL,
+ 0x70EB093B15B290CCULL, 0x73A1921916591CBDULL, 0x56436C9FE1A1AA8DULL,
+ 0xEFAC4B70633B8F81ULL, 0xBB215798D45DF7AFULL, 0x45F20042F24F1768ULL,
+ 0x930F80F4E8EB7462ULL, 0xFF6712FFCFD75EA1ULL, 0xAE623FD67468AA70ULL,
+ 0xDD2C5BC84BC8D8FCULL, 0x7EED120D54CF2DD9ULL, 0x22FE545401165F1CULL,
+ 0xC91800E98FB99929ULL, 0x808BD68E6AC10365ULL, 0xDEC468145B7605F6ULL,
+ 0x1BEDE3A3AEF53302ULL, 0x43539603D6C55602ULL, 0xAA969B5C691CCB7AULL,
+ 0xA87832D392EFEE56ULL, 0x65942C7B3C7E11AEULL, 0xDED2D633CAD004F6ULL,
+ 0x21F08570F420E565ULL, 0xB415938D7DA94E3CULL, 0x91B859E59ECB6350ULL,
+ 0x10CFF333E0ED804AULL, 0x28AED140BE0BB7DDULL, 0xC5CC1D89724FA456ULL,
+ 0x5648F680F11A2741ULL, 0x2D255069F0B7DAB3ULL, 0x9BC5A38EF729ABD4ULL,
+ 0xEF2F054308F6A2BCULL, 0xAF2042F5CC5C2858ULL, 0x480412BAB7F5BE2AULL,
+ 0xAEF3AF4A563DFE43ULL, 0x19AFE59AE451497FULL, 0x52593803DFF1E840ULL,
+ 0xF4F076E65F2CE6F0ULL, 0x11379625747D5AF3ULL, 0xBCE5D2248682C115ULL,
+ 0x9DA4243DE836994FULL, 0x066F70B33FE09017ULL, 0x4DC4DE189B671A1CULL,
+ 0x51039AB7712457C3ULL, 0xC07A3F80C31FB4B4ULL, 0xB46EE9C5E64A6E7CULL,
+ 0xB3819A42ABE61C87ULL, 0x21A007933A522A20ULL, 0x2DF16F761598AA4FULL,
+ 0x763C4A1371B368FDULL, 0xF793C46702E086A0ULL, 0xD7288E012AEB8D31ULL,
+ 0xDE336A2A4BC1C44BULL, 0x0BF692B38D079F23ULL, 0x2C604A7A177326B3ULL,
+ 0x4850E73E03EB6064ULL, 0xCFC447F1E53C8E1BULL, 0xB05CA3F564268D99ULL,
+ 0x9AE182C8BC9474E8ULL, 0xA4FC4BD4FC5558CAULL, 0xE755178D58FC4E76ULL,
+ 0x69B97DB1A4C03DFEULL, 0xF9B5B7C4ACC67C96ULL, 0xFC6A82D64B8655FBULL,
+ 0x9C684CB6C4D24417ULL, 0x8EC97D2917456ED0ULL, 0x6703DF9D2924E97EULL,
+ 0xC547F57E42A7444EULL, 0x78E37644E7CAD29EULL, 0xFE9A44E9362F05FAULL,
+ 0x08BD35CC38336615ULL, 0x9315E5EB3A129ACEULL, 0x94061B871E04DF75ULL,
+ 0xDF1D9F9D784BA010ULL, 0x3BBA57B68871B59DULL, 0xD2B7ADEEDED1F73FULL,
+ 0xF7A255D83BC373F8ULL, 0xD7F4F2448C0CEB81ULL, 0xD95BE88CD210FFA7ULL,
+ 0x336F52F8FF4728E7ULL, 0xA74049DAC312AC71ULL, 0xA2F61BB6E437FDB5ULL,
+ 0x4F2A5CB07F6A35B3ULL, 0x87D380BDA5BF7859ULL, 0x16B9F7E06C453A21ULL,
+ 0x7BA2484C8A0FD54EULL, 0xF3A678CAD9A2E38CULL, 0x39B0BF7DDE437BA2ULL,
+ 0xFCAF55C1BF8A4424ULL, 0x18FCF680573FA594ULL, 0x4C0563B89F495AC3ULL,
+ 0x40E087931A00930DULL, 0x8CFFA9412EB642C1ULL, 0x68CA39053261169FULL,
+ 0x7A1EE967D27579E2ULL, 0x9D1D60E5076F5B6FULL, 0x3810E399B6F65BA2ULL,
+ 0x32095B6D4AB5F9B1ULL, 0x35CAB62109DD038AULL, 0xA90B24499FCFAFB1ULL,
+ 0x77A225A07CC2C6BDULL, 0x513E5E634C70E331ULL, 0x4361C0CA3F692F12ULL,
+ 0xD941ACA44B20A45BULL, 0x528F7C8602C5807BULL, 0x52AB92BEB9613989ULL,
+ 0x9D1DFA2EFC557F73ULL, 0x722FF175F572C348ULL, 0x1D1260A51107FE97ULL,
+ 0x7A249A57EC0C9BA2ULL, 0x04208FE9E8F7F2D6ULL, 0x5A110C6058B920A0ULL,
+ 0x0CD9A497658A5698ULL, 0x56FD23C8F9715A4CULL, 0x284C847B9D887AAEULL,
+ 0x04FEABFBBDB619CBULL, 0x742E1E651C60BA83ULL, 0x9A9632E65904AD3CULL,
+ 0x881B82A13B51B9E2ULL, 0x506E6744CD974924ULL, 0xB0183DB56FFC6A79ULL,
+ 0x0ED9B915C66ED37EULL, 0x5E11E86D5873D484ULL, 0xF678647E3519AC6EULL,
+ 0x1B85D488D0F20CC5ULL, 0xDAB9FE6525D89021ULL, 0x0D151D86ADB73615ULL,
+ 0xA865A54EDCC0F019ULL, 0x93C42566AEF98FFBULL, 0x99E7AFEABE000731ULL,
+ 0x48CBFF086DDF285AULL, 0x7F9B6AF1EBF78BAFULL, 0x58627E1A149BBA21ULL,
+ 0x2CD16E2ABD791E33ULL, 0xD363EFF5F0977996ULL, 0x0CE2A38C344A6EEDULL,
+ 0x1A804AADB9CFA741ULL, 0x907F30421D78C5DEULL, 0x501F65EDB3034D07ULL,
+ 0x37624AE5A48FA6E9ULL, 0x957BAF61700CFF4EULL, 0x3A6C27934E31188AULL,
+ 0xD49503536ABCA345ULL, 0x088E049589C432E0ULL, 0xF943AEE7FEBF21B8ULL,
+ 0x6C3B8E3E336139D3ULL, 0x364F6FFA464EE52EULL, 0xD60F6DCEDC314222ULL,
+ 0x56963B0DCA418FC0ULL, 0x16F50EDF91E513AFULL, 0xEF1955914B609F93ULL,
+ 0x565601C0364E3228ULL, 0xECB53939887E8175ULL, 0xBAC7A9A18531294BULL,
+ 0xB344C470397BBA52ULL, 0x65D34954DAF3CEBDULL, 0xB4B81B3FA97511E2ULL,
+ 0xB422061193D6F6A7ULL, 0x071582401C38434DULL, 0x7A13F18BBEDC4FF5ULL,
+ 0xBC4097B116C524D2ULL, 0x59B97885E2F2EA28ULL, 0x99170A5DC3115544ULL,
+ 0x6F423357E7C6A9F9ULL, 0x325928EE6E6F8794ULL, 0xD0E4366228B03343ULL,
+ 0x565C31F7DE89EA27ULL, 0x30F5611484119414ULL, 0xD873DB391292ED4FULL,
+ 0x7BD94E1D8E17DEBCULL, 0xC7D9F16864A76E94ULL, 0x947AE053EE56E63CULL,
+ 0xC8C93882F9475F5FULL, 0x3A9BF55BA91F81CAULL, 0xD9A11FBB3D9808E4ULL,
+ 0x0FD22063EDC29FCAULL, 0xB3F256D8ACA0B0B9ULL, 0xB03031A8B4516E84ULL,
+ 0x35DD37D5871448AFULL, 0xE9F6082B05542E4EULL, 0xEBFAFA33D7254B59ULL,
+ 0x9255ABB50D532280ULL, 0xB9AB4CE57F2D34F3ULL, 0x693501D628297551ULL,
+ 0xC62C58F97DD949BFULL, 0xCD454F8F19C5126AULL, 0xBBE83F4ECC2BDECBULL,
+ 0xDC842B7E2819E230ULL, 0xBA89142E007503B8ULL, 0xA3BC941D0A5061CBULL,
+ 0xE9F6760E32CD8021ULL, 0x09C7E552BC76492FULL, 0x852F54934DA55CC9ULL,
+ 0x8107FCCF064FCF56ULL, 0x098954D51FFF6580ULL, 0x23B70EDB1955C4BFULL,
+ 0xC330DE426430F69DULL, 0x4715ED43E8A45C0AULL, 0xA8D7E4DAB780A08DULL,
+ 0x0572B974F03CE0BBULL, 0xB57D2E985E1419C7ULL, 0xE8D9ECBE2CF3D73FULL,
+ 0x2FE4B17170E59750ULL, 0x11317BA87905E790ULL, 0x7FBF21EC8A1F45ECULL,
+ 0x1725CABFCB045B00ULL, 0x964E915CD5E2B207ULL, 0x3E2B8BCBF016D66DULL,
+ 0xBE7444E39328A0ACULL, 0xF85B2B4FBCDE44B7ULL, 0x49353FEA39BA63B1ULL,
+ 0x1DD01AAFCD53486AULL, 0x1FCA8A92FD719F85ULL, 0xFC7C95D827357AFAULL,
+ 0x18A6A990C8B35EBDULL, 0xCCCB7005C6B9C28DULL, 0x3BDBB92C43B17F26ULL,
+ 0xAA70B5B4F89695A2ULL, 0xE94C39A54A98307FULL, 0xB7A0B174CFF6F36EULL,
+ 0xD4DBA84729AF48ADULL, 0x2E18BC1AD9704A68ULL, 0x2DE0966DAF2F8B1CULL,
+ 0xB9C11D5B1E43A07EULL, 0x64972D68DEE33360ULL, 0x94628D38D0C20584ULL,
+ 0xDBC0D2B6AB90A559ULL, 0xD2733C4335C6A72FULL, 0x7E75D99D94A70F4DULL,
+ 0x6CED1983376FA72BULL, 0x97FCAACBF030BC24ULL, 0x7B77497B32503B12ULL,
+ 0x8547EDDFB81CCB94ULL, 0x79999CDFF70902CBULL, 0xCFFE1939438E9B24ULL,
+ 0x829626E3892D95D7ULL, 0x92FAE24291F2B3F1ULL, 0x63E22C147B9C3403ULL,
+ 0xC678B6D860284A1CULL, 0x5873888850659AE7ULL, 0x0981DCD296A8736DULL,
+ 0x9F65789A6509A440ULL, 0x9FF38FED72E9052FULL, 0xE479EE5B9930578CULL,
+ 0xE7F28ECD2D49EECDULL, 0x56C074A581EA17FEULL, 0x5544F7D774B14AEFULL,
+ 0x7B3F0195FC6F290FULL, 0x12153635B2C0CF57ULL, 0x7F5126DBBA5E0CA7ULL,
+ 0x7A76956C3EAFB413ULL, 0x3D5774A11D31AB39ULL, 0x8A1B083821F40CB4ULL,
+ 0x7B4A38E32537DF62ULL, 0x950113646D1D6E03ULL, 0x4DA8979A0041E8A9ULL,
+ 0x3BC36E078F7515D7ULL, 0x5D0A12F27AD310D1ULL, 0x7F9D1A2E1EBE1327ULL,
+ 0xDA3A361B1C5157B1ULL, 0xDCDD7D20903D0C25ULL, 0x36833336D068F707ULL,
+ 0xCE68341F79893389ULL, 0xAB9090168DD05F34ULL, 0x43954B3252DC25E5ULL,
+ 0xB438C2B67F98E5E9ULL, 0x10DCD78E3851A492ULL, 0xDBC27AB5447822BFULL,
+ 0x9B3CDB65F82CA382ULL, 0xB67B7896167B4C84ULL, 0xBFCED1B0048EAC50ULL,
+ 0xA9119B60369FFEBDULL, 0x1FFF7AC80904BF45ULL, 0xAC12FB171817EEE7ULL,
+ 0xAF08DA9177DDA93DULL, 0x1B0CAB936E65C744ULL, 0xB559EB1D04E5E932ULL,
+ 0xC37B45B3F8D6F2BAULL, 0xC3A9DC228CAAC9E9ULL, 0xF3B8B6675A6507FFULL,
+ 0x9FC477DE4ED681DAULL, 0x67378D8ECCEF96CBULL, 0x6DD856D94D259236ULL,
+ 0xA319CE15B0B4DB31ULL, 0x073973751F12DD5EULL, 0x8A8E849EB32781A5ULL,
+ 0xE1925C71285279F5ULL, 0x74C04BF1790C0EFEULL, 0x4DDA48153C94938AULL,
+ 0x9D266D6A1CC0542CULL, 0x7440FB816508C4FEULL, 0x13328503DF48229FULL,
+ 0xD6BF7BAEE43CAC40ULL, 0x4838D65F6EF6748FULL, 0x1E152328F3318DEAULL,
+ 0x8F8419A348F296BFULL, 0x72C8834A5957B511ULL, 0xD7A023A73260B45CULL,
+ 0x94EBC8ABCFB56DAEULL, 0x9FC10D0F989993E0ULL, 0xDE68A2355B93CAE6ULL,
+ 0xA44CFE79AE538BBEULL, 0x9D1D84FCCE371425ULL, 0x51D2B1AB2DDFB636ULL,
+ 0x2FD7E4B9E72CD38CULL, 0x65CA5B96B7552210ULL, 0xDD69A0D8AB3B546DULL,
+ 0x604D51B25FBF70E2ULL, 0x73AA8A564FB7AC9EULL, 0x1A8C1E992B941148ULL,
+ 0xAAC40A2703D9BEA0ULL, 0x764DBEAE7FA4F3A6ULL, 0x1E99B96E70A9BE8BULL,
+ 0x2C5E9DEB57EF4743ULL, 0x3A938FEE32D29981ULL, 0x26E6DB8FFDF5ADFEULL,
+ 0x469356C504EC9F9DULL, 0xC8763C5B08D1908CULL, 0x3F6C6AF859D80055ULL,
+ 0x7F7CC39420A3A545ULL, 0x9BFB227EBDF4C5CEULL, 0x89039D79D6FC5C5CULL,
+ 0x8FE88B57305E2AB6ULL, 0xA09E8C8C35AB96DEULL, 0xFA7E393983325753ULL,
+ 0xD6B6D0ECC617C699ULL, 0xDFEA21EA9E7557E3ULL, 0xB67C1FA481680AF8ULL,
+ 0xCA1E3785A9E724E5ULL, 0x1CFC8BED0D681639ULL, 0xD18D8549D140CAEAULL,
+ 0x4ED0FE7E9DC91335ULL, 0xE4DBF0634473F5D2ULL, 0x1761F93A44D5AEFEULL,
+ 0x53898E4C3910DA55ULL, 0x734DE8181F6EC39AULL, 0x2680B122BAA28D97ULL,
+ 0x298AF231C85BAFABULL, 0x7983EED3740847D5ULL, 0x66C1A2A1A60CD889ULL,
+ 0x9E17E49642A3E4C1ULL, 0xEDB454E7BADC0805ULL, 0x50B704CAB602C329ULL,
+ 0x4CC317FB9CDDD023ULL, 0x66B4835D9EAFEA22ULL, 0x219B97E26FFC81BDULL,
+ 0x261E4E4C0A333A9DULL, 0x1FE2CCA76517DB90ULL, 0xD7504DFA8816EDBBULL,
+ 0xB9571FA04DC089C8ULL, 0x1DDC0325259B27DEULL, 0xCF3F4688801EB9AAULL,
+ 0xF4F5D05C10CAB243ULL, 0x38B6525C21A42B0EULL, 0x36F60E2BA4FA6800ULL,
+ 0xEB3593803173E0CEULL, 0x9C4CD6257C5A3603ULL, 0xAF0C317D32ADAA8AULL,
+ 0x258E5A80C7204C4BULL, 0x8B889D624D44885DULL, 0xF4D14597E660F855ULL,
+ 0xD4347F66EC8941C3ULL, 0xE699ED85B0DFB40DULL, 0x2472F6207C2D0484ULL,
+ 0xC2A1E7B5B459AEB5ULL, 0xAB4F6451CC1D45ECULL, 0x63767572AE3D6174ULL,
+ 0xA59E0BD101731A28ULL, 0x116D0016CB948F09ULL, 0x2CF9C8CA052F6E9FULL,
+ 0x0B090A7560A968E3ULL, 0xABEEDDB2DDE06FF1ULL, 0x58EFC10B06A2068DULL,
+ 0xC6E57A78FBD986E0ULL, 0x2EAB8CA63CE802D7ULL, 0x14A195640116F336ULL,
+ 0x7C0828DD624EC390ULL, 0xD74BBE77E6116AC7ULL, 0x804456AF10F5FB53ULL,
+ 0xEBE9EA2ADF4321C7ULL, 0x03219A39EE587A30ULL, 0x49787FEF17AF9924ULL,
+ 0xA1E9300CD8520548ULL, 0x5B45E522E4B1B4EFULL, 0xB49C3B3995091A36ULL,
+ 0xD4490AD526F14431ULL, 0x12A8F216AF9418C2ULL, 0x001F837CC7350524ULL,
+ 0x1877B51E57A764D5ULL, 0xA2853B80F17F58EEULL, 0x993E1DE72D36D310ULL,
+ 0xB3598080CE64A656ULL, 0x252F59CF0D9F04BBULL, 0xD23C8E176D113600ULL,
+ 0x1BDA0492E7E4586EULL, 0x21E0BD5026C619BFULL, 0x3B097ADAF088F94EULL,
+ 0x8D14DEDB30BE846EULL, 0xF95CFFA23AF5F6F4ULL, 0x3871700761B3F743ULL,
+ 0xCA672B91E9E4FA16ULL, 0x64C8E531BFF53B55ULL, 0x241260ED4AD1E87DULL,
+ 0x106C09B972D2E822ULL, 0x7FBA195410E5CA30ULL, 0x7884D9BC6CB569D8ULL,
+ 0x0647DFEDCD894A29ULL, 0x63573FF03E224774ULL, 0x4FC8E9560F91B123ULL,
+ 0x1DB956E450275779ULL, 0xB8D91274B9E9D4FBULL, 0xA2EBEE47E2FBFCE1ULL,
+ 0xD9F1F30CCD97FB09ULL, 0xEFED53D75FD64E6BULL, 0x2E6D02C36017F67FULL,
+ 0xA9AA4D20DB084E9BULL, 0xB64BE8D8B25396C1ULL, 0x70CB6AF7C2D5BCF0ULL,
+ 0x98F076A4F7A2322EULL, 0xBF84470805E69B5FULL, 0x94C3251F06F90CF3ULL,
+ 0x3E003E616A6591E9ULL, 0xB925A6CD0421AFF3ULL, 0x61BDD1307C66E300ULL,
+ 0xBF8D5108E27E0D48ULL, 0x240AB57A8B888B20ULL, 0xFC87614BAF287E07ULL,
+ 0xEF02CDD06FFDB432ULL, 0xA1082C0466DF6C0AULL, 0x8215E577001332C8ULL,
+ 0xD39BB9C3A48DB6CFULL, 0x2738259634305C14ULL, 0x61CF4F94C97DF93DULL,
+ 0x1B6BACA2AE4E125BULL, 0x758F450C88572E0BULL, 0x959F587D507A8359ULL,
+ 0xB063E962E045F54DULL, 0x60E8ED72C0DFF5D1ULL, 0x7B64978555326F9FULL,
+ 0xFD080D236DA814BAULL, 0x8C90FD9B083F4558ULL, 0x106F72FE81E2C590ULL,
+ 0x7976033A39F7D952ULL, 0xA4EC0132764CA04BULL, 0x733EA705FAE4FA77ULL,
+ 0xB4D8F77BC3E56167ULL, 0x9E21F4F903B33FD9ULL, 0x9D765E419FB69F6DULL,
+ 0xD30C088BA61EA5EFULL, 0x5D94337FBFAF7F5BULL, 0x1A4E4822EB4D7A59ULL,
+ 0x6FFE73E81B637FB3ULL, 0xDDF957BC36D8B9CAULL, 0x64D0E29EEA8838B3ULL,
+ 0x08DD9BDFD96B9F63ULL, 0x087E79E5A57D1D13ULL, 0xE328E230E3E2B3FBULL,
+ 0x1C2559E30F0946BEULL, 0x720BF5F26F4D2EAAULL, 0xB0774D261CC609DBULL,
+ 0x443F64EC5A371195ULL, 0x4112CF68649A260EULL, 0xD813F2FAB7F5C5CAULL,
+ 0x660D3257380841EEULL, 0x59AC2C7873F910A3ULL, 0xE846963877671A17ULL,
+ 0x93B633ABFA3469F8ULL, 0xC0C0F5A60EF4CDCFULL, 0xCAF21ECD4377B28CULL,
+ 0x57277707199B8175ULL, 0x506C11B9D90E8B1DULL, 0xD83CC2687A19255FULL,
+ 0x4A29C6465A314CD1ULL, 0xED2DF21216235097ULL, 0xB5635C95FF7296E2ULL,
+ 0x22AF003AB672E811ULL, 0x52E762596BF68235ULL, 0x9AEBA33AC6ECC6B0ULL,
+ 0x944F6DE09134DFB6ULL, 0x6C47BEC883A7DE39ULL, 0x6AD047C430A12104ULL,
+ 0xA5B1CFDBA0AB4067ULL, 0x7C45D833AFF07862ULL, 0x5092EF950A16DA0BULL,
+ 0x9338E69C052B8E7BULL, 0x455A4B4CFE30E3F5ULL, 0x6B02E63195AD0CF8ULL,
+ 0x6B17B224BAD6BF27ULL, 0xD1E0CCD25BB9C169ULL, 0xDE0C89A556B9AE70ULL,
+ 0x50065E535A213CF6ULL, 0x9C1169FA2777B874ULL, 0x78EDEFD694AF1EEDULL,
+ 0x6DC93D9526A50E68ULL, 0xEE97F453F06791EDULL, 0x32AB0EDB696703D3ULL,
+ 0x3A6853C7E70757A7ULL, 0x31865CED6120F37DULL, 0x67FEF95D92607890ULL,
+ 0x1F2B1D1F15F6DC9CULL, 0xB69E38A8965C6B65ULL, 0xAA9119FF184CCCF4ULL,
+ 0xF43C732873F24C13ULL, 0xFB4A3D794A9A80D2ULL, 0x3550C2321FD6109CULL,
+ 0x371F77E76BB8417EULL, 0x6BFA9AAE5EC05779ULL, 0xCD04F3FF001A4778ULL,
+ 0xE3273522064480CAULL, 0x9F91508BFFCFC14AULL, 0x049A7F41061A9E60ULL,
+ 0xFCB6BE43A9F2FE9BULL, 0x08DE8A1C7797DA9BULL, 0x8F9887E6078735A1ULL,
+ 0xB5B4071DBFC73A66ULL, 0x230E343DFBA08D33ULL, 0x43ED7F5A0FAE657DULL,
+ 0x3A88A0FBBCB05C63ULL, 0x21874B8B4D2DBC4FULL, 0x1BDEA12E35F6A8C9ULL,
+ 0x53C065C6C8E63528ULL, 0xE34A1D250E7A8D6BULL, 0xD6B04D3B7651DD7EULL,
+ 0x5E90277E7CB39E2DULL, 0x2C046F22062DC67DULL, 0xB10BB459132D0A26ULL,
+ 0x3FA9DDFB67E2F199ULL, 0x0E09B88E1914F7AFULL, 0x10E8B35AF3EEAB37ULL,
+ 0x9EEDECA8E272B933ULL, 0xD4C718BC4AE8AE5FULL, 0x81536D601170FC20ULL,
+ 0x91B534F885818A06ULL, 0xEC8177F83F900978ULL, 0x190E714FADA5156EULL,
+ 0xB592BF39B0364963ULL, 0x89C350C893AE7DC1ULL, 0xAC042E70F8B383F2ULL,
+ 0xB49B52E587A1EE60ULL, 0xFB152FE3FF26DA89ULL, 0x3E666E6F69AE2C15ULL,
+ 0x3B544EBE544C19F9ULL, 0xE805A1E290CF2456ULL, 0x24B33C9D7ED25117ULL,
+ 0xE74733427B72F0C1ULL, 0x0A804D18B7097475ULL, 0x57E3306D881EDB4FULL,
+ 0x4AE7D6A36EB5DBCBULL, 0x2D8D5432157064C8ULL, 0xD1E649DE1E7F268BULL,
+ 0x8A328A1CEDFE552CULL, 0x07A3AEC79624C7DAULL, 0x84547DDC3E203C94ULL,
+ 0x990A98FD5071D263ULL, 0x1A4FF12616EEFC89ULL, 0xF6F7FD1431714200ULL,
+ 0x30C05B1BA332F41CULL, 0x8D2636B81555A786ULL, 0x46C9FEB55D120902ULL,
+ 0xCCEC0A73B49C9921ULL, 0x4E9D2827355FC492ULL, 0x19EBB029435DCB0FULL,
+ 0x4659D2B743848A2CULL, 0x963EF2C96B33BE31ULL, 0x74F85198B05A2E7DULL,
+ 0x5A0F544DD2B1FB18ULL, 0x03727073C2E134B1ULL, 0xC7F6AA2DE59AEA61ULL,
+ 0x352787BAA0D7C22FULL, 0x9853EAB63B5E0B35ULL, 0xABBDCDD7ED5C0860ULL,
+ 0xCF05DAF5AC8D77B0ULL, 0x49CAD48CEBF4A71EULL, 0x7A4C10EC2158C4A6ULL,
+ 0xD9E92AA246BF719EULL, 0x13AE978D09FE5557ULL, 0x730499AF921549FFULL,
+ 0x4E4B705B92903BA4ULL, 0xFF577222C14F0A3AULL, 0x55B6344CF97AAFAEULL,
+ 0xB862225B055B6960ULL, 0xCAC09AFBDDD2CDB4ULL, 0xDAF8E9829FE96B5FULL,
+ 0xB5FDFC5D3132C498ULL, 0x310CB380DB6F7503ULL, 0xE87FBB46217A360EULL,
+ 0x2102AE466EBB1148ULL, 0xF8549E1A3AA5E00DULL, 0x07A69AFDCC42261AULL,
+ 0xC4C118BFE78FEAAEULL, 0xF9F4892ED96BD438ULL, 0x1AF3DBE25D8F45DAULL,
+ 0xF5B4B0B0D2DEEEB4ULL, 0x962ACEEFA82E1C84ULL, 0x046E3ECAAF453CE9ULL,
+ 0xF05D129681949A4CULL, 0x964781CE734B3C84ULL, 0x9C2ED44081CE5FBDULL,
+ 0x522E23F3925E319EULL, 0x177E00F9FC32F791ULL, 0x2BC60A63A6F3B3F2ULL,
+ 0x222BBFAE61725606ULL, 0x486289DDCC3D6780ULL, 0x7DC7785B8EFDFC80ULL,
+ 0x8AF38731C02BA980ULL, 0x1FAB64EA29A2DDF7ULL, 0xE4D9429322CD065AULL,
+ 0x9DA058C67844F20CULL, 0x24C0E332B70019B0ULL, 0x233003B5A6CFE6ADULL,
+ 0xD586BD01C5C217F6ULL, 0x5E5637885F29BC2BULL, 0x7EBA726D8C94094BULL,
+ 0x0A56A5F0BFE39272ULL, 0xD79476A84EE20D06ULL, 0x9E4C1269BAA4BF37ULL,
+ 0x17EFEE45B0DEE640ULL, 0x1D95B0A5FCF90BC6ULL, 0x93CBE0B699C2585DULL,
+ 0x65FA4F227A2B6D79ULL, 0xD5F9E858292504D5ULL, 0xC2B5A03F71471A6FULL,
+ 0x59300222B4561E00ULL, 0xCE2F8642CA0712DCULL, 0x7CA9723FBB2E8988ULL,
+ 0x2785338347F2BA08ULL, 0xC61BB3A141E50E8CULL, 0x150F361DAB9DEC26ULL,
+ 0x9F6A419D382595F4ULL, 0x64A53DC924FE7AC9ULL, 0x142DE49FFF7A7C3DULL,
+ 0x0C335248857FA9E7ULL, 0x0A9C32D5EAE45305ULL, 0xE6C42178C4BBB92EULL,
+ 0x71F1CE2490D20B07ULL, 0xF1BCC3D275AFE51AULL, 0xE728E8C83C334074ULL,
+ 0x96FBF83A12884624ULL, 0x81A1549FD6573DA5ULL, 0x5FA7867CAF35E149ULL,
+ 0x56986E2EF3ED091BULL, 0x917F1DD5F8886C61ULL, 0xD20D8C88C8FFE65FULL,
+ 0x31D71DCE64B2C310ULL, 0xF165B587DF898190ULL, 0xA57E6339DD2CF3A0ULL,
+ 0x1EF6E6DBB1961EC9ULL, 0x70CC73D90BC26E24ULL, 0xE21A6B35DF0C3AD7ULL,
+ 0x003A93D8B2806962ULL, 0x1C99DED33CB890A1ULL, 0xCF3145DE0ADD4289ULL,
+ 0xD0E4427A5514FB72ULL, 0x77C621CC9FB3A483ULL, 0x67A34DAC4356550BULL,
+ 0xF8D626AAAF278509ULL
+ };
+
+ // Indices to the Random64[] array
+ const int PieceIdx = 0;
+ const int CastleIdx = 768;
+ const int EnPassantIdx = 772;
+ const int TurnIdx = 780;
+
+ // book_key() builds up a PolyGlot hash key out of a position
+ uint64_t book_key(const Position& pos) {
+
+ // Piece offset is calculated as (64 * PolyPieceType + square), where
+ // PolyPieceType is: BP = 0, WP = 1, BN = 2, WN = 3 .... BK = 10, WK = 11
+ static const int PieceToPoly[] = { 0, 1, 3, 5, 7, 9, 11, 0, 0, 0, 2, 4, 6, 8, 10 };
+
+ uint64_t result = 0;
+ Bitboard b = pos.occupied_squares();
+
+ while (b)
+ {
+ Square s = pop_1st_bit(&b);
+ int p = PieceToPoly[int(pos.piece_on(s))];
+ result ^= Random64[PieceIdx + 64 * p + int(s)];
+ }
+
+ if (pos.can_castle_kingside(WHITE))
+ result ^= Random64[CastleIdx + 0];
+
+ if (pos.can_castle_queenside(WHITE))
+ result ^= Random64[CastleIdx + 1];
+
+ if (pos.can_castle_kingside(BLACK))
+ result ^= Random64[CastleIdx + 2];
+
+ if (pos.can_castle_queenside(BLACK))
+ result ^= Random64[CastleIdx + 3];
+
+ if (pos.ep_square() != SQ_NONE)
+ result ^= Random64[EnPassantIdx + square_file(pos.ep_square())];
+
+ if (pos.side_to_move() == WHITE)
+ result ^= Random64[TurnIdx];
+
+ return result;
+ }
+
+}
+
+
+/// Book c'tor. Make random number generation less deterministic, for book moves
+Book::Book() {
+
+ for (int i = abs(get_system_time() % 10000); i > 0; i--)
+ RKiss.rand();
+}
+
+
+/// Book destructor. Be sure file is closed before we leave.
+
+Book::~Book() {
+
+ close();
+}
+
+
+/// Book::close() closes the file only if it is open, otherwise
+/// we can end up in a little mess due to how std::ifstream works.
+
+void Book::close() {
+
+ if (bookFile.is_open())
+ bookFile.close();
+
+ bookName = "";
+}
+
+
+/// Book::open() opens a book file with a given file name
+
+void Book::open(const string& fileName) {
+
+ // Close old file before opening the new
+ close();
+
+ bookFile.open(fileName.c_str(), ifstream::in | ifstream::binary);
+
+ // Silently return when asked to open a non-exsistent file
+ if (!bookFile.is_open())
+ return;
+
+ // Get the book size in number of entries
+ bookFile.seekg(0, ios::end);
+ bookSize = long(bookFile.tellg()) / sizeof(BookEntry);
+
+ if (!bookFile.good())
+ {
+ cerr << "Failed to open book file " << fileName << endl;
+ exit(EXIT_FAILURE);
+ }
+
+ // Set only if successful
+ bookName = fileName;
+}
+
+
+/// Book::get_move() gets a book move for a given position. Returns
+/// MOVE_NONE if no book move is found. If findBestMove is true then
+/// return always the highest rated book move.
+
+Move Book::get_move(const Position& pos, bool findBestMove) {
+
+ if (!bookFile.is_open() || bookSize == 0)
+ return MOVE_NONE;
+
+ BookEntry entry;
+ int bookMove = MOVE_NONE;
+ unsigned score, scoresSum = 0, bestScore = 0;
+ uint64_t key = book_key(pos);
+
+ // Choose a book move among the possible moves for the given position
+ for (int idx = find_entry(key); idx < bookSize; idx++)
+ {
+ entry = read_entry(idx);
+
+ if (entry.key != key)
+ break;
+
+ score = entry.count;
+
+ if (!findBestMove)
+ {
+ // Choose book move according to its score. If a move has a very
+ // high score it has more probability to be choosen then a one with
+ // lower score. Note that first entry is always chosen.
+ scoresSum += score;
+ if (RKiss.rand() % scoresSum < score)
+ bookMove = entry.move;
+ }
+ else if (score > bestScore)
+ {
+ bestScore = score;
+ bookMove = entry.move;
+ }
+ }
+
+ // A PolyGlot book move is encoded as follows:
+ //
+ // bit 0- 5: destination square (from 0 to 63)
+ // bit 6-11: origin square (from 0 to 63)
+ // bit 12-13-14: promotion piece (from KNIGHT == 1 to QUEEN == 4)
+ //
+ // Castling moves follow "king captures rook" representation. So in case
+ // book move is a promotion we have to convert to our representation, in
+ // all other cases we can directly compare with a Move after having
+ // masked out special Move's flags that are not supported by PolyGlot.
+ int p = (bookMove >> 12) & 7;
+
+ if (p)
+ bookMove = int(make_promotion_move(move_from(Move(bookMove)),
+ move_to(Move(bookMove)), PieceType(p + 1)));
+
+ // Verify the book move (if any) is legal
+ MoveStack mlist[MAX_MOVES];
+ MoveStack* last = generate(pos, mlist);
+ for (MoveStack* cur = mlist; cur != last; cur++)
+ if ((int(cur->move) & ~(3 << 14)) == bookMove) // Mask out special flags
+ return cur->move;
+
+ return MOVE_NONE;
+}
+
+
+/// Book::find_entry() takes a book key as input, and does a binary search
+/// through the book file for the given key. The index to the first book
+/// entry with the same key as the input is returned. When the key is not
+/// found in the book file, bookSize is returned.
+
+int Book::find_entry(uint64_t key) {
+
+ int left, right, mid;
+
+ // Binary search (finds the leftmost entry)
+ left = 0;
+ right = bookSize - 1;
+
+ assert(left <= right);
+
+ while (left < right)
+ {
+ mid = (left + right) / 2;
+
+ assert(mid >= left && mid < right);
+
+ if (key <= read_entry(mid).key)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+
+ assert(left == right);
+
+ return read_entry(left).key == key ? left : bookSize;
+}
+
+
+/// Book::read_entry() takes an integer index, and returns the BookEntry
+/// at the given index in the book file.
+
+BookEntry Book::read_entry(int idx) {
+
+ assert(idx >= 0 && idx < bookSize);
+ assert(bookFile.is_open());
+
+ BookEntry e;
+
+ bookFile.seekg(idx * sizeof(BookEntry), ios_base::beg);
+
+ *this >> e.key >> e.move >> e.count >> e.learn;
+
+ if (!bookFile.good())
+ {
+ cerr << "Failed to read book entry at index " << idx << endl;
+ exit(EXIT_FAILURE);
+ }
+ return e;
+}
diff --git a/DroidFish/jni/stockfish/book.h b/DroidFish/jni/stockfish/book.h
new file mode 100644
index 0000000..ed68210
--- /dev/null
+++ b/DroidFish/jni/stockfish/book.h
@@ -0,0 +1,71 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#if !defined(BOOK_H_INCLUDED)
+#define BOOK_H_INCLUDED
+
+#include
+#include
+
+#include "move.h"
+#include "position.h"
+#include "rkiss.h"
+
+
+// A Polyglot book is a series of "entries" of 16 bytes. All integers are
+// stored highest byte first (regardless of size). The entries are ordered
+// according to key. Lowest key first.
+struct BookEntry {
+ uint64_t key;
+ uint16_t move;
+ uint16_t count;
+ uint32_t learn;
+};
+
+class Book {
+public:
+ Book();
+ ~Book();
+ void open(const std::string& fileName);
+ void close();
+ Move get_move(const Position& pos, bool findBestMove);
+ const std::string name() const { return bookName; }
+
+private:
+ // read n chars from the file stream and converts them in an
+ // integer number. Integers are stored with highest byte first.
+ template uint64_t get_int();
+
+ template
+ Book& operator>>(T& n) { n = (T)get_int(); return *this; }
+
+ BookEntry read_entry(int idx);
+ int find_entry(uint64_t key);
+
+ std::ifstream bookFile;
+ std::string bookName;
+ int bookSize;
+ RKISS RKiss;
+};
+
+// Yes, we indulge a bit here ;-)
+template inline uint64_t Book::get_int() { return 256 * get_int() + bookFile.get(); }
+template<> inline uint64_t Book::get_int<1>() { return bookFile.get(); }
+
+#endif // !defined(BOOK_H_INCLUDED)
diff --git a/DroidFish/jni/stockfish/endgame.cpp b/DroidFish/jni/stockfish/endgame.cpp
new file mode 100644
index 0000000..c8c491f
--- /dev/null
+++ b/DroidFish/jni/stockfish/endgame.cpp
@@ -0,0 +1,939 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+
+#include "bitcount.h"
+#include "endgame.h"
+#include "pawns.h"
+
+using std::string;
+
+extern uint32_t probe_kpk_bitbase(Square wksq, Square wpsq, Square bksq, Color stm);
+
+namespace {
+
+ // Table used to drive the defending king towards the edge of the board
+ // in KX vs K and KQ vs KR endgames.
+ const int MateTable[64] = {
+ 100, 90, 80, 70, 70, 80, 90, 100,
+ 90, 70, 60, 50, 50, 60, 70, 90,
+ 80, 60, 40, 30, 30, 40, 60, 80,
+ 70, 50, 30, 20, 20, 30, 50, 70,
+ 70, 50, 30, 20, 20, 30, 50, 70,
+ 80, 60, 40, 30, 30, 40, 60, 80,
+ 90, 70, 60, 50, 50, 60, 70, 90,
+ 100, 90, 80, 70, 70, 80, 90, 100,
+ };
+
+ // Table used to drive the defending king towards a corner square of the
+ // right color in KBN vs K endgames.
+ const int KBNKMateTable[64] = {
+ 200, 190, 180, 170, 160, 150, 140, 130,
+ 190, 180, 170, 160, 150, 140, 130, 140,
+ 180, 170, 155, 140, 140, 125, 140, 150,
+ 170, 160, 140, 120, 110, 140, 150, 160,
+ 160, 150, 140, 110, 120, 140, 160, 170,
+ 150, 140, 125, 140, 140, 155, 170, 180,
+ 140, 130, 140, 150, 160, 170, 180, 190,
+ 130, 140, 150, 160, 170, 180, 190, 200
+ };
+
+ // The attacking side is given a descending bonus based on distance between
+ // the two kings in basic endgames.
+ const int DistanceBonus[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
+
+ // Penalty for big distance between king and knight for the defending king
+ // and knight in KR vs KN endgames.
+ const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
+
+ // Build corresponding key code for the opposite color: "KBPKN" -> "KNKBP"
+ const string swap_colors(const string& keyCode) {
+
+ size_t idx = keyCode.find('K', 1);
+ return keyCode.substr(idx) + keyCode.substr(0, idx);
+ }
+
+ // Get the material key of a position out of the given endgame key code
+ // like "KBPKN". The trick here is to first build up a FEN string and then
+ // let a Position object to do the work for us. Note that the FEN string
+ // could correspond to an illegal position.
+ Key mat_key(const string& keyCode) {
+
+ assert(keyCode.length() > 0 && keyCode.length() < 8);
+ assert(keyCode[0] == 'K');
+
+ string fen;
+ size_t i = 0;
+
+ // First add white and then black pieces
+ do fen += keyCode[i]; while (keyCode[++i] != 'K');
+ do fen += char(tolower(keyCode[i])); while (++i < keyCode.length());
+
+ // Add file padding and remaining empty ranks
+ fen += string(1, '0' + int(8 - keyCode.length())) + "/8/8/8/8/8/8/8 w - -";
+
+ // Build a Position out of the fen string and get its material key
+ return Position(fen, false, 0).get_material_key();
+ }
+
+ typedef EndgameBase EF;
+ typedef EndgameBase SF;
+
+} // namespace
+
+
+/// Endgames member definitions
+
+template<> const Endgames::EFMap& Endgames::get() const { return maps.first; }
+template<> const Endgames::SFMap& Endgames::get() const { return maps.second; }
+
+Endgames::Endgames() {
+
+ add >("KNNK");
+ add >("KPK");
+ add >("KBNK");
+ add >("KRKP");
+ add >("KRKB");
+ add >("KRKN");
+ add >("KQKR");
+ add >("KBBKN");
+
+ add >("KNPK");
+ add >("KRPKR");
+ add >("KBPKB");
+ add >("KBPPKB");
+ add >("KBPKN");
+ add >("KRPPKRP");
+}
+
+Endgames::~Endgames() {
+
+ for (EFMap::const_iterator it = get().begin(); it != get().end(); ++it)
+ delete it->second;
+
+ for (SFMap::const_iterator it = get().begin(); it != get().end(); ++it)
+ delete it->second;
+}
+
+template
+void Endgames::add(const string& keyCode) {
+
+ typedef typename T::Base F;
+ typedef std::map M;
+
+ const_cast(get()).insert(std::pair(mat_key(keyCode), new T(WHITE)));
+ const_cast(get()).insert(std::pair(mat_key(swap_colors(keyCode)), new T(BLACK)));
+}
+
+template
+T* Endgames::get(Key key) const {
+
+ typename std::map::const_iterator it = get().find(key);
+ return it != get().end() ? it->second : NULL;
+}
+
+// Explicit template instantiations
+template EF* Endgames::get(Key key) const;
+template SF* Endgames::get(Key key) const;
+
+
+/// Mate with KX vs K. This function is used to evaluate positions with
+/// King and plenty of material vs a lone king. It simply gives the
+/// attacking side a bonus for driving the defending king towards the edge
+/// of the board, and for keeping the distance between the two kings small.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO);
+
+ Square winnerKSq = pos.king_square(strongerSide);
+ Square loserKSq = pos.king_square(weakerSide);
+
+ Value result = pos.non_pawn_material(strongerSide)
+ + pos.piece_count(strongerSide, PAWN) * PawnValueEndgame
+ + MateTable[loserKSq]
+ + DistanceBonus[square_distance(winnerKSq, loserKSq)];
+
+ if ( pos.piece_count(strongerSide, QUEEN)
+ || pos.piece_count(strongerSide, ROOK)
+ || pos.piece_count(strongerSide, BISHOP) > 1)
+ // TODO: check for two equal-colored bishops!
+ result += VALUE_KNOWN_WIN;
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
+/// defending king towards a corner square of the right color.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO);
+ assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame + BishopValueMidgame);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, KNIGHT) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+
+ Square winnerKSq = pos.king_square(strongerSide);
+ Square loserKSq = pos.king_square(weakerSide);
+ Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
+
+ // kbnk_mate_table() tries to drive toward corners A1 or H8,
+ // if we have a bishop that cannot reach the above squares we
+ // mirror the kings so to drive enemy toward corners A8 or H1.
+ if (opposite_color_squares(bishopSquare, SQ_A1))
+ {
+ winnerKSq = flop_square(winnerKSq);
+ loserKSq = flop_square(loserKSq);
+ }
+
+ Value result = VALUE_KNOWN_WIN
+ + DistanceBonus[square_distance(winnerKSq, loserKSq)]
+ + KBNKMateTable[loserKSq];
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// KP vs K. This endgame is evaluated with the help of a bitbase.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO);
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(strongerSide, PAWN) == 1);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square wksq, bksq, wpsq;
+ Color stm;
+
+ if (strongerSide == WHITE)
+ {
+ wksq = pos.king_square(WHITE);
+ bksq = pos.king_square(BLACK);
+ wpsq = pos.piece_list(WHITE, PAWN, 0);
+ stm = pos.side_to_move();
+ }
+ else
+ {
+ wksq = flip_square(pos.king_square(BLACK));
+ bksq = flip_square(pos.king_square(WHITE));
+ wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
+ stm = opposite_color(pos.side_to_move());
+ }
+
+ if (square_file(wpsq) >= FILE_E)
+ {
+ wksq = flop_square(wksq);
+ bksq = flop_square(bksq);
+ wpsq = flop_square(wpsq);
+ }
+
+ if (!probe_kpk_bitbase(wksq, wpsq, bksq, stm))
+ return VALUE_DRAW;
+
+ Value result = VALUE_KNOWN_WIN
+ + PawnValueEndgame
+ + Value(square_rank(wpsq));
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
+/// a bitbase. The function below returns drawish scores when the pawn is
+/// far advanced with support of the king, while the attacking king is far
+/// away.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.non_pawn_material(weakerSide) == 0);
+ assert(pos.piece_count(weakerSide, PAWN) == 1);
+
+ Square wksq, wrsq, bksq, bpsq;
+ int tempo = (pos.side_to_move() == strongerSide);
+
+ wksq = pos.king_square(strongerSide);
+ wrsq = pos.piece_list(strongerSide, ROOK, 0);
+ bksq = pos.king_square(weakerSide);
+ bpsq = pos.piece_list(weakerSide, PAWN, 0);
+
+ if (strongerSide == BLACK)
+ {
+ wksq = flip_square(wksq);
+ wrsq = flip_square(wrsq);
+ bksq = flip_square(bksq);
+ bpsq = flip_square(bpsq);
+ }
+
+ Square queeningSq = make_square(square_file(bpsq), RANK_1);
+ Value result;
+
+ // If the stronger side's king is in front of the pawn, it's a win
+ if (wksq < bpsq && square_file(wksq) == square_file(bpsq))
+ result = RookValueEndgame - Value(square_distance(wksq, bpsq));
+
+ // If the weaker side's king is too far from the pawn and the rook,
+ // it's a win
+ else if ( square_distance(bksq, bpsq) - (tempo ^ 1) >= 3
+ && square_distance(bksq, wrsq) >= 3)
+ result = RookValueEndgame - Value(square_distance(wksq, bpsq));
+
+ // If the pawn is far advanced and supported by the defending king,
+ // the position is drawish
+ else if ( square_rank(bksq) <= RANK_3
+ && square_distance(bksq, bpsq) == 1
+ && square_rank(wksq) >= RANK_4
+ && square_distance(wksq, bpsq) - tempo > 2)
+ result = Value(80 - square_distance(wksq, bpsq) * 8);
+
+ else
+ result = Value(200)
+ - Value(square_distance(wksq, bpsq + DELTA_S) * 8)
+ + Value(square_distance(bksq, bpsq + DELTA_S) * 8)
+ + Value(square_distance(bpsq, queeningSq) * 8);
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// KR vs KB. This is very simple, and always returns drawish scores. The
+/// score is slightly bigger when the defending king is close to the edge.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+ assert(pos.piece_count(weakerSide, BISHOP) == 1);
+
+ Value result = Value(MateTable[pos.king_square(weakerSide)]);
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// KR vs KN. The attacking side has slightly better winning chances than
+/// in KR vs KB, particularly if the king and the knight are far apart.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+ assert(pos.piece_count(weakerSide, KNIGHT) == 1);
+
+ Square defendingKSq = pos.king_square(weakerSide);
+ Square nSq = pos.piece_list(weakerSide, KNIGHT, 0);
+
+ int d = square_distance(defendingKSq, nSq);
+ Value result = Value(10)
+ + MateTable[defendingKSq]
+ + KRKNKingKnightDistancePenalty[d];
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// KQ vs KR. This is almost identical to KX vs K: We give the attacking
+/// king a bonus for having the kings close together, and for forcing the
+/// defending king towards the edge. If we also take care to avoid null move
+/// for the defending side in the search, this is usually sufficient to be
+/// able to win KQ vs KR.
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square winnerKSq = pos.king_square(strongerSide);
+ Square loserKSq = pos.king_square(weakerSide);
+
+ Value result = QueenValueEndgame
+ - RookValueEndgame
+ + MateTable[loserKSq]
+ + DistanceBonus[square_distance(winnerKSq, loserKSq)];
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+template<>
+Value Endgame::apply(const Position& pos) const {
+
+ assert(pos.piece_count(strongerSide, BISHOP) == 2);
+ assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
+ assert(pos.piece_count(weakerSide, KNIGHT) == 1);
+ assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
+ assert(pos.pieces(PAWN) == EmptyBoardBB);
+
+ Value result = BishopValueEndgame;
+ Square wksq = pos.king_square(strongerSide);
+ Square bksq = pos.king_square(weakerSide);
+ Square nsq = pos.piece_list(weakerSide, KNIGHT, 0);
+
+ // Bonus for attacking king close to defending king
+ result += Value(DistanceBonus[square_distance(wksq, bksq)]);
+
+ // Bonus for driving the defending king and knight apart
+ result += Value(square_distance(bksq, nsq) * 32);
+
+ // Bonus for restricting the knight's mobility
+ result += Value((8 - count_1s(pos.attacks_from(nsq))) * 8);
+
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
+/// K and two minors vs K and one or two minors or K and two knights against
+/// king alone are always draw.
+template<>
+Value Endgame::apply(const Position&) const {
+ return VALUE_DRAW;
+}
+
+template<>
+Value Endgame::apply(const Position&) const {
+ return VALUE_DRAW;
+}
+
+/// KBPKScalingFunction scales endgames where the stronger side has king,
+/// bishop and one or more pawns. It checks for draws with rook pawns and a
+/// bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_ZERO is
+/// returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
+/// will be used.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) >= 1);
+
+ // No assertions about the material of weakerSide, because we want draws to
+ // be detected even when the weaker side has some pawns.
+
+ Bitboard pawns = pos.pieces(PAWN, strongerSide);
+ File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
+
+ // All pawns are on a single rook file ?
+ if ( (pawnFile == FILE_A || pawnFile == FILE_H)
+ && (pawns & ~file_bb(pawnFile)) == EmptyBoardBB)
+ {
+ Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
+ Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8));
+ Square kingSq = pos.king_square(weakerSide);
+
+ if ( opposite_color_squares(queeningSq, bishopSq)
+ && abs(square_file(kingSq) - pawnFile) <= 1)
+ {
+ // The bishop has the wrong color, and the defending king is on the
+ // file of the pawn(s) or the neighboring file. Find the rank of the
+ // frontmost pawn.
+ Rank rank;
+ if (strongerSide == WHITE)
+ {
+ for (rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--) {}
+ assert(rank >= RANK_2 && rank <= RANK_7);
+ }
+ else
+ {
+ for (rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++) {}
+ rank = Rank(rank ^ 7); // HACK to get the relative rank
+ assert(rank >= RANK_2 && rank <= RANK_7);
+ }
+ // If the defending king has distance 1 to the promotion square or
+ // is placed somewhere in front of the pawn, it's a draw.
+ if ( square_distance(kingSq, queeningSq) <= 1
+ || relative_rank(strongerSide, kingSq) >= rank)
+ return SCALE_FACTOR_ZERO;
+ }
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KQKRPScalingFunction scales endgames where the stronger side has only
+/// king and queen, while the weaker side has at least a rook and a pawn.
+/// It tests for fortress draws with a rook on the third rank defended by
+/// a pawn.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
+ assert(pos.piece_count(strongerSide, QUEEN) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.piece_count(weakerSide, ROOK) == 1);
+ assert(pos.piece_count(weakerSide, PAWN) >= 1);
+
+ Square kingSq = pos.king_square(weakerSide);
+ if ( relative_rank(weakerSide, kingSq) <= RANK_2
+ && relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4
+ && (pos.pieces(ROOK, weakerSide) & rank_bb(relative_rank(weakerSide, RANK_3)))
+ && (pos.pieces(PAWN, weakerSide) & rank_bb(relative_rank(weakerSide, RANK_2)))
+ && (pos.attacks_from(kingSq) & pos.pieces(PAWN, weakerSide)))
+ {
+ Square rsq = pos.piece_list(weakerSide, ROOK, 0);
+ if (pos.attacks_from(rsq, strongerSide) & pos.pieces(PAWN, weakerSide))
+ return SCALE_FACTOR_ZERO;
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KRPKRScalingFunction scales KRP vs KR endgames. This function knows a
+/// handful of the most important classes of drawn positions, but is far
+/// from perfect. It would probably be a good idea to add more knowledge
+/// in the future.
+///
+/// It would also be nice to rewrite the actual code for this function,
+/// which is mostly copied from Glaurung 1.x, and not very pretty.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 1);
+ assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square wksq = pos.king_square(strongerSide);
+ Square wrsq = pos.piece_list(strongerSide, ROOK, 0);
+ Square wpsq = pos.piece_list(strongerSide, PAWN, 0);
+ Square bksq = pos.king_square(weakerSide);
+ Square brsq = pos.piece_list(weakerSide, ROOK, 0);
+
+ // Orient the board in such a way that the stronger side is white, and the
+ // pawn is on the left half of the board.
+ if (strongerSide == BLACK)
+ {
+ wksq = flip_square(wksq);
+ wrsq = flip_square(wrsq);
+ wpsq = flip_square(wpsq);
+ bksq = flip_square(bksq);
+ brsq = flip_square(brsq);
+ }
+ if (square_file(wpsq) > FILE_D)
+ {
+ wksq = flop_square(wksq);
+ wrsq = flop_square(wrsq);
+ wpsq = flop_square(wpsq);
+ bksq = flop_square(bksq);
+ brsq = flop_square(brsq);
+ }
+
+ File f = square_file(wpsq);
+ Rank r = square_rank(wpsq);
+ Square queeningSq = make_square(f, RANK_8);
+ int tempo = (pos.side_to_move() == strongerSide);
+
+ // If the pawn is not too far advanced and the defending king defends the
+ // queening square, use the third-rank defence.
+ if ( r <= RANK_5
+ && square_distance(bksq, queeningSq) <= 1
+ && wksq <= SQ_H5
+ && (square_rank(brsq) == RANK_6 || (r <= RANK_3 && square_rank(wrsq) != RANK_6)))
+ return SCALE_FACTOR_ZERO;
+
+ // The defending side saves a draw by checking from behind in case the pawn
+ // has advanced to the 6th rank with the king behind.
+ if ( r == RANK_6
+ && square_distance(bksq, queeningSq) <= 1
+ && square_rank(wksq) + tempo <= RANK_6
+ && (square_rank(brsq) == RANK_1 || (!tempo && abs(square_file(brsq) - f) >= 3)))
+ return SCALE_FACTOR_ZERO;
+
+ if ( r >= RANK_6
+ && bksq == queeningSq
+ && square_rank(brsq) == RANK_1
+ && (!tempo || square_distance(wksq, wpsq) >= 2))
+ return SCALE_FACTOR_ZERO;
+
+ // White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
+ // and the black rook is behind the pawn.
+ if ( wpsq == SQ_A7
+ && wrsq == SQ_A8
+ && (bksq == SQ_H7 || bksq == SQ_G7)
+ && square_file(brsq) == FILE_A
+ && (square_rank(brsq) <= RANK_3 || square_file(wksq) >= FILE_D || square_rank(wksq) <= RANK_5))
+ return SCALE_FACTOR_ZERO;
+
+ // If the defending king blocks the pawn and the attacking king is too far
+ // away, it's a draw.
+ if ( r <= RANK_5
+ && bksq == wpsq + DELTA_N
+ && square_distance(wksq, wpsq) - tempo >= 2
+ && square_distance(wksq, brsq) - tempo >= 2)
+ return SCALE_FACTOR_ZERO;
+
+ // Pawn on the 7th rank supported by the rook from behind usually wins if the
+ // attacking king is closer to the queening square than the defending king,
+ // and the defending king cannot gain tempi by threatening the attacking rook.
+ if ( r == RANK_7
+ && f != FILE_A
+ && square_file(wrsq) == f
+ && wrsq != queeningSq
+ && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
+ && (square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo))
+ return ScaleFactor(SCALE_FACTOR_MAX - 2 * square_distance(wksq, queeningSq));
+
+ // Similar to the above, but with the pawn further back
+ if ( f != FILE_A
+ && square_file(wrsq) == f
+ && wrsq < wpsq
+ && (square_distance(wksq, queeningSq) < square_distance(bksq, queeningSq) - 2 + tempo)
+ && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wpsq + DELTA_N) - 2 + tempo)
+ && ( square_distance(bksq, wrsq) + tempo >= 3
+ || ( square_distance(wksq, queeningSq) < square_distance(bksq, wrsq) + tempo
+ && (square_distance(wksq, wpsq + DELTA_N) < square_distance(bksq, wrsq) + tempo))))
+ return ScaleFactor( SCALE_FACTOR_MAX
+ - 8 * square_distance(wpsq, queeningSq)
+ - 2 * square_distance(wksq, queeningSq));
+
+ // If the pawn is not far advanced, and the defending king is somewhere in
+ // the pawn's path, it's probably a draw.
+ if (r <= RANK_4 && bksq > wpsq)
+ {
+ if (square_file(bksq) == square_file(wpsq))
+ return ScaleFactor(10);
+ if ( abs(square_file(bksq) - square_file(wpsq)) == 1
+ && square_distance(wksq, bksq) > 2)
+ return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KRPPKRPScalingFunction scales KRPP vs KRP endgames. There is only a
+/// single pattern: If the stronger side has no pawns and the defending king
+/// is actively placed, the position is drawish.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == RookValueMidgame);
+ assert(pos.piece_count(strongerSide, PAWN) == 2);
+ assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
+ assert(pos.piece_count(weakerSide, PAWN) == 1);
+
+ Square wpsq1 = pos.piece_list(strongerSide, PAWN, 0);
+ Square wpsq2 = pos.piece_list(strongerSide, PAWN, 1);
+ Square bksq = pos.king_square(weakerSide);
+
+ // Does the stronger side have a passed pawn?
+ if ( pos.pawn_is_passed(strongerSide, wpsq1)
+ || pos.pawn_is_passed(strongerSide, wpsq2))
+ return SCALE_FACTOR_NONE;
+
+ Rank r = Max(relative_rank(strongerSide, wpsq1), relative_rank(strongerSide, wpsq2));
+
+ if ( file_distance(bksq, wpsq1) <= 1
+ && file_distance(bksq, wpsq2) <= 1
+ && relative_rank(strongerSide, bksq) > r)
+ {
+ switch (r) {
+ case RANK_2: return ScaleFactor(10);
+ case RANK_3: return ScaleFactor(10);
+ case RANK_4: return ScaleFactor(15);
+ case RANK_5: return ScaleFactor(20);
+ case RANK_6: return ScaleFactor(40);
+ default: assert(false);
+ }
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KPsKScalingFunction scales endgames with king and two or more pawns
+/// against king. There is just a single rule here: If all pawns are on
+/// the same rook file and are blocked by the defending king, it's a draw.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO);
+ assert(pos.piece_count(strongerSide, PAWN) >= 2);
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square ksq = pos.king_square(weakerSide);
+ Bitboard pawns = pos.pieces(PAWN, strongerSide);
+
+ // Are all pawns on the 'a' file?
+ if ((pawns & ~FileABB) == EmptyBoardBB)
+ {
+ // Does the defending king block the pawns?
+ if ( square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1
+ || ( square_file(ksq) == FILE_A
+ && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB))
+ return SCALE_FACTOR_ZERO;
+ }
+ // Are all pawns on the 'h' file?
+ else if ((pawns & ~FileHBB) == EmptyBoardBB)
+ {
+ // Does the defending king block the pawns?
+ if ( square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1
+ || ( square_file(ksq) == FILE_H
+ && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB))
+ return SCALE_FACTOR_ZERO;
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KBPKBScalingFunction scales KBP vs KB endgames. There are two rules:
+/// If the defending king is somewhere along the path of the pawn, and the
+/// square of the king is not of the same color as the stronger side's bishop,
+/// it's a draw. If the two bishops have opposite color, it's almost always
+/// a draw.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 1);
+ assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
+ assert(pos.piece_count(weakerSide, BISHOP) == 1);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
+ Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
+ Square weakerBishopSq = pos.piece_list(weakerSide, BISHOP, 0);
+ Square weakerKingSq = pos.king_square(weakerSide);
+
+ // Case 1: Defending king blocks the pawn, and cannot be driven away
+ if ( square_file(weakerKingSq) == square_file(pawnSq)
+ && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
+ && ( opposite_color_squares(weakerKingSq, strongerBishopSq)
+ || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
+ return SCALE_FACTOR_ZERO;
+
+ // Case 2: Opposite colored bishops
+ if (opposite_color_squares(strongerBishopSq, weakerBishopSq))
+ {
+ // We assume that the position is drawn in the following three situations:
+ //
+ // a. The pawn is on rank 5 or further back.
+ // b. The defending king is somewhere in the pawn's path.
+ // c. The defending bishop attacks some square along the pawn's path,
+ // and is at least three squares away from the pawn.
+ //
+ // These rules are probably not perfect, but in practice they work
+ // reasonably well.
+
+ if (relative_rank(strongerSide, pawnSq) <= RANK_5)
+ return SCALE_FACTOR_ZERO;
+ else
+ {
+ Bitboard path = squares_in_front_of(strongerSide, pawnSq);
+
+ if (path & pos.pieces(KING, weakerSide))
+ return SCALE_FACTOR_ZERO;
+
+ if ( (pos.attacks_from(weakerBishopSq) & path)
+ && square_distance(weakerBishopSq, pawnSq) >= 3)
+ return SCALE_FACTOR_ZERO;
+ }
+ }
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KBPPKBScalingFunction scales KBPP vs KB endgames. It detects a few basic
+/// draws with opposite-colored bishops.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 2);
+ assert(pos.non_pawn_material(weakerSide) == BishopValueMidgame);
+ assert(pos.piece_count(weakerSide, BISHOP) == 1);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square wbsq = pos.piece_list(strongerSide, BISHOP, 0);
+ Square bbsq = pos.piece_list(weakerSide, BISHOP, 0);
+
+ if (!opposite_color_squares(wbsq, bbsq))
+ return SCALE_FACTOR_NONE;
+
+ Square ksq = pos.king_square(weakerSide);
+ Square psq1 = pos.piece_list(strongerSide, PAWN, 0);
+ Square psq2 = pos.piece_list(strongerSide, PAWN, 1);
+ Rank r1 = square_rank(psq1);
+ Rank r2 = square_rank(psq2);
+ Square blockSq1, blockSq2;
+
+ if (relative_rank(strongerSide, psq1) > relative_rank(strongerSide, psq2))
+ {
+ blockSq1 = psq1 + pawn_push(strongerSide);
+ blockSq2 = make_square(square_file(psq2), square_rank(psq1));
+ }
+ else
+ {
+ blockSq1 = psq2 + pawn_push(strongerSide);
+ blockSq2 = make_square(square_file(psq1), square_rank(psq2));
+ }
+
+ switch (file_distance(psq1, psq2))
+ {
+ case 0:
+ // Both pawns are on the same file. Easy draw if defender firmly controls
+ // some square in the frontmost pawn's path.
+ if ( square_file(ksq) == square_file(blockSq1)
+ && relative_rank(strongerSide, ksq) >= relative_rank(strongerSide, blockSq1)
+ && opposite_color_squares(ksq, wbsq))
+ return SCALE_FACTOR_ZERO;
+ else
+ return SCALE_FACTOR_NONE;
+
+ case 1:
+ // Pawns on neighboring files. Draw if defender firmly controls the square
+ // in front of the frontmost pawn's path, and the square diagonally behind
+ // this square on the file of the other pawn.
+ if ( ksq == blockSq1
+ && opposite_color_squares(ksq, wbsq)
+ && ( bbsq == blockSq2
+ || (pos.attacks_from(blockSq2) & pos.pieces(BISHOP, weakerSide))
+ || abs(r1 - r2) >= 2))
+ return SCALE_FACTOR_ZERO;
+
+ else if ( ksq == blockSq2
+ && opposite_color_squares(ksq, wbsq)
+ && ( bbsq == blockSq1
+ || (pos.attacks_from(blockSq1) & pos.pieces(BISHOP, weakerSide))))
+ return SCALE_FACTOR_ZERO;
+ else
+ return SCALE_FACTOR_NONE;
+
+ default:
+ // The pawns are not on the same file or adjacent files. No scaling.
+ return SCALE_FACTOR_NONE;
+ }
+}
+
+
+/// KBPKNScalingFunction scales KBP vs KN endgames. There is a single rule:
+/// If the defending king is somewhere along the path of the pawn, and the
+/// square of the king is not of the same color as the stronger side's bishop,
+/// it's a draw.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 1);
+ assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
+ assert(pos.piece_count(weakerSide, KNIGHT) == 1);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
+ Square strongerBishopSq = pos.piece_list(strongerSide, BISHOP, 0);
+ Square weakerKingSq = pos.king_square(weakerSide);
+
+ if ( square_file(weakerKingSq) == square_file(pawnSq)
+ && relative_rank(strongerSide, pawnSq) < relative_rank(strongerSide, weakerKingSq)
+ && ( opposite_color_squares(weakerKingSq, strongerBishopSq)
+ || relative_rank(strongerSide, weakerKingSq) <= RANK_6))
+ return SCALE_FACTOR_ZERO;
+
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KNPKScalingFunction scales KNP vs K endgames. There is a single rule:
+/// If the pawn is a rook pawn on the 7th rank and the defending king prevents
+/// the pawn from advancing, the position is drawn.
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame);
+ assert(pos.piece_count(strongerSide, KNIGHT) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) == 1);
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(weakerSide, PAWN) == 0);
+
+ Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
+ Square weakerKingSq = pos.king_square(weakerSide);
+
+ if ( pawnSq == relative_square(strongerSide, SQ_A7)
+ && square_distance(weakerKingSq, relative_square(strongerSide, SQ_A8)) <= 1)
+ return SCALE_FACTOR_ZERO;
+
+ if ( pawnSq == relative_square(strongerSide, SQ_H7)
+ && square_distance(weakerKingSq, relative_square(strongerSide, SQ_H8)) <= 1)
+ return SCALE_FACTOR_ZERO;
+
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KPKPScalingFunction scales KP vs KP endgames. This is done by removing
+/// the weakest side's pawn and probing the KP vs K bitbase: If the weakest
+/// side has a draw without the pawn, she probably has at least a draw with
+/// the pawn as well. The exception is when the stronger side's pawn is far
+/// advanced and not on a rook file; in this case it is often possible to win
+/// (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
+template<>
+ScaleFactor Endgame::apply(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO);
+ assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
+ assert(pos.piece_count(WHITE, PAWN) == 1);
+ assert(pos.piece_count(BLACK, PAWN) == 1);
+
+ Square wksq, bksq, wpsq;
+ Color stm;
+
+ if (strongerSide == WHITE)
+ {
+ wksq = pos.king_square(WHITE);
+ bksq = pos.king_square(BLACK);
+ wpsq = pos.piece_list(WHITE, PAWN, 0);
+ stm = pos.side_to_move();
+ }
+ else
+ {
+ wksq = flip_square(pos.king_square(BLACK));
+ bksq = flip_square(pos.king_square(WHITE));
+ wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
+ stm = opposite_color(pos.side_to_move());
+ }
+
+ if (square_file(wpsq) >= FILE_E)
+ {
+ wksq = flop_square(wksq);
+ bksq = flop_square(bksq);
+ wpsq = flop_square(wpsq);
+ }
+
+ // If the pawn has advanced to the fifth rank or further, and is not a
+ // rook pawn, it's too dangerous to assume that it's at least a draw.
+ if ( square_rank(wpsq) >= RANK_5
+ && square_file(wpsq) != FILE_A)
+ return SCALE_FACTOR_NONE;
+
+ // Probe the KPK bitbase with the weakest side's pawn removed. If it's a
+ // draw, it's probably at least a draw even with the pawn.
+ return probe_kpk_bitbase(wksq, wpsq, bksq, stm) ? SCALE_FACTOR_NONE : SCALE_FACTOR_ZERO;
+}
diff --git a/DroidFish/jni/stockfish/endgame.h b/DroidFish/jni/stockfish/endgame.h
new file mode 100644
index 0000000..e35c7b0
--- /dev/null
+++ b/DroidFish/jni/stockfish/endgame.h
@@ -0,0 +1,112 @@
+/*
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
+
+ Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#if !defined(ENDGAME_H_INCLUDED)
+#define ENDGAME_H_INCLUDED
+
+#include
+#include