【问题标题】:How does one integrate stockfish into an Android App?如何将stockfish 集成到Android 应用程序中?
【发布时间】:2017-04-23 02:39:35
【问题描述】:

我正在尝试研究如何将 stockfish(或任何与 UCI 兼容的引擎)集成到我的 Android 应用程序中。

我从这里下载了 stockfish Android zip: Download Stockfish Engine.

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

  • stockfish-8-arm64-v8a
  • stockfish-8-armeabi-v7a

我有两个问题:

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

谢谢!

【问题讨论】:

  • 这些文件实际上是 ELF ABI 格式(基本上是机器代码,带有一些用于链接的结构)。根据您的 IDE,您可能无法直接导入它们,因此您可能还需要在项目中启用 C/C++ 支持的源代码文件。
  • 顺利完成这项工作?
  • 还没有抱歉。我现在把它放在一边。
  • 这很简单,只要记住 Stockfish 是一个 C++ 项目,为了让 Android Studio 与 C++ 库对话,你需要使用 NDK developer.android.com/ndk/index.html
  • 你明白了吗?

标签: java android chess


【解决方案1】:

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

  1. 依靠JNI(Java 原生接口,参见jni-sample)来解决问题。
  2. 学习了如何使用 JNI 编译 Stockfish 后,您可以通过 UCI 协议与引擎进行交互:这里是 UCI Specification

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

修改像Droidfish 这样的现有项目比从头开始要容易得多。

【讨论】:

    【解决方案2】:

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

    • https://stockfishchess.org/download/下载源代码,与平台无关
    • 在 android studio 中创建 Native 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 文件之外的所有内容。
    • 重命名每个文件夹中的每个stockfish 文件,如lib_stockfish.so,现在文件夹应如下所示:
    ...
    -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"])
    
    • 在manifest文件中的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) {
            
        }
    
    
    
    

    【讨论】:

    • 嗨,感谢您的精彩解释,过去几天我一直在寻找这个,我按照您的说明进行操作,但不幸的是,当我运行代码时,我收到以下错误 E/error: java.io.IOException: Cannot run program "/data/app/com.example.testc-hUWO86ZpvRLc1on2Z0uyig==/lib/x86/lib_stockfish.so": error=2, No such file or directory,由process = Runtime.getRuntime().exec(file.getPath()); 行引起的错误,即使经过数小时的调试,我也找不到解决方案,请您帮我解决这个问题,
    • 在 libs 文件夹中是否有一个名为 x86 的文件夹,其中包含 lib_stockfish.so?
    • 嗨,是的,我在 libs/x86 文件夹中有一个 lib_stockfish.so 文件,我从另一个项目中复制了该文件并根据您的说明重命名...它对您有用吗?我又浪费了一天时间尝试找到解决方案,但没有运气,最后我放弃了:( -
    • 对我来说是的,它有效,我正在开发一个国际象棋游戏,你是否将jniLibs.srcDirs = ['libs'] 像这样放在应用程序 gradle 中:android{...sourceSets { main { jniLibs.srcDirs = ['libs'] }}}
    • 看来我在原始答案中遗漏了一些东西,您需要在应用程序标记android:extractNativeLibs="true" 中添加清单文件,并且在 MainActivity 中您应该在发出任何命令之前调用outThread.start();引擎
    猜你喜欢
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2012-11-10
    • 2011-06-29
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    相关资源
    最近更新 更多