This is a demonstration of a python program that runs the chess engine Stockfish and uses the Chessboard library to manage the board. You can run it on your PC from Python and it will beat you at Chess (it plays by default at its maximum ELO of around 2600).
This program can be used as the foundation for driving a chessboard or other device by replacing the simple keyboard entry of moves with communication with a device.
This program will only run under Python 2.7 with the right libraries installed. Please don’t try running it on an Arduino, which of course does not support Python or Stockfish. It will run on most PCs and the Raspberry Pi
TestPython Stockfish.zip
This zipfile contains everything you need to run the test of Stockfish from Python on 64 bit Windows using a simple text interface. It assumes you have Python 2.7 installed.
If you want to run it on a different machine you need to get the appropriate version of Stockfish. (It runs on the Raspberry Pi, sudo apt-get install stockfish)
Put all these files in a directory and run the Python program Maxchessdemo.py.
The easiest way from Windows is to Right Click and then choose “Edit with Idle” Then from Idle: “Run Module”
You will get a lot of start up stuff generated by Stockfish, including some errors because my code options are out of date.
It will stop with the message:
“Enter a board message:”
You enter a move by typing, for example “me2e4” ie Move E2 to E4 and then go from there, see example output in TestOutput.txt
Note:
The version of stockfish here is the 64 bit version, if you have a 32 bit machine, the you will need to get that from the Stockfish site.
If you use a different version of Stockfish, make sure the program name in Maxchessdemo.py is changed.
Modifying the Chess Program
This is a base program that assumes you play white. If you want the computer to play black you can modify it to send a blank move “” to Stockfish.
The program below contains this change. If you type ma9a9 as your first move the computer plays white. This is just an example of a simple change. If you type ma9a9 at any time other than the first move of a game it crashes.
Remember that the base program is just to illustrate how to manage the chess engine, anything else you need to add yourself.
Stockfish Python Program Listing:
#
#This program plays chess using Stockfish the open source chess engine, using the ChessBoard library to manage the board.
# it is written in Python 2.7 because chessboard is. Python 3 might work but I havn’t tested it.
# it assumes you have got the python libraries chessboard, subprocess and time
# it assumes stockfish is looded in the python directory.
# In this program the routines Getboard and Sendboard get a move in the for me2e4, by simple keyboard input. In the working system these get replaced by serial coms with the board
# it runs Stockfish using a list of moves not FEN. I couldn’t get the FEN routines to work in ChessBoard fails after h2 h4 so #’d out
# Instead they use a move list, which is less eligent, but works.
# See full working system at : www.chess.fortherapy.co.uk
# to start try running the program and type me2e4 at the first prompt.
# This program is built using lots of examples from around the web, so do what you want with it. A credit to www.chess.fortherapy.co.uk would be nice.
# initiate chessboard
from ChessBoard import ChessBoard
import subprocess, time
maxchess = ChessBoard()
# initiate stockfish chess engine
engine = subprocess.Popen(
‘stockfish-32.exe’, CHANGE THIS LINE TO MATCH FILENAME YOU HAVE
universal_newlines=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,)
def get():
# using the ‘isready’ command (engine has to answer ‘readyok’)
# to indicate current last line of stdout
stx=””
engine.stdin.write(‘isready\n’)
print(‘\nengine:’)
while True :
text = engine.stdout.readline().strip()
if text == ‘readyok’:
break
if text !=”:
print(‘\t’+text)
if text[0:8] == ‘bestmove’:
return text
def sget():
# using the ‘isready’ command (engine has to answer ‘readyok’)
# to indicate current last line of stdout
stx=””
engine.stdin.write(‘isready\n’)
print(‘\nengine:’)
while True :
text = engine.stdout.readline().strip()
#if text == ‘readyok’:
# break
if text !=”:
print(‘\t’+text)
if text[0:8] == ‘bestmove’:
mtext=text
return mtext
def getboard():
“”” gets a text string from the board “””
btxt = raw_input(“\n Enter a board message: “).lower()
return btxt
def sendboard(stxt):
“”” sends a text string to the board “””
print(“\n send to board: ” +stxt)
def newgame():
get ()
put(‘uci’)
get ()
put(‘setoption name Skill Level value ‘ +skill)
get ()
put(‘setoption name Hash value 128’)
get()
put(‘setoption name Best Book Move value true’)
get()
put(‘setoption name OwnBook value true’)
get()
put(‘uci’)
get ()
put(‘ucinewgame’)
maxchess.resetBoard()
fmove=””
return fmove
def bmove(fmove):
“”” assume we get a command of the form ma1a2 from board”””
fmove=fmove
# Get a move from the board
brdmove = bmessage[1:5].lower()
# now validate move
# if invalid, get reason & send back to board
# maxchess.addTextMove(move)
if maxchess.addTextMove(brdmove) == False :
etxt = “error”+ str(maxchess.getReason())+brdmove
maxchess.printBoard()
sendboard(etxt)
return fmove
# elif valid make the move and send Fen to board
else:
maxchess.printBoard()
# maxfen = maxchess.getFEN()
# sendboard(maxfen)
# remove line below when working
raw_input(“\n\nPress the enter key to continue”)
print (“fmove”)
print(fmove)
print (“brdmove”)
print(brdmove)
fmove =fmove+” ” +brdmove
cmove = “position startpos moves”+fmove
print (cmove)
# if fmove == True :
# move = “position startpos moves “+move
# else:
# move =”position fen “+maxfen
# put(‘ucinewgame’)
# get()
put(cmove)
# send move to engine & get engines move
put(“go movetime ” +movetime)
# time.sleep(6)
# text = get()
# put(‘stop’)
text = sget()
print (text)
smove = text[9:13]
hint = text[21:25]
if maxchess.addTextMove(smove) != True :
stxt = “e”+ str(maxchess.getReason())+move
maxchess.printBoard()
sendboard(stxt)
else:
temp=fmove
fmove =temp+” ” +smove
stx = smove+hint
sendboard(stx)
maxchess.printBoard()
# maxfen = maxchess.getFEN()
print (“computer move: ” +smove)
return fmove
def put(command):
print(‘\nyou:\n\t’+command)
engine.stdin.write(command+’\n’)
# assume new game
print (“\n Chess Program \n”)
skill = “10”
movetime = “6000”
fmove = newgame()
while True:
# Get message from board
bmessage = getboard()
# Message options Move, Newgame, level, style
code = bmessage[0]
# decide which function to call based on first letter of txt
fmove=fmove
if code == ‘m’: fmove = bmove(fmove)
elif code == ‘n’: newgame()
elif code == ‘l’: level()
elif code == ‘s’: style()
else : sendboard(‘error at option’)
THIS PROGRAM HAS SEVERAL ERRORS IN “RETURN”,”BREAK”,”ELSE” CAN ANYONE HELP ME TO SOLVE THAT
Amal, The program does work, but you need to make sure you have all the modules like chessboard installed and loaded in the right directories, see the comments section. You also need the Stockfish installed in the Python directory with the same file name in the code. This program is written in Python 2.7. I notice you hope to write your chess program on an Arduino. Obviously this program will not run on an Arduino as it doesn’t support Python. I ran it on a Windows PC and on an RPI.
IAM DOING A PROJECT SIMILAR TO THIS USING AN ARDUINO
Best of luck, I don’t think you will be able to get Stockfish to run on an Arduino, if you do I’d love to know and it certainly will not run chessboard or Python. You’d be better off with a Raspberry Pi to run the chess engine.
Hi where do I get the ChessBoard library?
following link donesnt work
http://www.arainyday.se/projects/python/ChessBoard/ChessBoard_2.05.zip
Klaus, ChessBoard is no longer supported by the owner and has been removed from his site.
However he has allowed me to put a copy here for you to download. ChessBoard
Max
Can you please better explain where to copy the library and stockfish
which file in which folder
and there are no links where to download the library
which file of stockfish (open source code?) must be copied in which folder
phyton is installed in /usr/bin and I cant put any files in this folder
Klaus,
from debian on the Raspberry pi just type:
sudo apt-get install stockfish
it puts all the right stuff in the right place
Hi Max,
First of all, great work buddy !!!
I am trying to replicate this and I am facing issue with the Python code. I have built the chess board with Reed Limit switches and now trying to setup the Python. I am new to Python and I am not able to run this code. I believe the intendation I am doing is wrong and that is causing the problem. It would be great if you could share the .py file.
Thanks and have a great day.
– Deepak
Deepak
I have now added the program file and all the other files in a zip file at the top of this page. I have tested it on an old DEll I have and it works.
I hope this helps
Hi Max,
Just to tell you that I tested your code from the raspberry I just received and everything worked perfectly. Many Thanks
Olivier
Hello, thanks for this. I’m building a robot arm to play chess and I’m trying to use this for it. I got it all working in Windows but I just got a Raspberry Pi and I’d like to get it working on that too.
I did sudo apt-get install stockfish
‘stockfish-32.exe’, CHANGE THIS LINE TO MATCH FILENAME YOU HAVE
What do I change this line to?
Sorry my first experience of Raspberry Pi, love it though, very cool.
Ok so I figured it out, its simply ‘stockfish’
# initiate stockfish chess engine
engine = subprocess.Popen(
‘stockfish’,
universal_newlines=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,)
One other question, I can use stockfish’s response to move my robot arm but there is no way to tell if the computer is taking a piece, the arm must know if it needs to remove a piece before doing the move. Any idea how to do this check?
I just solved that one, by adding a function to the chessboard script that returns whats on the board before the chessboard gets updated. Now I can make the arm remove the piece if its a taking move.
Next step is to learn servoblaster to control the robot arm I designed and 3D printed 🙂
Dom, Looks like you are solving all your own problems as you go!. Looks like a fantastic project, please keep me updated. What robot arm/ movement system are you using?
Its a little bit primitive at the moment, I used Cinema4D to design it then a Mendel90 3d printer to print the parts. I had to keep reprinting parts with design changes, so I went for functionality over looks, it may get a redesign once it works.
I used 4 x MG996R servos and 1 x 9g servo for the gripper. I started using arduino to control the servo’s but got lots of jitter and it wouldn’t do small movements accurately. I then used the Rasberry Pi and I was astounded by how much better and accurate it was.
I’m hopefully getting it all wired up to the Pi tonight. In the end I used PIGPIO instead of Servoblaster to control the servos as the python module is easy to use. I also use an ADXL345 accelerometer to control the gripper to ensure its always level. This worked on the arduino and I think I’ve got all the code to transfer it to the Pi. I’m just starting researching the board and reed switches. I’ll use the arduino for that. Thanks for all your info here, really helpful 🙂
Here is a video using the arduino and ADXL345 to keep it level, the gripper isn’t attached
http://www.youtube.com/watch?v=ao3sIZIkeSI
Here is the gripper, its my own design, it may need a a few tweaks but not bad for a first attempt
https://www.youtube.com/watch?v=JE6RPAG-Xhc
Looks promising, keep in touch
I realised my previous robot arm design was flawed. I looked into robot kits and came up with a new design and 3D printed it. I also used better servo’s as the cheap ebay ones wouldn’t do small movements very well.
http://www.youtube.com/watch?v=Ncoqzbk5wuA
This is a very basic test to pick something up. I need to do a lot more programming to make each servo move at the same time and will have more steps for a more elegant motion.
Ok getting there! Still needs a lot of tweaks on the movement. its a bit spring but it needs the loads bearing springs to support the arm.
https://www.youtube.com/watch?v=6myJSgHUDUs
Greetings.
When accidentally entering an invalid move (i.e. me2e8), I am kicked out to a “>>>” prompt. How do I continue with where I left off without restarting the game?
Jerome, the code is just an example of how to run stockfish it contains some error handling, but it isn’t a finished system.You need to write your own interface for user verification and error handling.
Thank you Max,
the program works great! Great help for an absolute beginner and a nice platform to start building from…
Just got it to run on my Mac, next step is to put in in RPi! I’m also trying to code some text-to-speech functionality. Thanks for the head-start.
Good morning Max!
I would first like to congratulate you on your excellent work.
I am building a robot that plays chess, using magnets and hall sensors to recognize the pieces, I also use a mechanical arm that I am designing, I also use a rasperbarry pi and an arduino.
To access Stockfish I use the TestPython-Stockfish files and am making changes to the code as needed.
I’m building this robot to market (sell my robot) and I want to do it honestly.
So I would like to know if I can publish a ChessBoard version with my changes under the GNU license giving you the credits due from the library. So anyone can have access to the source code of this new version of ChessBoard.
The person only needs to make the arduino code and assemble the hardware, in case the person wanted to do a project just like mine.
I want to know if you’re against it? I will respect your decision! Thank you!
Note: I am from Brazil and I am using Google Translate and may have inconsistency in the text.
Flávio, I have no objection to you giving away the software as long as the GNU licence persists and you make new versions available. However Chessboard is not mine. ChessBoard was written by John Eriksson (wmjoers) so you need to track him down (his Email is in the Readme file) and ask him.However, in the Readme file that accompanies Chessboard it says: You are free:
* to copy, distribute, display, and perform the work
* to make derivative works
* to make commercial use of the work
Under the following conditions:
===============================
***Attribution***
You must attribute the work in the manner specified by the author or licensor:
* For any reuse or distribution, you must make clear to others the license terms of this work.
So you decide.
Good morning Max!
Thanks for the clarification about the library.
As soon as I finish my ChessBoard changes, I’ll send the link to my GNU version and another Youtube link with the robot running.
Appreciate your attention! Thank you!
Hi Max, Can you tell me How can I change game level? Please
Regards and congratulations
Fabro, The game level, ie skill level of Stockfish is set using the UCI interface and setting the option “Skill Level”, so you will see the line put(‘setoption name Skill Level value ‘ +skill) in the example code, with skill being set to 10 later on. Skill can be in the range 0-20, 20 being the strongest. See Stockfish parameters and UCI info.
I spent over a month trying to get the python code to read the 64 reed switches with no luck. Can someone please give me a source code or help. thanks.
–dooby kalisheeno
Dooby,
my suggestion is that you start by building a test 3×3 reed matrix as described on the NOX pages.
This includes full instructions on hardware build and software download. If you do not want to build the full project you can just build a simple 3×3 reed switch circuit on a bit of board and then test it using the noxreed.py program tests the reed switches.
The 8×8 is just a bigger version.
Your program is the best you have seen, it is short, simple and works perfectly on windows 7 and 10. You are a great programmer.
I have adapted some things, and I only get him to work playing me with white (ex: me first move intro ‘me2e4’). How could I get him to work playing black? For example, introducing me7e6 as the first movement.
Thank you so much for everything.
Regards
Pedro, if you go to the the code page you will see that I have added a modified version that allows you to play black.
Hello,
In your example listing above you have the following line:
‘stockfish-32.exe’, CHANGE THIS LINE TO MATCH FILENAME YOU HAVE
I’m trying to get this to run on a Raspberry Pi, I’ve installed stockfish using apt-get…
So what should the above line read? I’m rather new to Linux and have no idea where things go or how to find them.
Thanks.
just changing it to stockfish should work, see comments above
Great!
Thanks a lot.
i am getting this error
SyntaxError: Missing parentheses in call to ‘print’. Did you mean print(” +—————–+”)?
>>>
To Whom It May Concern: I have ported chessboard.py, chessclient.py and Max’s script to Python 3.
There are very little lines to change into. Here it goes:
quote
ChessClient.py in Python3
————–
array mousePos must be converted to int
lines 95-105
if not chess.isGameOver():
if event.type == MOUSEMOTION:
mx = event.pos[0]
my = event.pos[1]
mousePos[0] = int(mx/60) # int(float coord)
mousePos[1] = int(my/60) # int(float coord)
elif event.type == MOUSEBUTTONDOWN:
ChessBoard.py class
————-
change from every line (there are three or four) the old method has_key
In Python 3 must be, i.e.:
#if specialMoves.has_key(toPos): #Python 2
if toPos in specialMoves: #Python 3
Maxchessdemobfirst.py
———————
In python 3:
The subprocess must be buffered to zero (I think so)
I have done in this way (I did not want to patch too much things, such stderr, etc.)
engine = subprocess.Popen(
‘stockfish15.exe’,
universal_newlines=True,
bufsize=0,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,)
Then stockfish throws a lot of calculations that start with “info etc…..”
To avoid all of this we can add this lines to sget() function:
if text[0:4] == ‘info’:
continue
I think in Stockfish the book options are not allowed.
The functions level() and style() seem not defined.
aq quick fix it would be:
def level():
level = input(“\n\nSkill of calculation must be between 0 and 20 : “)
put(‘setoption name Skill Level value ‘ +level)
get ()
def style():
“””
“UCI command is: option name Style type combo default Normal var Solid var Normal var Risky\n”
“””
put(“setoption name Style value Risky”)
get ()
Also I would add a “go depth …” command to adjust the level of calculation, but it isn’t my script.
unquote
I hope this can help. Regards