Running Stockfish hosted in Azure function

While working on small chess application had an idea to integrate Stockfish engine, so it will be possible to play with engine.
More about Stockfish here : https://stockfishchess.org/
and here https://github.com/mcostalba/Stockfish

The idea is to pass FEN and Depth for calculation to some API which will suggest the best move.
My main problem is that the goal is to host engine in Azure, as function written in C# while Stockfish is in C++. There are of course some .net ports but really outdated and did not want to experiment with them.

First step is just to clone git repo of Stockfish and build exe file, put it into separate folder in my solution. Stockfish is a command line tool. I will send the commands to console and read the output.

This is what I will send and get:


And in the solution it will look like this:

With "No build" and "Copy to output" options

The function by itself to get the request is pretty simple:
[FunctionName("stockfish")]
        public static async Task RunStockfish(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext context)
        {
            string fen = req.Query["fen"];
            string depth = req.Query["depth"];
            
            depth = depth ?? "5";

            var result = await RunStockfish(log, context, fen, depth);
            return fen != null || int.TryParse(depth,out var k)
                ? (ActionResult)new OkObjectResult(result)
                : new BadRequestObjectResult("Please check parameters");
        }


the part which is calling Stockfish  await RunStockfish(log, context, fen, depth);

private static async Task RunStockfish(ILogger log, ExecutionContext context, string fen, string depth)
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = Path.Combine(context.FunctionAppDirectory, "resources", "stockfish.exe");
            process.StartInfo.Arguments = "";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardError = true;
            process.Start();
            //await process.StandardInput.WriteLineAsync("uci");
            await process.StandardInput.WriteLineAsync("position fen " + fen);
            await process.StandardInput.WriteLineAsync($"go depth {depth}");
            //process.StandardInput.WriteLine("eval");

            // await Task.Delay(3000);

            await process.StandardInput.WriteLineAsync("quit");
            string output = await process.StandardOutput.ReadToEndAsync();
            string err = await process.StandardError.ReadToEndAsync();
            process.WaitForExit();

            return output;
        }

Just build and deploy to Azure (you can try to play locally first :) )

In my sample I just passed starting point with FEN string
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -


What is left, just parse the output, grab the last line and cut "bestmove".



Comments

Popular posts from this blog

How to poll database using WCF-SQL adapter

SQL query timeout from application but works fast from SSMS