What language do you wish to use?
Awhile back I wrote a routine in PowerBasic, that communicated with a UCI engine, and was able to feed it a position and then see its analysis, but since the chance of you wanting to code your program in that language is pretty low, the code probably won't help much.
As I recall, the process involves opening a "pipe" and communicating with the engine that way.
You will, of course, have to be familiar with all of the UCI commands/protocols.
Having the source code to Stockfish couldn't hurt either, so downloading that is probably ideal.
This link might also have some info that will help.
I'd be surprised if their wasn't an open source program that you could use as a template. Google will probably help.
Good luck on your project.
Writing Code Against UCI Chess Engine
Thank you for your response. I will likely use c# as I am most familiar with it, but am code agnostic as fas as looking at code examples. I am struggling on where to begin... I will look at your links at let you know what I find :)
I'll look for the code. It's not on my current hard drive, (which is relatively new) but I must have it saved on some backup somewhere.
In the meantime, I found this page and this page, which you should add to your bookmarks. They might help to clear some of the muddy waters.
Thank you much. I found this as well which looked very interesting https://code.google.com/p/officechess/source/browse/trunk/OfficeChess8/EngineInterfaces/UCI/UCI.cs?r=21
I have looked through the documentation and got some very basic things running through the command line. I am struggling with you to get it to show evaluations and multiple lines. Perhaps after a night's sleep I will see something new...
Are you communicating with it, back and forth, at all yet?
For example, are you seeing the readyok and uciok messages, and stuff like that?
I'm guessing no because that's 90% of it. The hard part (for me) was just figuring out how to correctly set up the STDIN and STDOUT pipe commands, so I could "talk" to the engine.
But once that was done, and once I finally figured that out, I was gold, as I recall. Then it was just a matter of reading the documentation and protocols and figuring out how to correctly send a FEN position to it, how to tell it to stop when I didn't want analysis anymore, etc., etc. And all of that was easy.
Alas, this was all awhile ago and I've forgotten all what I did.
I'll have time to look for my code this weekend.
Eric, I wasn't able to find my old code.
HOWEVER, if you go to the PowerBASIC website, and go to the forum section, and enter chess as a keyword, you will find a two-year old discussion that I started back when "I" first was looking into how to do this.
Here's the direct link but I'm not sure if this link will be valid (I had to enter text to prove I wasn't a computer) but you can try:
http://www.powerbasic.com/support/pbforums/showthread.php?t=48073&highlight=chess
The topic is Beginner's question about "pipes." Paul Dixon's example is what initially got me started.
Thanks for your help on this one. I found some C# code which has been really helpful. Thanks for pointing me in the right direction. If I get a little further, which is only a matter of finding the time, I will share what I came up with.
Thanks again!
I'm actually playing around with the same idea, I'm planning to build a game database and analysis tool to store and analyze all the games I play. Could you share where you got the c# code from? I'm just getting started, I've been programming for 17 years, but never used a chess engine before. Thanks.
First try this typical communication with engine itself from inside a windows console. start the engine.exe, then send the following commands, look what happens (see uci protocol for more info):
> uci
> isready
> position startpos
> go infinite
> stop
> quit
This is more or less what chess guis send.
A while ago i wrote some python 3 wrapper around engine-gui communication, a middleware. This worked with babas chess and with chessbase > v11, it didnt work with old chessbase software and it doesnt work with scid (someone really needs to fix scid for windose). it always does work from a console.
the following python 3 sourcecode just prints engine/gui messages to a log file in same dir and then passes through the messages unchanged. it doesnt do other stuff but it is easy to extend. If you want executables, CXFreeze worked for me. To make the module work you need to change the global var ENGINE to fit the path to the engine.exe you are using (i just tested with houdini). To see that it works just call the module from inside a windows console. Try the same commands from above. the output should be the same. Because i use os._exit (sys.exit does not work) the console needs to be closed to see contents of log file, bug fixes are welcome. didnt test it on linux. Good luck and happy code extending. License: free.
The sourcecode (example_uci_wrapper.py):
import sys, os, subprocess, threading, queue, logging
ENCODING = sys.getfilesystemencoding() # needed in some places
# logging
# this is needed as you cant just print() out some stuff in this case,
# because it will be interpreted as gui messages
LOGFILE = 'messages.log'
if os.path.exists(LOGFILE):
os.remove(LOGFILE) # remove logfile from previous session
logging.basicConfig(format='%(message)s',filename=LOGFILE,level=logging.DEBUG)
# thats the connection to the engine
ENGINE = 'houdini-x64.exe' # edit as you need
PROCESS = subprocess.Popen(
os.path.abspath(ENGINE),
universal_newlines = False, # binary io
shell = False, # in my tests it didnt work with True
stdin = subprocess.PIPE,
stdout = subprocess.PIPE
)
class MessageEmitter: # Baseclass for Engine,Gui
def __init__(self):
self.inchannel = None # childclass defines
self.outchannel = None # childclass defines
self.commdirection = None # unelegant. childclass defines
self.queue = queue.Queue()
def enqueue(self):
for message in iter(self.outchannel.readline, b''):
self.queue.put(message)
self.outchannel.close()
class Engine(MessageEmitter):
def __init__(self, process=PROCESS):
super().__init__()
self.inchannel = process.stdin
self.outchannel = process.stdout
self.commdirection = 'gui' # Will be start of line in logging file
class Gui(MessageEmitter):
def __init__(self):
super().__init__()
# for detatch() see (pythondocs)/library/sys.html#sys.stderr
self.inchannel = sys.stdout.detach()
self.outchannel = sys.stdin.detach()
self.commdirection = 'eng' # Will be start of line in logging file
def read(source):
try:
message = source.queue.get_nowait()
# message = source.queue.get(timeout=.1)
except queue.Empty:
return None
else:
return message
def send(target, *messages, encoding=ENCODING):
for message in messages:
logging.debug(
target.commdirection + '\t' + str(message.strip(), encoding)
)
target.inchannel.write(message)
target.inchannel.flush()
def quit(exception=None):
if exception is not None:
logging.debug('***Exception***' + exception)
send(engine, b'quit')
# os._exit should not be used in python code because
# it doesnt do cleanup actions
# but i didnt get sys.exit to just end the program
# (guess its because of the threads im using)
# this may mean you have to close the console before beeing able
# to see changes in logfile.
os._exit(0)
def collect(messageemitter):
t = threading.Thread(target=messageemitter.enqueue)
t.setDaemon(True)
t.start()
def communicate(engine,gui):
enginemessage = read(engine)
if enginemessage is not None:
# do stuff with enginemessage here
send(gui, enginemessage)
guimessage=read(gui)
if guimessage is not None:
if guimessage.startswith(b'quit'):
quit()
# do stuff with guimessage here
send(engine, guimessage)
threading.Timer(0,communicate,args=(engine,gui)).start()
engine,gui = Engine(),Gui()
# Collect engine/gui messages, line by line, using threads.
# Put them into queues
collect(engine)
collect(gui)
# communicate reads the messages from the queues,
# if there are messages.
# This is necessary because uci protocol is chaotic.
# everyone sends messages when he wants to.
# you just can rely to "readyok" as answer to "isready"
# and to "bestmove .." as last enginemessage sent if
# gui sends "stop" to stop a "go infinite"
communicate(engine,gui)
nilshero wrote:
First try this typical communication with engine itself from inside a windows console. start the engine.exe, then send the following commands, look what happens (see uci protocol for more info):
> uci> isready> position startpos> go infinite> stop> quit
This is more or less what chess guis send.
A while ago i wrote some python 3 wrapper around engine-gui communication, a middleware. This worked with babas chess and with chessbase > v11, it didnt work with old chessbase software and it doesnt work with scid (someone really needs to fix scid for windose). it always does work from a console.
the following python 3 sourcecode just prints engine/gui messages to a log file in same dir and then passes through the messages unchanged. it doesnt do other stuff but it is easy to extend. If you want executables, CXFreeze worked for me. To make the module work you need to change the global var ENGINE to fit the path to the engine.exe you are using (i just tested with houdini). To see that it works just call the module from inside a windows console. Try the same commands from above. the output should be the same. Because i use os._exit (sys.exit does not work) the console needs to be closed to see contents of log file, bug fixes are welcome. didnt test it on linux. Good luck and happy code extending. License: free.
The sourcecode (example_uci_wrapper.py):
import sys, os, subprocess, threading, queue, loggingENCODING = sys.getfilesystemencoding() # needed in some places# logging# this is needed as you cant just print() out some stuff in this case,# because it will be interpreted as gui messagesLOGFILE = 'messages.log'if os.path.exists(LOGFILE): os.remove(LOGFILE) # remove logfile from previous sessionlogging.basicConfig(format='%(message)s',filename=LOGFILE,level=logging.DEBUG)# thats the connection to the engineENGINE = 'houdini-x64.exe' # edit as you needPROCESS = subprocess.Popen( os.path.abspath(ENGINE), universal_newlines = False, # binary io shell = False, # in my tests it didnt work with True stdin = subprocess.PIPE, stdout = subprocess.PIPE)class MessageEmitter: # Baseclass for Engine,Gui def __init__(self): self.inchannel = None # childclass defines self.outchannel = None # childclass defines self.commdirection = None # unelegant. childclass defines self.queue = queue.Queue() def enqueue(self): for message in iter(self.outchannel.readline, b''): self.queue.put(message) self.outchannel.close()class Engine(MessageEmitter): def __init__(self, process=PROCESS): super().__init__() self.inchannel = process.stdin self.outchannel = process.stdout self.commdirection = 'gui' # Will be start of line in logging fileclass Gui(MessageEmitter): def __init__(self): super().__init__() # for detatch() see /library/sys.html#sys.stderr self.inchannel = sys.stdout.detach() self.outchannel = sys.stdin.detach() self.commdirection = 'eng' # Will be start of line in logging filedef read(source): try: message = source.queue.get_nowait()# message = source.queue.get(timeout=.1) except queue.Empty: return None else: return messagedef send(target, *messages, encoding=ENCODING): for message in messages: logging.debug( target.commdirection + '\t' + str(message.strip(), encoding) ) target.inchannel.write(message) target.inchannel.flush()def quit(exception=None): if exception is not None: logging.debug('***Exception***' + exception) send(engine, b'quit') # os._exit should not be used in python code because # it doesnt do cleanup actions # but i didnt get sys.exit to just end the program # (guess its because of the threads im using) # this may mean you have to close the console before beeing able # to see changes in logfile. os._exit(0)def collect(messageemitter): t = threading.Thread(target=messageemitter.enqueue) t.setDaemon(True) t.start()def communicate(engine,gui): enginemessage = read(engine) if enginemessage is not None: # do stuff with enginemessage here send(gui, enginemessage) guimessage=read(gui) if guimessage is not None: if guimessage.startswith(b'quit'): quit() # do stuff with guimessage here send(engine, guimessage) threading.Timer(0,communicate,args=(engine,gui)).start()engine,gui = Engine(),Gui() # Collect engine/gui messages, line by line, using threads.# Put them into queuescollect(engine)collect(gui)# communicate reads the messages from the queues,# if there are messages.# This is necessary because uci protocol is chaotic.# everyone sends messages when he wants to.# you just can rely to "readyok" as answer to "isready"# and to "bestmove .." as last enginemessage sent if# gui sends "stop" to stop a "go infinite"communicate(engine,gui)
What The... You must be very smart, I don't Understand.
Well, at least i dont reprint python code unformatted. Please delete and repost your post without quoting my full text.
In C#, you can use Process to communicate with other console-based programs. You just need to find the documentation for the UCI protocol, and create the appropriate wrapper for it.
If anyone is still interested in communincating with a chess engine via UCI, this example Python script worked for me, running from Eclipse with PyDev:
It's utterly rudimentary code which you may want to tidy up and extend, but it provides the essentials to get you up and running, talking to the engine and experimenting with the UCI protocol.
Once I set the engine path, the sample code worked the first time and it was obvious where and how to enter new UCI commands. The code is so straightforward I imagine a programmer with only passing familiarity with Python could use it.
nilshero's work is a fine model for gui/engine communication but it's technical overkill for programmers like the OP who are just trying to pry some candidate moves and scores out of a chess engine. You don't need or want a gui layer for that.
nilshero's code is also written in Python 3, which is the latest and greatest version of Python, but not compatible with Python 2, which is what most people have installed on their systems.
The C# code some posters have linked is OK but doesn't stand alone. Half the code is devoted to converting integer board coordinates from a global data object in a different module to algebraic notation.
If you're a decent C# programmer, you can build an app which will call this engine interface code. Or you can download the whole project solution and maybe it will compile and run without much trouble. But it's not sample code you can drop into your programming environment and start jamming with.
Dear EricFleet,
Did you finally find any working c++ code that uses Stockfish libraries? It would be indeed very useful to see some examples and learn from them.
Thanks, look forward to hearing from you.
Randy
Because the OP wants the best 3 moves for every position, the correct sequence of commands to send to the engine would be:
uci
isready
setoption name MultiPV value 3
ucinewgame
position fen FEN1
go movetime 1000
ucinewgame
position fen FEN2
go movetime 1000
...
quit
This assumes 1 sec analysis per move ('1000'), while FEN1, FEN2, ... would be the FENs for the positions you want to analyze. The engine would reply with 'bestmove ...' after the 1 sec expires, and you would have to capture the lines
info multipv N depth D score S cp pv ....
last send before it. (Where N, D, S are numbers, N = 1, 2 or 3 for the best, 2nd and 3rd-best moves, and the order of the items on the line could in fact be different or missing, depending on the particular engine.) The move you are interested in would be the first move after "pv".
I would like to develop a simple program to do chess analysis with Stockfish. I would simply like to programmatically pass a position to the program and get the top three candidate moves along with an evaluation.
I know it can be done, but I dont know how to write against a UCI interface. Can anyone point me in the right direction?