c# - 无法与“Stockfish-9-armv7”二进制文件通信
问题描述
我正在 Unity3D 中开发国际象棋游戏。我想为Android平台开发它。对于 AI,我使用的是 Stockfish 国际象棋引擎。我下载了名为“ Stockfish-9-armv7 ”的 Android 版 Stockfish 二进制文件。我将此二进制文件放在我的 StreamingAssets 文件夹中,以便它在构建步骤期间正确进入目标平台。直到这里一切正常,即当我构建我的 Unity 项目时,文件被放置在正确的位置,我可以很好地看到它。
现在为了让我的 AI 工作,我必须使用UCI协议与这个二进制文件进行通信。所以我在我的 Unity 项目中编写了一个 C# 脚本,它创建了一个进程来运行二进制文件并与之通信。但这不起作用。
然而,当我对 Windows 执行完全相同的操作时,即使用名为“stockfish_9_x64.exe”的 Windows 二进制版本的 Stockfish 并将其构建为独立应用程序时,一切正常,我能够通过我的 C# 代码与引擎进行通信。
我在网上进行了研究,但找不到太多资源和指导。我发现了一个类似的帖子,通读它让我得出结论,它可能与文件权限有关。提出这个问题的人实际上通过编写这两行代码解决了这个问题:
string[] cmd = { "chmod", "744", Path.Combine(strToFolder, fileName) };
Java.Lang.Runtime.GetRuntime().Exec(cmd);
然而,他使用的是 Xamarin 并且可以访问 Java 运行时库。我正在使用 Unity 和 C#,我真的不知道如何更改此二进制文件的执行/运行权限并运行它。事实上,我什至不知道这是否是问题所在。
我只想将 stockfish 集成到我的 Unity 项目中,并以 Android 作为目标平台。如果有人有任何想法,建议或以前有人这样做过,请指导我。即使我从一开始就错了,而且我的方法有问题,也要让我知道,以及更正的方法。
下面是我的代码:
public class CommunicateWithEngine {
public static Process mProcess;
public static void Communicate()
{
// since the apk file is archived this code retreives the stockfish binary data and
// creates a copy of it in the persistantdatapath location.
string filepath = Application.persistentDataPath + "/" + "Stockfish-9-armv7";
if (!File.Exists(filepath))
{
WWW executable = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "Stockfish-9-armv7");
while (!executable.isDone)
{
}
File.WriteAllBytes(filepath, executable.bytes);
}
// creating the process and communicating with the engine
mProcess = new Process();
ProcessStartInfo si = new ProcessStartInfo()
{
FileName = System.IO.Path.Combine(Application.persistentDataPath, "Stockfish-9-armv7"),
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");
}
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;
Test.PrintStringToTheConsole(text);
}
}
解决方案
对于任何与 OP 和我一样遇到同样问题的人。经过 12 小时的搜索和谷歌搜索,这里是一个解决方案。您可以使用可执行的 stockfish 二进制文件,但您必须将二进制文件的扩展名更改为 .so 并将其统一导入文件夹 /Assets/Plugins/Android 中。构建后,您可以在设备上的文件夹 /data/data//lib 中找到它。在这里您可以执行它并获取输入和输出。
推荐阅读
- python - 比较一个数据帧中的元素,并使用 pandas 将输出放入另一个数据帧
- mysql - 当我点击 recyclarview itam 它应该从我的 recyclarview 中隐藏
- python - 消除
在 Beautiful Soup 中使用 .decompose() 标记 - jenkins - 从 Jenkins 运行 ansible 时缺少 sudo 密码错误
- entity-framework-core - EF Core:插入加密列时操作数类型冲突
- python - Selenium (Python) - 启用后单击禁用按钮
- php - docker 容器之间的 CURL 请求
- github - 可以使 github 克隆兄弟姐妹对其他用户不可见吗?
- bash - Bash 将参数传递给 --init-file 脚本
- python - 程序 Discord.py 命令使用消息