>source

Windows 7에서는 명령줄을 통해 체스 엔진과 통신할 수 있습니다. 소규모 예제 세션 건어윈 7에서:

C:\run\Stockfish>stockfish-x64.exe
Stockfish 2.2.2 JA SSE42 by Tord Romstad, Marco Costalba and Joona Kiiski
quit
C:\run\Stockfish>

첫 번째 줄은 엔진에 의해 출력되었고 'quit'는 내가 엔진을 종료하기 위해 입력한 것입니다(다음이 있습니다. 내가 할 수 있는 다른 일들, 그러나 그것은 나에게 분명합니다).

이제 파이썬에서 해당 엔진과 통신하고 싶습니다.

import subprocess
engine= subprocess.Popen(
    'stockfish-x64.exe',
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
for line in engine.stdout:
    print(line.strip())
engine.stdin.write('quit\n')

그리고 나는

C:\run\Stockfish>communicate.py
b'Stockfish 2.2.2 JA SSE42 by Tord Romstad, Marco Costalba and Joona Kiiski'

하지만 엔진을 종료하지 않습니다(아니오C:\run\Stockfish> 프롬프트), 입력을 계속 기다립니다. 창문을 손으로 닫아야 해요. 내 종료 메시지(python 스크립트의 마지막 줄)가 stdin에 기록되지 않는 것 같습니다.

즉, stdout에서 읽을 수 있지만 stdin에 쓸 때 아무 일도 일어나지 않습니다.

내가 무엇을 잘못하고 있으며 어떻게 해야 합니까?

C:\run\Stockfish>프롬프트는 쉘에서 가져온 것입니다. 왜 하위 프로세스가 그것을 인쇄할 것으로 예상합니까?

Wooble2021-11-27 23:10:23

내 python 스크립트가 완료된 것을 볼 것으로 기대하십시오.

Nils Lindemann2021-11-27 23:10:23

이것은 매우 도움이 되었습니다. 공유해 주셔서 감사합니다!

jaggedsoft2021-11-27 23:10:23

Popen: ..., bufsize=1, ...에 추가 인수를 추가할 때까지 code가 작동하지 않았습니다.

Darius Duesentrieb2021-11-28 05:39:11

감사합니다 @DariusDuesentrieb, 그 사이에 변경된 것 같습니다. 나는 그것을 추가했다.

Nils Lindemann2021-11-28 16:41:35
  • 답변 # 1

    질문에서 편집한 내용을 이 답변으로 이동합니다.

    larsmans님의 도움으로 해결했습니다.

    Python 스크립트의 예:

    import subprocess, time
    engine= subprocess.Popen(
        'stockfish14.exe',
        universal_newlines=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        bufsize=1,
    )
    def put(command):
        print('\nyou:\n\t'+command)
        engine.stdin.write(command+'\n')
    def get():
        # using the 'isready' command (engine has to answer 'readyok')
        # to indicate current last line of stdout
        engine.stdin.write('isready\n')
        print('\nengine:')
        while True:
            text= engine.stdout.readline().strip()
            if text== 'readyok':
                break
            if text !='':
                print('\t'+text)
    get()
    put('uci')
    get()
    put('setoption name Hash value 128')
    get()
    put('ucinewgame')
    get()
    put('position startpos moves e2e4 e7e5 f2f4')
    get()
    put('go infinite')
    time.sleep(3)
    get()
    put('stop')
    get()
    put('quit')
    

    출력:

    C:\run\chessengines\Stockfish>communicate.py
    engine:
            Stockfish 14 by the Stockfish developers (see AUTHORS file)
    you:
            uci
    engine:
            id name Stockfish 14
            id author the Stockfish developers (see AUTHORS file)
            option name Debug Log File type string default
            option name Threads type spin default 1 min 1 max 512
            option name Hash type spin default 16 min 1 max 33554432
            option name Clear Hash type button
            option name Ponder type check default false
            option name MultiPV type spin default 1 min 1 max 500
            option name Skill Level type spin default 20 min 0 max 20
            option name Move Overhead type spin default 10 min 0 max 5000
            option name Slow Mover type spin default 100 min 10 max 1000
            option name nodestime type spin default 0 min 0 max 10000
            option name UCI_Chess960 type check default false
            option name UCI_AnalyseMode type check default false
            option name UCI_LimitStrength type check default false
            option name UCI_Elo type spin default 1350 min 1350 max 2850
            option name UCI_ShowWDL type check default false
            option name SyzygyPath type string default <empty>        option name SyzygyProbeDepth type spin default 1 min 1 max 100
            option name Syzygy50MoveRule type check default true
            option name SyzygyProbeLimit type spin default 7 min 0 max 7
            option name Use NNUE type check default true
            option name EvalFile type string default nn-3475407dc199.nnue
            uciok
    you:
            setoption name Hash value 128
    engine:
    you:
            ucinewgame
    engine:
    you:
            position startpos moves e2e4 e7e5 f2f4
    engine:
    you:
            go infinite
    engine:
            info string NNUE evaluation using nn-3475407dc199.nnue enabled
            info depth 1 seldepth 1 multipv 1 score cp 90 nodes 33 nps 33000 tbhits 0 time 1 pv e5f4
            info depth 2 seldepth 2 multipv 1 score cp 336 nodes 72 nps 36000 tbhits 0 time 2 pv e5f4 a2a3 d8h4 e1e2
            info depth 3 seldepth 3 multipv 1 score cp 322 nodes 115 nps 57500 tbhits 0 time 2 pv e5f4 g2g3 f4g3
            info depth 4 seldepth 4 multipv 1 score cp 160 nodes 438 nps 219000 tbhits 0 time 2 pv e5f4 d2d3 d8h4 e1e2
            info depth 5 seldepth 5 multipv 1 score cp 38 nodes 1463 nps 365750 tbhits 0 time 4 pv e5f4 g1f3 g8f6 b1c3 d7d5
            info depth 6 seldepth 6 multipv 1 score cp 41 nodes 2424 nps 404000 tbhits 0 time 6 pv e5f4 g1f3 g8f6 b1c3 d7d5 e4d5 f6d5
            info depth 7 seldepth 7 multipv 1 score cp 41 nodes 3409 nps 426125 tbhits 0 time 8 pv e5f4 g1f3 g8f6 b1c3 d7d5 e4d5 f6d5
            info depth 8 seldepth 11 multipv 1 score cp 43 nodes 4937 nps 448818 tbhits 0 time 11 pv d7d5 g1f3 d5e4 f3e5 f7f6 b1c3 f6e5 d1h5 e8d7
            info depth 9 seldepth 11 multipv 1 score cp 4 nodes 14604 nps 486800 tbhits 0 time 30 pv d7d5 g1f3 e5f4 e4d5 g8f6 f1c4 f6d5 e1g1 d5b6
            info depth 10 seldepth 13 multipv 1 score cp 24 nodes 16663 nps 490088 tbhits 0 time 34 pv d7d5 g1f3 e5f4 e4d5 g8f6 f1c4 f6d5 e1g1
            info depth 11 seldepth 16 multipv 1 score cp 49 nodes 24347 nps 486940 tbhits 0 time 50 pv e5f4 f1c4 d7d5 e4d5 g8f6 b1c3 c7c6
            info depth 12 seldepth 19 multipv 1 score cp 46 nodes 58792 nps 477983 tbhits 0 time 123 pv e5f4 g1f3 g7g5 h2h3 d7d5 e4d5 d8d5 b1c3 d5e6 d1e2
            info depth 13 seldepth 19 multipv 1 score cp 45 nodes 88777 nps 482483 tbhits 0 time 184 pv e5f4 f1c4 d7d6 b1c3 d8h4 e1f1 c8e6 c3d5 h4d8 g1f3
            info depth 14 seldepth 17 multipv 1 score cp 50 nodes 120394 nps 483510 tbhits 0 time 249 pv e5f4 f1c4 d7d5 c4d5 d8h4 e1f1 b8c6 d2d4 g7g5 b1c3 f8g7 g1f3 h4h5
            info depth 15 seldepth 19 multipv 1 score cp 52 nodes 192828 nps 480867 tbhits 0 time 401 pv e5f4 f1c4 g8f6 b1c3 c7c6 d2d4 d7d5 e4d5 c6d5 d1e2 f8e7 c4b3 e8g8 c1f4 e7b4 g1f3
            info depth 16 seldepth 22 multipv 1 score cp 59 nodes 309617 nps 475602 tbhits 0 time 651 pv e5f4 f1c4 g8f6 b1c3 c7c6 d2d4 d7d5 e4d5 c6d5 c4b5 b8c6 c1f4 f8d6 f4d6 d8d6 d1e2 c8e6 b5c6
     b7c6 g1f3
            info depth 17 seldepth 26 multipv 1 score cp 34 nodes 955333 nps 476237 hashfull 65 tbhits 0 time 2006 pv e5f4 f1c4 b8c6 d2d4 d8h4 e1f1 d7d6 g1f3 c8g4 c4b5 h4h5 b1c3 e8c8 b5c6 b7c6 c
    1f4 f7f5 d1d3 g8f6 d4d5 f5e4 d3a6 c8d7
            info depth 18 seldepth 28 multipv 1 score cp 44 nodes 1132938 nps 477227 hashfull 78 tbhits 0 time 2374 pv e5f4 f1c4 c7c6 d2d4 d7d5 e4d5 c6d5 c4b5 b8c6 c1f4 g8f6 b1c3 f8b4 g1f3 b4c3
    b2c3 e8g8 e1g1 c8g4
    you:
            stop
    engine:
    you:
            quit
    C:\run\chessengines\stockfish>

  • 답변 # 2

    python-chess처럼 asyncio를 사용하고 싶을 수도 있습니다. 보다

    및 예 선적 서류 비치

    import asyncio
    import chess
    import chess.engine
        async def main():
            transport, engine= await chess.engine.popen_uci("/usr/bin/stockfish")
            board= chess.Board()
            while not board.is_game_over():
                result= await engine.play(board, chess.engine.Limit(time=0.1))
                board.push(result.move)
            await engine.quit()
        asyncio.set_event_loop_policy(chess.engine.EventLoopPolicy())
        asyncio.run(main())
    

    @Nils thx 댓글입니다. gitter.im/python-chess/community에서 토론에 초대합니다.

    Wolfgang Fahl2021-11-28 12:22:23

    좋습니다. 해결책을 찾은 것 같습니다. 다른 사람이 python-chess를 고려하고 있는 경우를 대비하여 숙고 및 무한/무한(중단 가능) 분석이 지원됩니다(python-chess.readthedocs.io/en/latest/…).

    Niklas2021-11-28 12:22:23

    예를 들어 이 문서에서는 start() 및 quit() 함수를 찾을 수 있지만 stop() 및 position() 함수는 찾을 수 없습니다.

    Nils Lindemann2021-11-28 12:22:23

    @Nils paste.debian.net/1127901과 같은 것입니까? 비비동기 API에서도 사용 가능합니다. 이것이 도움이 된다면 문서를 확장할 것입니다. readyok을 사용하여 동기화하는 것은 전혀 문제가 없습니다.

    Niklas2021-11-28 12:22:23

    Stackoverflow 주석은 아마도 이에 대한 올바른 위치가 아닐 것입니다. 예외가 발생하지 않고 기록된 것 같습니다. 근본 원인은 두 번째 분석이 계속 진행되는 동안 예제가 종료되기 때문입니다. 로그를 덜 무섭게 만들려고 노력할 것입니다 ... Btw. 역추적의 줄 번호가 최신 python-chess 버전과 일치하지 않습니다.

    Niklas2021-11-28 12:22:23
  • 답변 # 3

    교착 상태가 발생했습니다: 하위 프로세스는 입력을 기다리고 있고 프로그램은 더 많은 라인을 출력하기를 기다리고 있습니다.

    for line in engine.stdout:
        print(line.strip())
    

    이 루프는 하위 프로세스가 종료될 때만 중지됩니다.표준 출력.

  • 이전 bash : 하위 쉘의 출력 파일 설명자를 상위 쉘의 입력 파일 설명자로 리디렉션하는 방법은 무엇입니까?
  • 다음 각 행에 R의 항목 수가 다른 csv에서 히스토그램 또는 막대 플롯 만들기