|
|||||||||||
|
Weakening an UCI engine (Windows, Python)
Hello dear all,
inspired by the ChessSystemTal2-v21 invincible? thread and as well by the birth of Absurd-1.0 engine from the same authors (C. Whittington & E. Schröder), mentioned in the very same thread, I wanted to achieve a much weaker version. Currently these engines are pretty useless for human players and chess computers, maybe except the SenseRobot Chess. On another hand, they do provide wild games when facing other mighty chess engines, and that's already an achievement - both authors deserve many thanks for sharing these. Time ago I learnt IT development, I have been pretty efficient writing Cobol but this doesn't help here ![]() So, I asked ChatGPT for some help. This provided me with the basics which nevertheless required many tests and manual improvements. This solution is based on Python; if you don't have it installed check here. The code I use is pretty basic, hence I don't suspect any particular version requirement. It is a "wrapper" meaning the Python code will act between the GUI and the UCI engine. It handles both channel queues, the one the GUI uses to talk to the engine, and the one the engine uses to talk to the GUI. It is so quite similar to known tools such as InBetween and Polyglot, just made for the specific goal of slowing down and limiting the strength of the engine. Here is the Python code: Code:
import subprocess
import threading
import sys
import time
import queue
import re
ENGINE = ["Absurd-1.0.exe"]
DEPTH_LIMIT = 4
INFO_DELAY = 2.5
info_queue = queue.Queue()
bestmove_buffer = None
bestmove_sent = False
engine = subprocess.Popen(
ENGINE,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True,
bufsize=1
)
# -------- GUI → engine --------
def gui_to_engine():
global bestmove_buffer, bestmove_sent
for line in sys.stdin:
line = line.strip()
# reset state for each new move
if line.startswith("position"):
bestmove_buffer = None
bestmove_sent = False
# enforce ponder=false
if line.lower().startswith("setoption name ponder"):
engine.stdin.write("setoption name Ponder value false\n")
engine.stdin.flush()
sys.stdout.write("info Ponder forced to false" + "\n")
sys.stdout.flush()
continue
# replace any go with go depth
if line.startswith("go"):
engine.stdin.write(f"go depth {DEPTH_LIMIT}\n")
engine.stdin.flush()
sys.stdout.write(f"info go depth forced to {DEPTH_LIMIT}\n")
sys.stdout.flush()
continue
engine.stdin.write(line + "\n")
engine.stdin.flush()
# -------- listening to engine --------
def engine_reader():
global bestmove_buffer
for line in engine.stdout:
line = line.strip()
if line.startswith("info") and not line.startswith("info string"):
info_queue.put(line)
elif line.startswith("bestmove"):
# store without posting
bestmove_buffer = line
else:
# uciok, readyok, ...
sys.stdout.write(line + "\n")
sys.stdout.flush()
# -------- slowed down info + triggering logic --------
def info_emitter():
global bestmove_sent, bestmove_buffer
while True:
line = info_queue.get()
if not bestmove_sent:
time.sleep(INFO_DELAY)
trigger = False
# --- A condition: opening move (Polyglot syntax) ---
if line == "info depth 1 time 0 nodes 0 nps 0 cpuload 0":
trigger = True
sys.stdout.write("info move played from opening library\n")
sys.stdout.flush()
# --- B condition: max depth reached ---
else:
m = re.search(r"\bdepth\s+(\d+)", line)
if m:
reached = int(m.group(1))
if reached >= DEPTH_LIMIT:
trigger = True
# display line
if not bestmove_sent:
sys.stdout.write(line + "\n")
sys.stdout.flush()
# post bestmove once max depth PV displayed
if trigger and bestmove_buffer and not bestmove_sent:
sys.stdout.write(bestmove_buffer + "\n")
sys.stdout.flush()
bestmove_sent = True
bestmove_buffer = None
# -------- Starting up --------
threading.Thread(target=gui_to_engine, daemon=True).start()
threading.Thread(target=engine_reader, daemon=True).start()
info_emitter()
Adjust the Depth & Delay to your taste, and to the expected game time setting. Sometimes, in complex positions, more PVs will be displayed (with selective depth increasing along), resulting in more time used to move, which is quite natural. Some moves will also be played much faster; hence a human-like pace. Ponder is disabled (but the opponent may ponder, if wanted, and make good use of the slowed engine time to think). Opening moves should still be played a tempo. How to use? I assume Python is installed on your PC; in the GUI (tested using Arena and HIARCS Chess Explorer Pro) you may choose the command line engine target as a .bat file instead of a .exe; so we need a tiny .bat file including only one line: python Wrapper_v2.py The above assumes you saved the Python code under the name Wrapper_v2.py (feel free to change that). I also provide a .zip file including both Python code and bat file. They must be located in the same directory where the wrapped engine is. The Wrapper ignores GUI instructions about pondering and time control; hence you can have the engine face any opponent granted any time control (great for playing as a human or launching a tournament including MessChess engines). Please let me know if specific issues occur; and if the solution is useful to you. I tested it with a couple of engines, including SF18 and polyglot (and of course Absurd and CSTal2_v21 as well). I also want to test Patricia 5 soon ![]() MfG, Tibono p.s.: I provided a new, enhanced version (SlowWrapper v4), please read down a couple of posts for more information, and get the new attachment. Geändert von Tibono (10.02.2026 um 21:00 Uhr) |
| Folgende 3 Benutzer sagen Danke zu Tibono für den nützlichen Beitrag: | ||
|
|
Ähnliche Themen
|
||||
| Thema | Erstellt von | Forum | Antworten | Letzter Beitrag |
| Test: Chessnut EVO Maia engine testing | Ray | Die ganze Welt der Schachcomputer / World of chess computers | 7 | 21.02.2024 11:25 |
| Frage: Freie Engine (Uci) für PC - Spielstil | Ecki | Die ganze Welt der Schachcomputer / World of chess computers | 4 | 05.04.2015 16:03 |
| News: Revelation als UCI engine: PCSengine software | krval | Die ganze Welt der Schachcomputer / World of chess computers | 1 | 13.08.2013 16:06 |
| Mephisto PC-Modul als UCI Engine | FluidDynamics | Die ganze Welt der Schachcomputer / World of chess computers | 0 | 14.02.2008 08:53 |
| Fruit als Engine? | Robert | Die ganze Welt der Schachcomputer / World of chess computers | 3 | 04.08.2005 08:26 |