Someone brought to my attention that Python Chess was using up a lot of CPU cycles, even when (actually, especially when) it was just sitting waiting for user input. I checked on my system and found it was using 30-40% of the CPU time…way too much for such a simple game!
Some googling revealed that I was using pygame’s event loop in a reckless manner. I was using pygame.event.get() to get user mouse clicks or other input — evidently, this will return a list of events that have queued up since the last time the get() function was called (not sure if there is a limit to the queue size….) Since the call to get() is basically a while(1) loop, it was being called just as fast as it could, which is pretty unecessary for a game like chess. Actually, probably for any game this is overkill. Luckily, there are a few easy solutions.
The option which I used for Python Chess is to use pygame.event.wait() rather than pygame.event.get(). The wait() function will cause the program to go into an idle state (ie. not hogging the processor) until it gets a single event. This is much more suited for the game of chess, where the user needs time to ponder their move, anyway. Replacing my event.get() calls to event.wait() makes the CPU usage of Python Chess go down to 0-1% on my system, with occassional spikes during the AI’s turn of up to 10% (these are just rough numbers seen via Windows Task Manager). Quite an improvement!
Another option for limiting CPU usage is to create a pygame.time.Clock() object, then calling the object’s tick(fps) function every time through your while(1) loop. This will limit the loop’s execution to fps (frames per second) times per second, allowing it to go idle in between loop processing. (Note that on slower systems, the desired fps may not be achievable, so it will still use up a healthy chunk of processing time if the value is too high.) Using time.Clock seems to be more suited to “action” style games, where there is screen movement going on every time through the loop, for instance.