【问题标题】:StockFish Chess Engine won't work on Android Device but, works on Standalone Build and Unity editor perfectlyStockFish Chess Engine 无法在 Android 设备上运行,但可以在独立构建和 Unity 编辑器上完美运行
【发布时间】:2020-04-13 04:11:12
【问题描述】:

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

我已确保将文件复制/创建到正确的目录并成功。有人可以帮我解决这个问题吗?

    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;
            }

    }

【问题讨论】:

  • 据我所知,exe文件不会在Andriod中运行...,当环境发生变化时,使用绝对文件路径会破坏你的程序。
  • 嗨,@MyBug18 我没有使用安卓的 Exe 文件。我正在使用由 stockfish 团队 (stockfishchess.org/download) 提供的预编译二进制文件 stockfish 10。我已经检查并确认文件安装在正确的位置。

标签: c# android unity3d binaryfiles chess


【解决方案1】:

我设法使这项工作像这样。您需要更新文件路径中的包名。

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。

它会自动复制到安卓手机的lib文件夹中

【讨论】:

  • 您好,非常感谢您回复本帖。 stockfish 二进制 10 绝对不可能做到这一点。我相信他们为以后的版本修复了它。我很高兴你能弄清楚。那时我最终使用了另一个更容易实现的游戏引擎。
猜你喜欢
  • 1970-01-01
  • 2021-12-07
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多