You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have written a little script that converts chess notation into valid moves for stockfish.py. Maybe someone can refine it a bit and put it in?
The goal of my implementation wasn't to make it correct but to make it convenient for user entry. But I'm sure it can be adopted to make it more rigid. For example I tried to remove capitalization requirements, but that resulted in only bishops needing to be capitalized to make it work. If you want to be more stringent you could enforce all piece descriptions.
The code should be pretty self explanatory, but if you have questions, feel free to ask.
Here's a brief overview
The function will take the stockfish board, a move string in chess notation and a color argument.
The color argument, when set to not False will output messages in color. It is not important for this function for the purpose of translating chess notation to stockfish notation. It is there because in my program whenever something is referenced to one side or another, I use the colored library to provide colored text on the terminal, in this case for the returned error messages.
It will either return a valid move, or an error message.
See a working example here: https://github.com/FalcoGer/pychess but you might have to adjust the stockfish path.
Feel free to take any code you want from that.
classPlayer:
BLACK="Black"WHITE="White"defgetNTM(stockfish: Stockfish) ->str:
returnPlayer.WHITEif (stockfish.get_fen_position().find(" w ") >0) elsePlayer.BLACKdefresolveMove(stockfish: Stockfish, move: str, color: bool=True) ->str:
# turn shorthand notation into valid moves for stockfish# "e4" = pawn to e4# "xe4" = pawn captures e4# "bxc5" = pawn in b file captures c5# "Bxc5" = bishop captures c5# "Bbxc5" = bishop in b file captures c5 (because another bishop could also capture c5)# "B3xd4" = bishop from rank 3 captures d4 (because another bishop from the same file could also capture)# "ra6" = rook to a6# "rfa6" = rook in f file (f6) to a6# "qxf4" = queen captures f4# "d2d1q" = pawn from d2 to d1 turns into a queen# "d2xe1q" = pawn from d2 captures e1 and turns into a queenmove=move.replace(" ", "").replace("-", "")
ntm=getNTM(stockfish)
iflen(move) ==0:
return"Empty move"ifregex.match("^(?:[a-h][1-8]){2}[qrnb]$", move.lower()):
move=move.lower()
ifstockfish.is_move_correct(move):
returnmoveelse:
return"Invalid move."else:
# castlingif (move.lower() =='oo'):
# castle king side# need to check if it's actually a king there as another piece could also have a valid move.ifntm==Player.WHITEandstockfish.get_what_is_on_square("e1") ==Stockfish.Piece.WHITE_KING:
move="e1g1"elifntm==Player.BLACKandstockfish.get_what_is_on_square("e8") ==Stockfish.Piece.BLACK_KING:
move="e8g8"else:
move="Invalid"ifstockfish.is_move_correct(move):
returnmoveelse:
return"Can not castle king side."elif (move.lower() =='ooo'):
# castle queen sideifntm==Player.WHITEandstockfish.get_what_is_on_square("e1") ==Stockfish.Piece.WHITE_KING:
move="e1c1"elifntm==Player.BLACKandstockfish.get_what_is_on_square("e8") ==Stockfish.Piece.BLACK_KING:
move="e8c8"else:
move="Invalid"ifstockfish.is_move_correct(move):
returnmoveelse:
return"Can not castle queen side."# resolve the rest with regex# do not allow lower case 'b' in first group because it conflicts with second group# allow other lower case letters for conveniencematch=regex.match("^([RNBKQrnkq]?)([a-h]?)([1-8]?)(x?)([a-h][1-8])(=?[RNBKQrnbkq]?)$", move)
ifmatch==None:
return"Not a valid move string."groups=match.groups()
piece=None# resolve piece classiflen(groups[0]) ==0:
piece=Stockfish.Piece.WHITE_PAWNifntm==Player.WHITEelseStockfish.Piece.BLACK_PAWNelse:
ifgroups[0].lower() =='r':
piece=Stockfish.Piece.WHITE_ROOKifntm==Player.WHITEelseStockfish.Piece.BLACK_ROOKelifgroups[0] =='B': # bxc6 is a pawn from b, not a bishop.piece=Stockfish.Piece.WHITE_BISHOPifntm==Player.WHITEelseStockfish.Piece.BLACK_BISHOPelifgroups[0].lower() =='n':
piece=Stockfish.Piece.WHITE_KNIGHTifntm==Player.WHITEelseStockfish.Piece.BLACK_KNIGHTelifgroups[0].lower() =='k':
piece=Stockfish.Piece.WHITE_KINGifntm==Player.WHITEelseStockfish.Piece.BLACK_KINGelifgroups[0].lower() =='q':
piece=Stockfish.Piece.WHITE_QUEENifntm==Player.WHITEelseStockfish.Piece.BLACK_QUEENelse:
returnf"Can not determine piece to move ('{groups[0]}')."# resolve source filesrc_file=Noneiflen(groups[1]) ==1:
src_file=groups[1]
# resolve source ranksrc_rank=Noneiflen(groups[2]) ==1:
src_rank=groups[2]
# resolve captureisCapture=groups[3] =='x'# pawn conversionturnsInto=groups[5].lstrip('=')
# resolve dstdst=groups[4]
# resolve srcsrc=None# find srcifsrc_file!=Noneandsrc_rank!=None:
src=f"{src_file}{src_rank}"else:
possibleSrc= []
# run through all the squares and check all the pieces if they can move to the squareforfileinrange(ord('a'), ord('h') +1):
file=chr(file)
ifsrc_file!=Noneandsrc_file!=file:
continueforrankinrange(1,8+1):
rank=str(rank)
ifsrc_rank!=Noneandsrc_rank!=rank:
continuesrc=f"{file}{rank}"ifpiece==stockfish.get_what_is_on_square(src) andstockfish.is_move_correct(f"{src}{dst}{turnsInto}"):
possibleSrc.append(src)
iflen(possibleSrc) ==1:
src=possibleSrc[0]
eliflen(possibleSrc) ==0:
pieceDesc=str(piece).replace("Piece.", "")
ifcolor:
pieceDesc=colored(pieceDesc, color=ColorConst.WHITE_PIECEifntm==Player.WHITEelseColorConst.BLACK_PIECE, on_color=ColorConst.FEN_BG, attrs=['bold'])
ifsrc_rank!=Noneandsrc_file==None:
pieceDesc=pieceDesc+f" from rank {src_rank}"elifsrc_rank==Noneandsrc_file!=None:
pieceDesc=pieceDesc+f" from file {src_file}"# no need to check for both since that is already covered above# no need to check for neither since no additional description is neededreturnf"No {pieceDesc} can go to {dst}"else:
pieceDesc=str(piece).replace("Piece.", "")
ifcolor:
pieceDesc=colored(pieceDesc, color=ColorConst.WHITE_PIECEifntm==Player.WHITEelseColorConst.BLACK_PIECE, on_color=ColorConst.FEN_BG, attrs=['bold'])
returnf"Could not determine which {pieceDesc} you want to move to {dst}"# build stockfish movemove=f"{src}{dst}{turnsInto}"# check if resolved move is indeed a captureifstockfish.is_move_correct(move):
if ((isCaptureandturnsInto!=''andstockfish.get_what_is_on_square(dst) ==None) or (isCaptureandturnsInto==''andstockfish.will_move_be_a_capture(move) ==Stockfish.Capture.NO_CAPTURE)):
return"Move is no Capture"elif (notisCaptureandturnsInto!=''andstockfish.get_what_is_on_square(dst) !=None) or (notisCaptureandturnsInto==''andstockfish.will_move_be_a_capture(move) !=Stockfish.Capture.NO_CAPTURE):
print("Warning: Move results in a capture, but capture was not indicated by the move string.")
returnmovereturn"Invalid Move"
The text was updated successfully, but these errors were encountered:
Hi, thanks for this - I think going from human notation --> stockfish notation (and the other way around) would be a nice feature to add. I can definitely get started on including this for the library, but are you sure you don't want to make the PR? It's quite a bit of work you've done here, and I doubt I would be modifying much.
Hello, this project is no longer maintained in this repo but on this fork. (For more information about this please look here).
Because there is an associated PR, there is probably no need to transfer this issue or create a proxy issue. But please look at the other repo for updates on this
I have written a little script that converts chess notation into valid moves for stockfish.py. Maybe someone can refine it a bit and put it in?
The goal of my implementation wasn't to make it correct but to make it convenient for user entry. But I'm sure it can be adopted to make it more rigid. For example I tried to remove capitalization requirements, but that resulted in only bishops needing to be capitalized to make it work. If you want to be more stringent you could enforce all piece descriptions.
The code should be pretty self explanatory, but if you have questions, feel free to ask.
Here's a brief overview
The function will take the stockfish board, a move string in chess notation and a color argument.
The color argument, when set to not False will output messages in color. It is not important for this function for the purpose of translating chess notation to stockfish notation. It is there because in my program whenever something is referenced to one side or another, I use the colored library to provide colored text on the terminal, in this case for the returned error messages.
It will either return a valid move, or an error message.
See a working example here: https://github.com/FalcoGer/pychess but you might have to adjust the stockfish path.
Feel free to take any code you want from that.
The text was updated successfully, but these errors were encountered: