如何将鳕鱼整合到Android应用程序中?

时间:2017-04-23 02:39:36

标签: java android chess

我试图找出如何将鳕鱼(或任何UCI兼容引擎)集成到我的Android应用程序中。

我从这里下载了鱿鱼Android拉链: Download Stockfish Engine

在zip的Android目录下有两个文件:

  • 鱼干-8- arm64-V8A
  • 鱼干-8- armeabi-V7A

我有两个问题:

  1. 我只需要将这两个文件包含在我的应用程序中(如果是这样,我将它们放在哪里)?我希望这些是预先构建的二进制文件,所以我不必担心编译自己。
  2. 如何从我的Android Java代码调用这些文件?
  3. 谢谢!

2 个答案:

答案 0 :(得分:8)

Stockfish是用C ++编写的,用Java编写的常规Android应用程序来调用它,你需要

  1. 依靠JNI(Java Native Interface,请参阅jni-sample)来实现这一目标。
  2. 在您学习如何使用JNI编译Stockfish之后,您可以通过 UCI协议与引擎进行交互:以下是UCI Specification

  3. 然后您可以调用特定方法(例如,评估一个位置,或建议最佳移动)。这一切都始于发送引擎isready。如果你得到了答案,那么你就走在了正确的轨道上。

  4. 修改像Droidfish这样的现有项目而不是从头开始会容易得多。

答案 1 :(得分:4)

在搜索了许多天后,我找到了解决方案:

  • https://stockfishchess.org/download/下载源代码,与平台无关
  • 在android studio中创建本机C ++项目
  • 您可以删除cpp文件夹中的native-lib.cpp文件(以及代码中的引用)
  • 提取下载文件的内容,转到src文件夹,将所有文件复制到android项目的cpp文件夹中
  • 在CMakeLists.txt(cpp文件夹)中添加:
   add_executable(
            stockfish
    
            benchmark.cpp   evaluate.h ...(and the rest of the copied files)
    )
  • 在externalNativeBuild-> cmake的build.gradle(app)中添加targets "stockfish",如下所示:
externalNativeBuild {
            cmake {
                targets "stockfish"
                cppFlags ""
            }
        }

  • 构建APK
  • 在/app/.cxx/cmake/debug文件夹中已生成包含可执行文件的文件夹
  • 创建一个没有c ++支持的新android项目
  • 在libs文件夹的新项目中,复制上述文件夹(保留名称),然后在每个文件夹中删除除stockfish文件之外的所有内容。
  • 像这样lib_stockfish.so一样重命名每个文件夹中的每个stockfish文件,现在这些文件夹应如下所示:
...
-libs
     -arm64-v8a
               -lib_stockfish.so
     -armeabi-v7a
               -lib_stockfish.so
and so on...
...
  • 在android的build.gradle(app)中添加:
sourceSets {
        main {

            jniLibs.srcDirs = ['libs']
        }
    }
  • 在build.gradle(app)中的依赖项中添加:
implementation fileTree(dir: "libs", include: ["*.jar", "*.so"])
  • 在清单文件中的application标记中添加:
android:extractNativeLibs="true"
  • 现在这只是Java中的代码:

String path = getApplicationContext().getApplicationInfo().nativeLibraryDir+"/lib_stockfish.so";


File file = new File(path);

try {
    process = Runtime.getRuntime().exec(file.getPath());
} catch (IOException e) {
    e.printStackTrace();
}



Thread outThread =  new Thread(new Runnable() {
    @Override
    public void run() {

        Process processOut = process;
        if(processOut == null){
            return;
        }


           BufferedReader out = new BufferedReader(new InputStreamReader(processOut.getInputStream()));

            String data;
            try{


                   while( (data = out.readLine()) != null ){

                    //do something with data
                   }


                } catch(IOException e){
                 
               }

            }
        });

        outThread.start();


///to give commands

String command = "uci";//or other command

command += "\n";

try {
        Process ep = process;

        if (ep != null) {
            ep.getOutputStream().write(command.getBytes());
            ep.getOutputStream().flush();
        }
    } catch (IOException e) {
        
    }