pythonchesspython-chessstockfish

Why the python chess engine time goes downward Although the engine is running constantly without stopping?


When i tried this code in my main project to get infinite analysis in my chess GUI (I wanted the engine to think infinitely about a position and give its data (score, best move, etc..) and no depth or time limit) , when I check time of analysis of engine ( which must be going up as it is running infinitely) ,it gives times up and down (like go from 5 sec to 3 sec and so on) so i tried it individually and still give me strange times as it goes on. How can I make the time go up only ( Make infinite analysis with engine ) , and for who is asking , I use threading so that I run the infinite analysis WITH the app (GUI) itself, as if if it used normally this line will be infinitely long and won't run rest of code

import queue
import time
import chess.engine
import threading
import chess
board = chess.Board()
info_queue = queue.Queue()
engine = chess.engine.SimpleEngine.popen_uci("C:/Program Files/ChessX/data/engines/stockfish/stockfish-windows-x86-64.exe")
multipv_dict = []
def test():
    global board
    global info_queue
    global multipv_dict
    global engine
    with engine.analysis(board, chess.engine.Limit(time=None), multipv=1) as analysis:
        for info in analysis:
            try:
                if "multipv" in info and "pv" in info:
                    multipv_dict.append(info)  # Save the info

                    # If we got all PVs we asked for
                    if len(multipv_dict) == 1:
                        # 🧹 Clear old queue safely
                        with info_queue.mutex:
                            info_queue.queue.clear()

                        # 💡 Add all PVs
                        info_queue.put(multipv_dict)

                        multipv_dict = []
            except chess.engine.EngineTerminatedError:break
while True:
    tg = threading.Thread(target=test)
    tg.start()
    time.sleep(2)  # Wait for the thread to start
    if not info_queue.empty():
        info_list = info_queue.get()    # this is the [info_dict, ...]
        # Since you requested multipv=1, you know info_list has exactly one item
        info = info_list[0]                 # the InfoDict

        # 2) Pull out the ‘time’ field
        elapsed = info.get("time")
        print(f"Engine thinking time: {elapsed:.3f} seconds")
Engine thinking time: 1.970 seconds
Engine thinking time: 1.532 seconds
Engine thinking time: 1.980 seconds
Engine thinking time: 1.861 seconds
Engine thinking time: 1.765 seconds
Engine thinking time: 1.866 seconds
Engine thinking time: 1.499 seconds
Engine thinking time: 0.742 seconds

and for who is wondering for analysis itself

[{'depth': 18, 'seldepth': 24, 'multipv': 1, 'score': PovScore(Cp(+28), WHITE), 'nodes': 278301, 'nps': 212281, 'hashfull': 108, 'tbhits': 0, 'time': 1.311, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('g8f6'), Move.from_uci('f3e5'), Move.from_uci('f6e4'), Move.from_uci('d2d4'), Move.from_uci('d7d5'), Move.from_uci('f1d3'), Move.from_uci('f8d6'), Move.from_uci('b1d2'), Move.from_uci('d8h4'), Move.from_uci('d1f3'), Move.from_uci('e4f6')]}]
[{'depth': 20, 'seldepth': 30, 'multipv': 1, 'score': PovScore(Cp(+26), WHITE), 'nodes': 252508, 'nps': 232940, 'hashfull': 81, 'tbhits': 0, 'time': 1.084, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('d2d4'), Move.from_uci('e5d4'), Move.from_uci('f3d4'), Move.from_uci('g8f6'), Move.from_uci('d4c6'), Move.from_uci('b7c6'), Move.from_uci('f1d3'), Move.from_uci('d7d5'), Move.from_uci('e4e5'), Move.from_uci('f6d7'), Move.from_uci('e1g1'), Move.from_uci('d7c5'), Move.from_uci('f2f4'), Move.from_uci('c5d3'), Move.from_uci('c2d3'), Move.from_uci('c8f5'), Move.from_uci('g2g4'), Move.from_uci('f5c8'), Move.from_uci('f4f5'), Move.from_uci('d8h4')]}]
[{'depth': 24, 'seldepth': 27, 'multipv': 1, 'score': PovScore(Cp(+28), WHITE), 'nodes': 443589, 'nps': 249067, 'hashfull': 164, 'tbhits': 0, 'time': 1.781, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('f1b5'), Move.from_uci('a7a6'), Move.from_uci('b5a4'), Move.from_uci('g8f6'), Move.from_uci('e1g1'), Move.from_uci('f6e4'), Move.from_uci('d2d4'), Move.from_uci('b7b5'), Move.from_uci('a4b3'), Move.from_uci('d7d5'), Move.from_uci('d4e5'), Move.from_uci('c8e6'), Move.from_uci('c2c3'), Move.from_uci('f8c5'), Move.from_uci('b1d2'), Move.from_uci('e8g8'), Move.from_uci('b3c2'), Move.from_uci('f7f5'), Move.from_uci('e5f6'), Move.from_uci('e4f6'), Move.from_uci('d2b3'), Move.from_uci('c5b6')]}]
[{'depth': 22, 'seldepth': 32, 'multipv': 1, 'score': PovScore(Cp(+34), WHITE), 'nodes': 526291, 'nps': 270031, 'hashfull': 198, 'tbhits': 0, 'time': 1.949, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('f1b5'), Move.from_uci('a7a6'), Move.from_uci('b5a4'), Move.from_uci('g8f6'), Move.from_uci('e1g1'), Move.from_uci('b7b5'), Move.from_uci('a4b3'), Move.from_uci('f6e4'), Move.from_uci('d2d4'), Move.from_uci('d7d5'), Move.from_uci('d4e5'), Move.from_uci('c8e6'), Move.from_uci('c2c3'), Move.from_uci('f8e7'), Move.from_uci('b1d2'), Move.from_uci('e4c5'), Move.from_uci('b3c2'), Move.from_uci('d5d4'), Move.from_uci('d2b3'), Move.from_uci('c5b3'), Move.from_uci('a2b3'), Move.from_uci('d4c3')]}]
[{'depth': 20, 'seldepth': 30, 'multipv': 1, 'score': PovScore(Cp(+19), WHITE), 'nodes': 456265, 'nps': 271748, 'hashfull': 167, 'tbhits': 0, 'time': 1.679, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('f1b5'), Move.from_uci('g8f6'), Move.from_uci('d2d4'), Move.from_uci('e5d4'), Move.from_uci('e1g1'), Move.from_uci('a7a6'), Move.from_uci('b5a4'), Move.from_uci('f8e7'), Move.from_uci('f1e1'), Move.from_uci('e8g8'), Move.from_uci('e4e5'), Move.from_uci('f6e8'), Move.from_uci('h2h3'), Move.from_uci('d7d6'), Move.from_uci('a4c6'), Move.from_uci('b7c6'), Move.from_uci('f3d4'), Move.from_uci('d8d7'), Move.from_uci('e5d6'), Move.from_uci('e7d6')]}]       
[{'depth': 24, 'seldepth': 36, 'multipv': 1, 'score': PovScore(Cp(+31), WHITE), 'nodes': 427789, 'nps': 303181, 'hashfull': 154, 'tbhits': 0, 'time': 1.411, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('f1b5'), Move.from_uci('g8f6'), Move.from_uci('e1g1'), Move.from_uci('f6e4'), Move.from_uci('f1e1'), Move.from_uci('e4d6'), Move.from_uci('f3e5'), Move.from_uci('f8e7'), Move.from_uci('b5f1'), Move.from_uci('c6e5'), Move.from_uci('e1e5'), Move.from_uci('e8g8'), Move.from_uci('d2d4'), Move.from_uci('e7f6'), Move.from_uci('e5e1'), Move.from_uci('f8e8'), Move.from_uci('c1f4'), Move.from_uci('e8e1'), Move.from_uci('d1e1'), Move.from_uci('f6d4')]}]       
[{'depth': 25, 'seldepth': 35, 'multipv': 1, 'score': PovScore(Cp(+27), WHITE), 'nodes': 371424, 'nps': 275946, 'hashfull': 154, 'tbhits': 0, 'time': 1.346, 'pv': [Move.from_uci('e2e4'), Move.from_uci('e7e5'), Move.from_uci('g1f3'), Move.from_uci('b8c6'), Move.from_uci('f1b5'), Move.from_uci('g8f6'), Move.from_uci('e1g1'), Move.from_uci('f6e4'), Move.from_uci('f1e1'), Move.from_uci('e4d6'), Move.from_uci('f3e5'), Move.from_uci('f8e7'), Move.from_uci('b5f1'), Move.from_uci('c6e5'), Move.from_uci('e1e5'), Move.from_uci('e8g8'), Move.from_uci('d2d4'), Move.from_uci('d6e8'), Move.from_uci('d4d5'), Move.from_uci('e7c5'), Move.from_uci('e5e1'), Move.from_uci('d7d6'), Move.from_uci('b1c3'), Move.from_uci('f7f5'), Move.from_uci('c1e3'), Move.from_uci('c5e3'), Move.from_uci('e1e3'), Move.from_uci('e8f6'), Move.from_uci('e3e2'), Move.from_uci('c8d7'), Move.from_uci('a2a4'), Move.from_uci('f8e8'), Move.from_uci('a4a5')]}]

I this is caused by the difference between analysis and analyse, could anyone help me and explain the difference between these two?


Solution

  • The reason the time value in your output goes up and down is because you are starting a new analysis in a new thread every loop iteration. Each time you call engine.analysis(), it starts a fresh analysis from scratch, so the reported time field is the time spent in that particular analysis session, not a cumulative time. When you start a new thread, the timer resets, so you see small values that go up, then reset again.

    Start a single analysis and keep it running, collecting info as it comes in, instead of starting a new thread/analysis every time.

    Difference between analysis and analyse: