简体   繁体   English

国际象棋 GUI 应用程序未收到使用通用国际象棋接口 (UCI) 的国际象棋引擎的响应

[英]Response from my chess engine using Universal Chess Interface (UCI) isn't received by the chess GUI apps

I've coded some toy chess engines in the past using different languages, all of them providing their own simple text-based UI.我过去曾使用不同的语言编写过一些玩具国际象棋引擎,它们都提供了自己简单的基于文本的 UI。 Now I want to write an engine that can be used with chess GUIs like ChessX or Cute Chess.现在我想编写一个引擎,它可以与 ChessX 或 Cute Chess 等国际象棋 GUI 一起使用。 I've read and understood (at least I thought so) the Universal Chess Interface (UCI) protocol.我已经阅读并理解(至少我是这么认为的)通用国际象棋接口(UCI)协议。

To get a first working version, I'm using Python (3.9 on macOS) for my engine, here's the part that's looking for input via STDIN a full (non-)working example as requested:为了获得第一个工作版本,我将 Python(macOS 上的 3.9)用于我的引擎,这 是通过 STDIN 查找输入的部分, 一个完整(非)工作示例按要求:

import sys
import os
import time
import re
import select
import fileinput


if __name__ == '__main__':
    while True:
        if select.select([sys.stdin, ], [], [], 0.0)[0]:
            for line in fileinput.input():
                tokens = [ x.strip().lower() for x in re.split("\s+", line.strip()) ]
                if tokens[0] == "uci":
                    sys.stdout.write("id name mychess\n")
                    sys.stdout.write("id author myname\n")
                    sys.stdout.write("uciok\n")
                elif tokens[0] == "isready":
                    sys.stdout.write("readyok\n")
        time.sleep(2)

When I put my engine in one of the GUIs (or a simple python-chess app, see below), my engine gets the initial "uci" command and answers accordingly as I can verify using some test and logging code not shown in the minimal example above.当我将我的引擎放入其中一个 GUI(或简单的 python-chess 应用程序,见下文)时,我的引擎会获得初始的“uci”命令并相应地回答,因为我可以使用一些未显示在最小值中的测试和日志记录代码进行验证上面的例子。

But then, nothing happens ... until the GUIs are telling me they timed-out.但是,什么都没有发生……直到 GUI 告诉我他们超时了。 Obviously, they didn't get any answer from my engine.显然,他们没有从我的引擎中得到任何答案。 Using the python-chess library, I can verify that the response from my engine isn't coming through to the GUI process.使用 python-chess 库,我可以验证来自我的引擎的响应没有通过 GUI 进程。

This is the code in my python-chess app to connect to my engine:这是我的 python-chess 应用程序中连接到我的引擎的代码:

engine = chess.engine.SimpleEngine.popen_uci(r"./engine.py")

If I put there the path to the stockfish engine, I can see the response from that engine and how the python-chess app answers with "ucinewgame" and a lot of other communication.如果我把通往stockfish引擎的路径放在那里,我可以看到该引擎的响应以及python-chess 应用程序如何回答“ucinewgame”和许多其他通信。

So, why is the response from my engine not read by the GUI client?那么,为什么 GUI 客户端没有读取来自我的引擎的响应?

Update: I suspect it has something to do with the select code in my example.更新:我怀疑这与我的示例中的select代码有关。 It's there to simulate non-blocking access to STDIN.它可以模拟对 STDIN 的非阻塞访问。 In a simpler approach, I'm just using a blocking call to input and it works (here's the gist of it):在一种更简单的方法中,我只是对输入使用阻塞调用并且它可以工作(这是它的要点):

while True:
    line = input()
    if line.strip().lower() == "uci":
        print("id name mychess")
        print("uciok")

The problem seems to be in using select.select() and/or fileinput.input() .问题似乎在于使用select.select()和/或fileinput.input() If I omit those fancy techniques and simply read from STDIN, everything works and cutechess accepts my engine.如果我省略那些花哨的技术并简单地从 STDIN 读取,一切正常,并且cutechess的女孩接受我的引擎。 This is the basic code for a UCI chess engine to get recognized:这是 UCI 国际象棋引擎获得识别的基本代码:

import sys
import os
import re


if __name__ == '__main__':
    while True:
        line = input()
        tokens = [ x.strip().lower() for x in re.split("\s+", line.strip()) ]
        if tokens[0] == "uci":
            sys.stdout.write("id name mychess\n")
            sys.stdout.write("id author myname\n")
            sys.stdout.write("uciok\n")
        elif tokens[0] == "isready":
            print("readyok")

Of course, the blocking call to input() now doesn't allow for concurrent calculations in my engine while accepting input from the GUI immediately, but that's stuff for perhaps another question.当然,对input()的阻塞调用现在不允许在我的引擎中进行并发计算,同时立即接受来自 GUI 的输入,但这可能是另一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM