As per the PGN specification, this should not happen. See also cutechess/cutechess#172.
I wrote this simple "one move engine" that can be used to test the correct implementation in fastchess:
import asyncio, sys
VERSION = "one move engine 0.95"
class Engine:
def __init__(self, move):
print(VERSION, flush=True)
self.move = move
def go(self):
print(
f"info depth 1 seldepth 1 multipv 1 score cp 0 time 1 nodes 1 nps 1 pv {self.move}",
flush=True,
)
print(f"bestmove {self.move}", flush=True)
async def UCIinterface(self):
while True:
line = await asyncio.get_event_loop().run_in_executor(
None, sys.stdin.readline
)
parts = line.split()
if not parts:
continue
if parts[0] == "quit":
break
elif parts[0] == "uci":
print(f"id name {VERSION}\nid author {self.move}\n")
print("uciok", flush=True)
elif parts[0] == "isready":
print("readyok", flush=True)
elif parts[0] == "go":
self.go()
async def main(move):
engine = Engine(move)
await engine.UCIinterface()
if __name__ == "__main__":
move = sys.argv[1] if len(sys.argv) > 1 else "e2e4"
asyncio.run(main(move))
A sample output running python one_move_engine.py e2e4 vs. python one_move_engine.py a1a1 is shown below.
[Event "Fastchess Tournament"]
[Site "?"]
[Date "2025.11.16"]
[Round "1"]
[White "e2e4"]
[Black "a1a1"]
[Result "1-0"]
[GameDuration "00:00:00"]
[GameStartTime "2025-11-16T11:39:19 +0100"]
[GameEndTime "2025-11-16T11:39:19 +0100"]
[PlyCount "2"]
[Termination "illegal move"]
[TimeControl "1"]
[ECO "B00"]
[Opening "King's Pawn Game"]
1. e4 {0.00/1 0.000s} a1a1 {0.00/1 0.000s, Black makes an illegal move} 1-0
[Event "Fastchess Tournament"]
[Site "?"]
[Date "2025.11.16"]
[Round "1"]
[White "a1a1"]
[Black "e2e4"]
[Result "0-1"]
[GameDuration "00:00:00"]
[GameStartTime "2025-11-16T11:39:19 +0100"]
[GameEndTime "2025-11-16T11:39:19 +0100"]
[PlyCount "1"]
[Termination "illegal move"]
[TimeControl "1"]
1. a1a1 {0.00/1 0.000s, White makes an illegal move} 0-1
As per the PGN specification, this should not happen. See also cutechess/cutechess#172.
I wrote this simple "one move engine" that can be used to test the correct implementation in fastchess:
A sample output running
python one_move_engine.py e2e4vs.python one_move_engine.py a1a1is shown below.