Not able to communicate with “Stockfish-9-armv7” b

2019-08-07 11:38发布

问题:

I am developing a Chess Game in Unity3D. I want to develop it for the Android platform. For AI I am using the Stockfish Chess Engine. I downloaded the Stockfish binary for Android named "Stockfish-9-armv7". I placed this binary file in my StreamingAssets folder so that it correctly goes into the targeted platform during build step. Everything works fine till here i.e. when I build my Unity project the file is placed in the correct location and I can very well see it.

Now in order for my AI to work I have to communicate with this binary file using UCI protocols. And so I wrote a C# script in my Unity project that creates a process to run the binary file and communicate with it. But this is not working.

However when I do the exact same thing for Windows i.e. using the windows binary version of Stockfish named "stockfish_9_x64.exe" and building it as a standalone application, things work perfectly and I am able to communicate with the engine via my C# code.

I researched it online but unable to find much resources and guidance. I found a similar post and reading through it led me conclude that maybe it has something to do with file permissions. The guy who asked this question actually solved the issue by writing these two lines of code:

string[] cmd = { "chmod", "744", Path.Combine(strToFolder, fileName) };
Java.Lang.Runtime.GetRuntime().Exec(cmd);  

However he was using Xamarin and had access to Java Runtime library. I am using Unity and C# and I really don't know how to change the execute/run permission of this binary file and run it. In fact I don't even know whether this is the problem or not.

I just want to integrate stockfish into my Unity project with Android as the targeted platform. If anyone has any ideas, suggestions or if anyone has done this before, please guide me. Even if I am wrong from the start and my approach is buggy let me know that as well along with the corrected approach.

Given below is my code:

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