StockFish Chess Engine 无法在 Android 设备上运行,但可以在独立构建和 Unity 编辑器上完美运行

StockFish Chess Engine won't work on Android Device but, works on Standalone Build and Unity editor perfectly

我一直在研究国际象棋游戏并使用 Stockfish 国际象棋引擎在其中实现 AI。我成功地启动了可执行文件,将 fen 代码作为输入发送并从引擎接收输出。它在统一编辑器和独立构建上完美运行。但是,它不适用于 android 设备。我不知道为什么。

我已确保文件 copied/created 到正确的目录并且成功。有人可以帮我解决这个问题吗?

    string fen;
    public static Process mProcess;

    void Start()
    {
        Setup();
    }


    public void Setup()
    {
        // since the apk file is archived this code retreives the stockfish binary data and
        // creates a copy of it in the persistantdatapath location.
#if UNITY_EDITOR

        string filepath = "D:\Chess Projects\StockFishTest\Assets\StreamingAssets\stockfish_10_x64.exe";
#elif UNITY_ANDROID
        string filepath = Application.persistentDataPath + "/" + "stockfish-10-armv7";
        Debug.Log(filepath);
        if (!File.Exists(filepath))
        {
            WWW executable = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "stockfish-10-armv7");
            while (!executable.isDone)
            {
            }
            File.WriteAllBytes(filepath, executable.bytes);

            //change permissions via plugin

        }
        var plugin = new AndroidJavaClass("com.chessbattles.jeyasurya.consoleplugin.AndroidConsole");
            string command = "chmod 777 "+filepath;
            outPut = plugin.CallStatic<string>("ExecuteCommand",command);

#else
        string filepath = Application.streamingAssetsPath+ "/" + "stockfish_10_x64.exe";
#endif
        // creating the process and communicating with the engine
        mProcess = new Process();
        ProcessStartInfo si = new ProcessStartInfo()
        {
            FileName = filepath,
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardError = true,
            RedirectStandardInput = true,
            RedirectStandardOutput = true
        };
        mProcess.StartInfo = si;
        mProcess.OutputDataReceived += new DataReceivedEventHandler(MProcess_OutputDataReceived);
        mProcess.Start();
        mProcess.BeginErrorReadLine();
        mProcess.BeginOutputReadLine();

        SendLine("uci");
        SendLine("isready");

    }

    public void GetMove(string fen, int processTime = 0, int DepthValue = 1)
    {

        if(fen ==null || fen == ""){
            UnityEngine.Debug.LogError("Enter proper Fen");
            Debug.Log("Enter proper Fen");
            return;
        }

        SendLine("position fen "+ fen);

        if(processTime != 0){
            SendLine("go movetime "+processTime);
        }
        else if(DepthValue != 0)
        {
            SendLine("go depth "+ DepthValue);
        }
        else
        {
            SendLine("go depth " + DepthValue);
        }

    }

    public string output = "";
    public bool moveReady = false;
    public void SendLine(string command) {
        mProcess.StandardInput.WriteLine(command);
        mProcess.StandardInput.Flush();
    }

    void MProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        output = "";
    //    UnityEngine.Debug.Log("Output: " + e.Data);
        output = e.Data;
        if (output.Length != 0)
            if (output[0] == 'b' && output[3] == 't')
            {
                output = e.Data.Substring(9, 4);
      //          Debug.Log(output);
                moveReady = true;
            }
            else
            {
                moveReady = false;
            }

    }

我已经成功地完成了这项工作。您需要更新文件路径中的包名称。

using System.Diagnostics;
using System.IO;
using UnityEngine;

namespace Assets.Scripts
{
    public class EngineCommunicator
    {
        public static Process mProcess;
        public static string fileName = "stockfish.android.armv7";
        public static void Communicate()
        {
#if UNITY_EDITOR
            string filepath = "E:\Personal\Unity\Chess2d\Assets\Plugins\Windows\stockfish_13_win_x64";
#elif UNITY_ANDROID
            string filepath = "/data/data/com.tiringbring.Chess2d/lib/stockfish.android.armv7.so";
            UI.Instance.AddJob(() =>
            {
                UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text = filepath;
            });
            

            if (!File.Exists(filepath))
            {
                UI.Instance.AddJob(() =>
                {
                    UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text =UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text +" "+ "file not found";
                });
            }else{
                UI.Instance.AddJob(() =>
                {
                    UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text =UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text +" "+ "file found";
                });
            }
#else
        string filepath = Application.streamingAssetsPath+ "/" + "stockfish_13_x64.exe";
#endif
            // creating the process and communicating with the engine
            mProcess = new Process();
            ProcessStartInfo si = new ProcessStartInfo()
            {
                FileName = filepath,
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                RedirectStandardOutput = true
            };
            mProcess.StartInfo = si;
            mProcess.OutputDataReceived += new DataReceivedEventHandler(MProcess_OutputDataReceived);
            mProcess.Start();
            mProcess.BeginErrorReadLine();
            mProcess.BeginOutputReadLine();

            SendLine("uci");
            SendLine("isready");
            SendLine("ucinewgame");
            SendLine("position startpos");
            SendLine("go infinite searchmoves e2e4 d2d4");


        }


        private static void SendLine(string command)
        {
            mProcess.StandardInput.WriteLine(command);
            mProcess.StandardInput.Flush();
        }

        private static void MProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            string text = e.Data;
            UI.Instance.AddJob(() =>
            {
                UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text = UI.Instance.TestText.GetComponent<TMPro.TextMeshProUGUI>().text +" "+ text;
            });

            UnityEngine.Debug.Log(text);
        }
    }
}

将文件放在 Assets/Android 目录中,扩展名为 .so。

它将自动复制到 android 手机上的 lib 文件夹中