Code Monkey home page Code Monkey logo

stockfish's People

Contributors

2kofawsome avatar aaadamm avatar guidopetri avatar hitecherik avatar janrnc avatar johndoknjas avatar kieferro avatar mickkn avatar vivekthazhathattil avatar zhelyabuzhsky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stockfish's Issues

Stockfish crashes on invalid position instead of error mesasge

When stockfish is given a position where both kings are in check, such as 1q2nB2/pP1k2KP/NN1Q1qP1/8/1P1p4/4p1br/3R4/6n1/ w, stockfish will simply crash. Is there a way to instead of crashing throwing an error message, as then it would be possible to use a try: except: statement to filter out these positions?

CP evaluation unit test too lenient

In your source code for the CP evaluation test, the assertion is far too lenient. Just checking if it is above zero allows for large scope of evaluation variance. I was expecting it to test for one single hard value.

take longer time compare with chess module

stockfish python module take longer time compare with chess module using the same stockfish version

can compare my code using stockfish python module on #94
with

import chess
import chess.pgn
import time
from IPython.display import display, HTML, clear_output

def engine_analyse(app_path, board, nodes):
    #engine = chess.engine.SimpleEngine.popen_uci(app_path)
    #info = engine.analyse(board, chess.engine.Limit(time = 9.9, depth = 9, 
    #                                                nodes = nodes, mate = 9) )
    #engine.quit()
    with chess.engine.SimpleEngine.popen_uci(app_path) as engine:
        info = engine.analyse(board, chess.engine.Limit(time = 9.9, depth = 9, 
                                                        nodes = nodes, mate = 9) )
    clear_output(wait = True)
    return info

def stockfish_analyse(board):
    app_path = "engine/stockfish"
    nodes = 9
    info = engine_analyse(app_path, board, nodes)
    return info

def who(player):
    return "White" if player == chess.WHITE else "Black"

def display_board(board, use_svg):
    if use_svg:
        return board._repr_svg_()
    else:
        return "<pre>" + str(board) + "</pre>"

def play_pgn(file_pgn, analyse, sleep = 9.9, visual = "svg"):
    """
    visual: "simple" | "svg" | None
    """
    use_svg = (visual == "svg")
    pgn = open(file_pgn)
    read_game = chess.pgn.read_game(pgn)
    read_game_mainline_moves = read_game.mainline_moves()
    board = read_game.board()
    game = chess.pgn.Game()

    try:
        for uci in read_game_mainline_moves:
            board.push(uci)

            if board.is_checkmate():
                html = """
                <table>
                <tr>
                <th rowspan = "7" style = "width:45%%;text-align: center">%s</th>
                <th style = "text-align: left">Board</th>
                <td style = "text-align: left"><pre>%s</pre></td>
                </tr>
                <tr>
                <th style = "text-align: left">Move</th>
                <td style = "text-align: left">UCI : %s</td>
                </tr>
                </table>
                """ % (board._repr_svg_(), board, uci)
            else:
                info = analyse(board)
                if info:
                    score = info['score']
                    info_pv_uci = [info_pv.uci() for info_pv in info['pv'] ]
                    pv = ", ".join(info_pv_uci)
                    nodes = info['nodes']
                    depth = info['depth']
                    info_time = info['time']
                else: 
                    score = ''
                    pv = ''
                    nodes = ''
                    depth = ''
                    info_time = ''
                html = """
                <table>
                <tr>
                <th rowspan = "12" style = "width:45%%;text-align: center">%s</th>
                <th style = "text-align: left">Board</th>
                <td style = "text-align: left"><pre>%s</pre></td>
                </tr>
                <tr>
                <th style = "text-align: left">Move</th>
                <td style = "text-align: left">UCI : %s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Score</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">PV</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Depth</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Nodes</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Time</th>
                <td style = "text-align: left">%s</td>
                </tr>
                </table>
                """ % (board_stop, board, uci, score, pv, depth, nodes, info_time)

            if visual is not None:
                if visual == "svg":
                    clear_output(wait = True)

                display(HTML(html) )

                if visual == "svg":
                    time.sleep(sleep)

    except KeyboardInterrupt:
        msg = "Game Interrupted!"
        return (msg, board)

    if board.is_checkmate():
        msg = "Checkmate : " + who(not board.turn) + " Wins!"
    else:
        msg = "Draw"
    
    if visual is not None:
        print(msg)
        print('PGN File :', file_pgn)

play_pgn("pgn/chess_openings/a/A00 - Amar Gambit.pgn", stockfish_analyse, sleep = 0.0)

when using stockfish module set the parameter to 0 in hope to have faster result
and when using chess python module set the parameter to 9 in hope to have longer

but the result is stockfish python module still get the longer time
tested using default parameter in stockfish python module but still get the longer time

stockfish derivatives not work when analyze pgn

stockfish derivatives (like fairy_stockfish and brainfish) not work when analyze pgn

import chess.pgn
import time
from IPython.display import display, HTML, clear_output
from stockfish import Stockfish

def who(player):
    return "White" if player == chess.WHITE else "Black"

def analyse(engine, fen):
    stockfish = Stockfish(path = engine, depth = 1, 
                          parameters = {'Contempt': 0, 'Debug Log File': '', 'Hash': 0, 
                                        'Min Split Depth': 0, 'Minimum Thinking Time': 10, 
                                        'Move Overhead': 0, 'MultiPV': 0, 'Ponder': 'false', 
                                        'Skill Level': 0, 'Slow Mover': 0, 'Threads': 0, 
                                        'UCI_Chess960': 'false', 'UCI_Elo': 0, 
                                        'UCI_LimitStrength': 'false'} )

    stockfish.set_fen_position(fen)

    evaluation = stockfish.get_evaluation()
    best_move = stockfish.get_best_move(wtime = 0, btime = 0)
    best_move_time = stockfish.get_best_move_time(0)
    top_moves = stockfish.get_top_moves(3)

    info = {}
    info["evaluation"] = evaluation
    info["best_move"] = best_move
    info["best_move_time"] = best_move_time
    info["top_moves"] = top_moves
    return info

def brainfish_analyse(fen):
    info = analyse("engine/brainfish", fen)
    return info

def fairy_stockfish_analyse(fen):
    info = analyse("engine/fairy_stockfish", fen)
    return info

def stockfish_analyse(fen):
    info = analyse("engine/stockfish", fen)
    return info

def play_pgn(file_pgn, analyse, sleep = 9.9, visual = "svg"):
    """
    visual: "simple" | "svg" | None
    """
    use_svg = (visual == "svg")
    pgn = open(file_pgn)
    read_game = chess.pgn.read_game(pgn)
    read_game_mainline_moves = read_game.mainline_moves()
    board = read_game.board()
    game = chess.pgn.Game()

    try:
        for uci in read_game_mainline_moves:
            board.push(uci)

            if board.is_checkmate():
                html = """
                <table>
                <tr>
                <th rowspan = "7" style = "width:45%%;text-align: center">%s</th>
                <th style = "text-align: left">Board</th>
                <td style = "text-align: left"><pre>%s</pre></td>
                </tr>
                <tr>
                <th style = "text-align: left">Move</th>
                <td style = "text-align: left">UCI : %s</td>
                </tr>
                </table>
                """ % (board._repr_svg_(), board, uci)
            else:
                info = analyse(fen)
                if info:
                    evaluation_type = info['evaluation']['type'] if info['evaluation'] else ''
                    evaluation_value = info['evaluation']['value'] if info['evaluation'] else ''
                    best_move = info['best_move']
                    best_move_time = info['best_move_time']
                    top_moves = "<br />".join(str(i).replace('{', '').replace('}', '').replace('\'', '') for i in info['top_moves'] )
                else: 
                    evaluation_type = ''
                    evaluation_value = ''
                    best_move = ''
                    best_move_time = ''
                    top_moves = ''
                html = """
                <table>
                <tr>
                <th rowspan = "11" style = "width:45%%;text-align: center">%s</th>
                <th style = "text-align: left">Board</th>
                <td style = "text-align: left"><pre>%s</pre></td>
                </tr>
                <tr>
                <th style = "text-align: left">Move</th>
                <td style = "text-align: left">UCI : %s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Evaluation</th>
                <td style = "text-align: left">Type : %s<br />Value : %s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Best Move</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Best Move Time</th>
                <td style = "text-align: left">%s</td>
                </tr>
                <tr>
                <th style = "text-align: left">Top Moves</th>
                <td style = "text-align: left">%s</td>
                </tr>
                </table>
                """ % (board._repr_svg_(), board, uci, evaluation_type, 
                       evaluation_value, best_move, best_move_time, top_moves)

            if visual is not None:
                if visual == "svg":
                    clear_output(wait = True)

                display(HTML(html) )

                if visual == "svg":
                    time.sleep(sleep)

    except KeyboardInterrupt:
        msg = "Game Interrupted!"
        return (msg, board)

    if board.is_checkmate():
        msg = "Checkmate : " + who(not board.turn) + " Wins!"
    else:
        msg = "Draw"

    if visual is not None:
        print(msg)
        print('PGN File :', file_pgn)
        print('SVG File :', file_svg)

# choose : stockfish_analyse
# brainfish_analyse, fairy_stockfish_analyse = looping forever 
play_pgn("pgn/chess-play.pgn", stockfish_analyse, sleep = 0.0)

no error occured but the result is not expected (looping forever)

Stockfish .EXE Does Not Run in Background Upon PyInstaller Packaging

I had a look at models.py, and it doesn't seem like it's built to open and run stockfish_<version>.exe in the background, though it does from the PyCharm IDE.

The --noconsole command doesn't seem to apply to dependent executables.

Is there a snippet that one could add to make sure that the executable never displays a console?

cannot import name 'Stockfish' from 'stockfish'

while opening this python file:

from stockfish import Stockfish

stockfish = Stockfish('/Users/zhelyabuzhsky/Work/stockfish/stockfish-9-64')

get a following error:

ImportError: cannot import name 'Stockfish' from 'stockfish'

FR - Include chess notation entry

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.

class Player:
    BLACK = "Black"
    WHITE = "White"

def getNTM(stockfish: Stockfish) -> str:
    return Player.WHITE if (stockfish.get_fen_position().find(" w ") > 0) else Player.BLACK

def resolveMove(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 queen
    move = move.replace(" ", "").replace("-", "")
    ntm = getNTM(stockfish)
    if len(move) == 0:
        return "Empty move"
    if regex.match("^(?:[a-h][1-8]){2}[qrnb]$", move.lower()):
        move = move.lower()
        if stockfish.is_move_correct(move):
            return move
        else:
            return "Invalid move."
    else:
        # castling
        if (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.
            if ntm == Player.WHITE and stockfish.get_what_is_on_square("e1") == Stockfish.Piece.WHITE_KING:
                move = "e1g1"
            elif ntm == Player.BLACK and stockfish.get_what_is_on_square("e8") == Stockfish.Piece.BLACK_KING:
                move = "e8g8"
            else:
                move = "Invalid"
            if stockfish.is_move_correct(move):
                return move
            else:
                return "Can not castle king side."
        elif (move.lower() == 'ooo'):
            # castle queen side
            if ntm == Player.WHITE and stockfish.get_what_is_on_square("e1") == Stockfish.Piece.WHITE_KING:
                move = "e1c1"
            elif ntm == Player.BLACK and stockfish.get_what_is_on_square("e8") == Stockfish.Piece.BLACK_KING:
                move = "e8c8"
            else:
                move = "Invalid"
            if stockfish.is_move_correct(move):
                return move
            else:
                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 convenience
        match = regex.match("^([RNBKQrnkq]?)([a-h]?)([1-8]?)(x?)([a-h][1-8])(=?[RNBKQrnbkq]?)$", move)
        if match == None:
            return "Not a valid move string."
        groups = match.groups()
        piece = None

        # resolve piece class
        if len(groups[0]) == 0:
            piece = Stockfish.Piece.WHITE_PAWN if ntm == Player.WHITE else Stockfish.Piece.BLACK_PAWN
        else:
            if groups[0].lower() == 'r':
                piece = Stockfish.Piece.WHITE_ROOK if ntm == Player.WHITE else Stockfish.Piece.BLACK_ROOK
            elif groups[0] == 'B': # bxc6 is a pawn from b, not a bishop.
                piece = Stockfish.Piece.WHITE_BISHOP if ntm == Player.WHITE else Stockfish.Piece.BLACK_BISHOP
            elif groups[0].lower() == 'n':
                piece = Stockfish.Piece.WHITE_KNIGHT if ntm == Player.WHITE else Stockfish.Piece.BLACK_KNIGHT
            elif groups[0].lower() == 'k':
                piece = Stockfish.Piece.WHITE_KING if ntm == Player.WHITE else Stockfish.Piece.BLACK_KING
            elif groups[0].lower() == 'q':
                piece = Stockfish.Piece.WHITE_QUEEN if ntm == Player.WHITE else Stockfish.Piece.BLACK_QUEEN
            else:
                return f"Can not determine piece to move ('{groups[0]}')."

        # resolve source file
        src_file = None
        if len(groups[1]) == 1:
            src_file = groups[1]

        # resolve source rank
        src_rank = None
        if len(groups[2]) == 1:
            src_rank = groups[2]

        # resolve capture
        isCapture = groups[3] == 'x'

        # pawn conversion
        turnsInto = groups[5].lstrip('=')

        # resolve dst
        dst = groups[4]

        # resolve src
        src = None
        # find src
        if src_file != None and src_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 square
            for file in range(ord('a'), ord('h') + 1):
                file = chr(file)
                if src_file != None and src_file != file:
                    continue
                for rank in range(1,8+1):
                    rank = str(rank)
                    if src_rank != None and src_rank != rank:
                        continue
                    src = f"{file}{rank}"
                    if piece == stockfish.get_what_is_on_square(src) and stockfish.is_move_correct(f"{src}{dst}{turnsInto}"):
                        possibleSrc.append(src)
            if len(possibleSrc) == 1:
                src = possibleSrc[0]
            elif len(possibleSrc) == 0:
                pieceDesc = str(piece).replace("Piece.", "")
                if color:
                    pieceDesc = colored(pieceDesc, color=ColorConst.WHITE_PIECE if ntm == Player.WHITE else ColorConst.BLACK_PIECE, on_color=ColorConst.FEN_BG, attrs=['bold'])
                if src_rank != None and src_file == None:
                    pieceDesc = pieceDesc + f" from rank {src_rank}"
                elif src_rank == None and src_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 needed
                return f"No {pieceDesc} can go to {dst}"
            else:
                pieceDesc = str(piece).replace("Piece.", "")
                if color:
                    pieceDesc = colored(pieceDesc, color=ColorConst.WHITE_PIECE if ntm == Player.WHITE else ColorConst.BLACK_PIECE, on_color=ColorConst.FEN_BG, attrs=['bold'])

                return f"Could not determine which {pieceDesc} you want to move to {dst}"
        # build stockfish move
        move = f"{src}{dst}{turnsInto}"
        # check if resolved move is indeed a capture
        if stockfish.is_move_correct(move):
            if ((isCapture and turnsInto != '' and stockfish.get_what_is_on_square(dst) == None) or (isCapture and turnsInto == '' and stockfish.will_move_be_a_capture(move) ==Stockfish.Capture.NO_CAPTURE)):
                return "Move is no Capture"
            elif (not isCapture and turnsInto != '' and stockfish.get_what_is_on_square(dst) != None) or (not isCapture and turnsInto == '' and stockfish.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.")
            return move
    return "Invalid Move"

Option to get board visual from either side

For the get_board_visual function, it might be useful to let the user get the board from Black's side, if they choose. E.g., a bool param could be added to the function, representing whether to get the board from white's side (user can get the board from Black's side by sending in False as the arg). This param should probably be optional and set to True by default, in order to not break existing code using the function.

Some code would have to be written to flip the board, since afaik Stockfish only returns it from White's side.

Feature: set_skill_level

def set_skill_level(self, skill_level: int) -> None:
    self.__put(f"setoption name Skill Level value {skill_level}")

I suggest adding this little code block which makes it possible to set stockfish' skill level as a number from 0 to 20

some permission issue on CentOS and MacOS.

stockfish = stockfish.Stockfish()
Exception ignored in: <bound method Stockfish.del of <stockfish.Stockfish object at 0x7fa010ab1cf8>>
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/stockfish.py", line 140, in del
self.stockfish.kill()
AttributeError: 'Stockfish' object has no attribute 'stockfish'
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/site-packages/stockfish.py", line 27, in init
stdout=subprocess.PIPE
File "/usr/lib64/python3.4/subprocess.py", line 856, in init
restore_signals, start_new_session)
File "/usr/lib64/python3.4/subprocess.py", line 1464, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'stockfish'

Parameters not unique for objects

Hi, I'm using the script with 2 sub processes, one running some eval and some running an AI. But it seems that there is bug somewhere with the get_parameters() function. The parameters are shared between objects.

Running this test, pretty much shows the problem

def test_get_parameters(self):

    s1 = Stockfish()
    s2 = Stockfish()

    arg1 = s1.get_parameters()
    arg2 = s2.get_parameters()

    assert arg1 == arg2

    s1.set_skill_level(1)

    arg1 = s1.get_parameters()
    arg2 = s2.get_parameters()

    assert arg1 != arg2

won't open

Hello

I am trying to use your program inside my own program, but it craches with the following error:

Traceback (most recent call last):
File "c:/Users/12000780/PycharmProjects/PyGames/schaken/main.py", line 10, in
engine = Stockfish("C:/Users/" + user + "/PycharmProjects/PyGames/schaken/stockfish-win")
File "C:\Users\12000780\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\stockfish\models.py", line 33, in init
self.stockfish = subprocess.Popen(
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 854, in init
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1776.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 1307, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
PermissionError: [WinError 5] Toegang geweigerd
Exception ignored in: <function Stockfish.del at 0x0000019442330820>
Traceback (most recent call last):
File "C:\Users\12000780\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\stockfish\models.py", line 270, in del
self.stockfish.kill()
AttributeError: 'Stockfish' object has no attribute 'stockfish'

I am using Python 3.8 and Windows. Could it be that it only works in Linux?

Thanks

Error in stockfish\models.py in __del__, _put

I did not even use del I dont know why it is error'ing there.
The exact line which is error'ing is, stdin.flush()
It gives OSError: [Errorno 22] Invalid argument.
I have a different computer where I do not get the error.
I dont understand.

image

Bild_2022-05-02_103426413

set_position accepts FEN string

Maybe the set_position and set_fen_position methods could be conflated? or at least the input checked to see if it makes sense.

sf = stockfish.Stockfish('path-to-sf')
sf.set_position('2k5/3b4/p3p3/1p1pPn2/1Pp3pB/P3K3/2P2P2/8 w - - 2 36')
sf.get_best_move() #e2e4

Get evaluation is too slow

Hello

I am making a chess analyzing program, and to test it, I wanted to see what it thinks of the Sicillian Defense opening (e4, c5). For the first move, it tells me e4 is the best move, which is a really strong move. For c5, it doesn't think it's the best move (thats ok), so it thinks for 5 hours to evaluate the position at depth 25 with 4 threads. (btw, it needs longer than 5 hours to evaluate the position, while Lichess does it within 10 minutes if it analyzes locally.) Can you please explain why this happens and fix it for me? (I need to do it twice for 1 move and can't debug my program if it's wrong)

Thanks

Detect Capture

I'm building a chess robot using stockfish and this python library. When stockfish is going to capture a piece, I want the robot to remove the captured piece and place it to the side. Then the arm will move its piece in the place of the captured one.

I need a way for the stockfish engine to send an additional piece of information that the move it's making will be a capture. That way it will remove the existing piece.

Thanks

How to handle pawns on Row8 and Row1

Is there a way to choose the type of piece you will get when you reach the opponent row. ?

my chess board will not accept a pawn to enter row 8 - not a valid move, am I right or do I do something wrong?

Crashing when using Stockfish 15

The function self._get_stockfish_major_version is crashing when using the latest stockfish. They probably changed the output a bit.

UnboundLocalError: local variable 'evaluation' referenced before assignment

This integration of has worked well, but it occasionally throws this error:

   File "C:\Users\Joshua\Anaconda3\lib\site-packages\stockfish\models.py", line 256, in get_evaluation
     return evaluation
 UnboundLocalError: local variable 'evaluation' referenced before assignment

I'll throw a try/escape into a while loop to avoid it, but I thought I'd let you know.

freezes when given certain fen inputs

Hi,

I have an instance of Stockfish working perfectly, however when some fen strings are given as input, there is no return value to the stockfish.get_best_move() and it just keeps thinking infinitely without returning anything. Can you try running the code below please?

As you run it, you can see the visual board that shows and it surely exists (since it's a real time scenario of a game).
But the move won't show and the program will keep running.

from stockfish import Stockfish


params = {
            "Threads": 1,
            "Ponder": "true",
            "Skill Level": 20
        }

stockfish = Stockfish(path="stockfish12/bin/stockfish", depth=6, parameters=params)

stockfish.set_fen_position('4r3/pbk4p/1p1n4/2p5/3p4/7P/PPP2Pr1/RN1R2K1 b KQkq - 0 1')

print(stockfish.get_board_visual())
print(stockfish.get_best_move())

Thanks in advance,

Fred

get_evaluation is really slow

Hello

I am making a chess program, and my checkmate detection is using the get_evaluation() method. I am using 2 threads, and it is buzy for 5 minutes now without getting the evaluation of the starting position. Because I don't know how much threads my users have availible, I can't just assign more threads to make it faster.

Here is my code:

os.system("pip install stockfish")
from stockfish import Stockfish
import platform
input("WARNING. This chess program is about as strong as it gets. Press enter to continue...")
if platform.system == "Linux":
    engine = Stockfish("schaken/stockfish-linux/stockfish", parameters={"Slow Mover": 120, "Threads": 2})
else:
    engine = Stockfish("schaken/stockfish-win/stockfish.exe", parameters={"Slow Mover": 120, "Threads": 2})
engine.set_depth(20)
engine.set_skill_level(20)
wit = True
moves = []
engine.set_position(moves)
while engine.get_evaluation() != {'type': 'mate', 'value': 0}:
    if wit:
        print(engine.get_board_visual(), end="")
        print("  a   b   c   d   e   f   g   h")
        print()
        move = input("Zet een zet zoals e2e4  ")
        while not engine.is_move_correct(move):
            move = input("Zet een zet zoals e2e4  ")
        moves.append(move)
        engine.set_position(moves)
        wit = False
    else:
        best_move = engine.get_best_move()
        moves.append(best_move)
        print("Mijn zet is", best_move)
        engine.set_position(moves)
        wit = True
    

Is there a way to make it faster? (I can't play e4 to start)

Thanks in advance

Where to include stockfish = Stockfish("pathtostockfish")?

I'm getting this error:
Traceback (most recent call last): File "C:\Users\etfri\anaconda3\envs\py38\lib\site-packages\stockfish\models.py", line 270, in __del__ self.stockfish.kill() AttributeError: 'Stockfish' object has no attribute 'stockfish'

As you mentioned, I have installed the stockfish binaries to C:\Users\etfri\Desktop\stockfishlib,

but where should I include the stockfish = Stockfish("/Users/etfri/Desktop/stockfishlib")? inside the Stockfish class, before / after?

Can't unambiguously make castling moves in custom Chess960 position

import stockfish

bot = stockfish.Stockfish('stockfish')
bot.set_fen_position('4rkr1/4p1p1/8/8/8/8/8/5K1R w H - 0 100')  # Chess 960, white has mate in 1 in castling
print(bot.get_best_move())  # f1g1 -- castling or normal king move?

In this custom position, white has mate in 1 if castling is performed. Engine recognises this and attempts to castle, but resulting output can mean either castling, or normal move.

Checkmate detection

Is there a way to detect checkmate or stalmate in my own chess engine? (maybe using get_evaluation for checkmate?)

Thanks

Engine returning the same chess moves for all the positions

Currently, no moves are getting updated in the board.

Code -
stockfish = Stockfish() stockfish.set_position(['e4', 'e6','Nf3', 'c6', 'a3', 'Qb6', 'Nc3', 'Bc5', 'd4']) print(stockfish.get_board_visual())

This is the board currently -
Screenshot 2021-03-15 at 3 41 19 PM

I have tried it with multiple pgn moves data, and also on both mac and linux.

no output

i dont get any output when i use any of the functions , and i dont get an error either
i don t know what i am doing wrong, please help if u can

does_current_engine_version_have_wdl_option() not work on stockfish variant

using stockfish variant (brainfish and fairy_stockfish), not work for does_current_engine_version_have_wdl_option()

#stockfish = Stockfish(path = "engine/brainfish")
stockfish = Stockfish(path = "engine/fairy_stockfish")
#stockfish = Stockfish(path = "engine/fairy_stockfish")
if stockfish.does_current_engine_version_have_wdl_option():
    get_wdl_stats = stockfish.get_wdl_stats()
    print(get_wdl_stats)
else:
    get_wdl_stats = 'dont have'
    print(get_wdl_stats)

code above produce runtime error

RuntimeError                              Traceback (most recent call last)
<ipython-input-80-1bf8c7999c28> in <module>
      1 stockfish = Stockfish(path = "engine/fairy_stockfish")
      2 if stockfish.does_current_engine_version_have_wdl_option():
----> 3     get_wdl_stats = stockfish.get_wdl_stats()
      4     print(get_wdl_stats)
      5 else:

~/opt/miniconda3/envs/python3_test/lib/python3.7/site-packages/stockfish/models.py in get_wdl_stats(self)
    367         if not self.does_current_engine_version_have_wdl_option():
    368             raise RuntimeError(
--> 369                 "Your version of Stockfish isn't recent enough to have the UCI_ShowWDL option."
    370             )
    371         self._go()

RuntimeError: Your version of Stockfish isn't recent enough to have the UCI_ShowWDL option.

but this code run smoothly both brainfish and fairy_stockfish

#stockfish = Stockfish(path = "engine/brainfish")
stockfish = Stockfish(path = "engine/fairy_stockfish")
evaluation = stockfish.get_evaluation()
print(evaluation)

also test stockfish_mv is not work

stockfish = Stockfish(path = "engine/stockfish_mv")
stockfish.get_stockfish_major_version()

error traceback

ValueError                                Traceback (most recent call last)
<ipython-input-81-21fd1715ed6e> in <module>
----> 1 stockfish = Stockfish(path = "engine/stockfish_mv")
      2 stockfish.get_stockfish_major_version()

~/opt/miniconda3/envs/python3_test/lib/python3.7/site-packages/stockfish/models.py in __init__(self, path, depth, parameters)
     47 
     48         self._stockfish_major_version: int = int(
---> 49             self._read_line().split(" ")[1].split(".")[0]
     50         )
     51 

ValueError: invalid literal for int() with base 10: '2018-11-29'

No exception raised when fen position is wrong

Hi,
it's me again.

When I accidentally set a wrong fen position and ask for the best move, stockfish hangs forever without returning anything or throwing an exception.

Here is an example

from stockfish import Stockfish

#Wrong fen because there are too many kings
wrong_fen = '3kk3/8/8/8/8/8/8/3KK3 w - - 0 0'

s = Stockfish()
print('stockfish created')

s.set_fen_position(wrong_fen)
print('board position set')

try:
    move = s.get_best_move()
    print('best move is {}'.format(move))
except Exception as e:
    print('getting the best move failed with {}'.format(e))
finally:
    print('the end')

The output is:

stockfish created
board position set
stockfish: /builddir/build/BUILD/stockfish-10/src/position.h:255: Square Position::square(Color) const [with PieceType Pt = KING]: Assertion `pieceCount[make_piece(c, Pt)] == 1' failed.

As you can see no exception was raised or caught. But even more problematic is that the call get_best_move doesn't return at all. This is an issue because when using it inside an application, it might get stuck there without you even knowing.

Import resolves to Its containing file/cannot find reference 'Stockfish' in 'stockfish.py'

Trying out the stockfish wrapper with some simple code

from stockfish import Stockfish

stockfish = Stockfish('D:/Programming/Python/test/stockfish.exe')

When I hover over 'stockfish' in the import statement, Pycharm tells me "Import resolves to its containing file"
When I hover over 'Stockfish' in the import statement, Pycharm tells me "Cannot find reference 'Stockfish' in 'stockfish.py'"

My stockfish executable is in the same folder as the .py file
When run it gives me this error:

Traceback (most recent call last):
  File "D:/Programming/Python/test/stockfish.py", line 1, in <module>
    from stockfish import Stockfish
  File "D:\Programming\Python\test\stockfish.py", line 1, in <module>
    from stockfish import Stockfish
ImportError: cannot import name 'Stockfish' from partially initialized module 'stockfish' (most likely due to a circular import) 
(D:\Programming\Python\test\stockfish.py)

Python 3.8
Stockfish 12
Windows 10

stockfish.info returning mate in 1 in a checkmate position

Example code:

sf = stockfish.Stockfish(stockfish_executable)
sf.set_fen_position('8/8/8/6pp/8/4k1PP/8/r3K3 w - - 12 53')
sf.get_best_move()
sf.info  # blah blah mate 1

The position in the FEN is checkmate, but info string returns a mate in 1:

'info depth 10 seldepth 2 multipv 1 score mate 1 nodes 204 nps 204000 tbhits 0 time 1 pv a2a1'

The FEN position is the last position in this game.

Change stockfish parameters

Hello, I would like to know how to change Stockfish parameters other than skill level.

I would like to change "Threads" and "Minimum Thinking Time".

Also: am I suppose to wait between setting up the board position and asking for the best move? Or can I ask it straight away?

Thanks a lot

will_move_be_a_capture throws exeption when converting pawn

When you call will_move_be_a_capture() throws an exception when the move described is a pawn conversion.

Test case:

from stockfish import Stockfish
stockfish = Stockfish("/path/to/stockfish")
stockfish.set_fen_position('8/1R6/5pk1/4P3/bPn5/P4PP1/3pq3/6K1 b - - 0 11')
stockfish.will_move_be_a_capture('d2d1q')
ValueError                                Traceback (most recent call last)
----> 1 stockfish.will_move_be_a_capture('d2d1q')

File ~/repositories/chess/py_stockfish/lib/python3.10/site-packages/stockfish/models.py:641, in Stockfish.will_move_be_a_capture(self, move_value)
    639     raise ValueError("The proposed move is not valid in the current position.")
    640 starting_square_piece = self.get_what_is_on_square(move_value[:2])
--> 641 ending_square_piece = self.get_what_is_on_square(move_value[-2:])
    642 if ending_square_piece != None:
    643     if self._parameters["UCI_Chess960"] == "false":

File ~/repositories/chess/py_stockfish/lib/python3.10/site-packages/stockfish/models.py:601, in Stockfish.get_what_is_on_square(self, square)
    589 """Returns what is on the specified square.
    590
    591 Args:
   (...)
    597     object if the square is empty.
    598 """
    600 file_letter = square[0].lower()
--> 601 rank_num = int(square[1])
    602 if (
    603     len(square) != 2
    604     or file_letter < "a"
   (...)
    607     or square[1] > "8"
    608 ):
    609     raise ValueError(
    610         "square argument to the get_what_is_on_square function isn't valid."
    611     )

ValueError: invalid literal for int() with base 10: 'q'

To fix it, change

ending_square_piece = self.get_what_is_on_square(move_value[-2:])

to

ending_square_piece = self.get_what_is_on_square(move_value[2:4])

Bad values, and inconsistency due to tendency to 2.57

I have found that the get_evaluation is getting cp values that has tendency to 2.57. Here are the runs: TestCase1Results.txt.
Here is the code that was run:
moveAnalyze-in-txt.txt, where I called getStats() with the fen and move specified in the test case files.

I used stockfish module version 3.17.0 and stockfish 14 on Elementary OS 5.1 Hera (Ubuntu 18.04 base).

The results were also not the values given by lichess.org. Can someone please explain what's wrong and/or how to fix it?

evaluation does not work in SF 12

Hi Ilya,
I checked this several times with different settings, "stockfish.get_evaluation()" does not work in stockfish 12.
It works well in stockfish 8. Maybe this is a Stockfish 12 specific problem ??

here is a debug:
{'Write Debug Log': 'false', 'Contempt': 0, 'Min Split Depth': 0, 'Threads': 2, 'Ponder': 'false', 'Hash': 16, 'MultiPV': 1, 'Skill Level': 20, 'Move Overhead': 30, 'Minimum Thinking Time': 20, 'Slow Mover': 80, 'UCI_Chess960': 'false'}
^CTraceback (most recent call last):
File "/home/nnn/Desktop/pypro/stockfishTest.py", line 35, in
print(stockfish.get_evaluation()['type'])
File "/home/nnn/tf2/lib/python3.6/site-packages/stockfish/models.py", line 246, in get_evaluation
text = self._read_line()
File "/home/nnn/tf2/lib/python3.6/site-packages/stockfish/models.py", line 73, in _read_line
return self.stockfish.stdout.readline().strip()

Kind regards

Marius

models.py has ValueError when parsing stockfish release with minor version

When trying to instantiate Stockfish with

from stockfish import Stockfish
stockfish = Stockfish("path/to/stockfish_14.1_linux_x64")

I get ValueError: invalid literal for int() with base 10: '14.1' from models.py. One way this can be fixed is by adding an additional cast to float before casting to int.

get_fen_position() doesn't work after set_position()

After running stockfish.set_position([VALID MOVES])
and then trying print(stockfish.get_fen_position())
you will only be returned the starting fen position, not where you expect after running set_position.

This is problematic since I'm trying to save FEN positions after setting the moves. Could someone see if this same issue is happening to them?

Can't define Stockfish

when I write first two line of usage code:
from stockfish import Stockfish
stockfish = Stockfish()
return error:
'Stockfish' object has no attribute 'stockfish'
Using python 3.5 ,Windows 10 .

"OSError: [Errno 22] Invalid argument"

Hello.
Here is my code:

from stockfish import Stockfish

STOCKFISH_PATH = "C:/path/to/Stockfish/stockfish.exe"

stockfish = Stockfish(STOCKFISH_PATH)

Whenever I try to run this code, I get the following error.

Traceback (most recent call last):
  File "C:\path\to\stockfishbot.py", line 3, in <module>
    stockfish = Stockfish(STOCKFISH_PATH)
  File "C:\path\to\AppData\Local\Programs\Python\Python39\lib\site-packages\stockfish\models.py", line 39, in __init__
    self._stockfish_major_version: int = int(self._read_line().split(" ")[1])
IndexError: list index out of range
Exception ignored in: <function Stockfish.__del__ at 0x00000204B4F505E0>
Traceback (most recent call last):
  File "C:\path\to\AppData\Local\Programs\Python\Python39\lib\site-packages\stockfish\models.py", line 396, in __del__
    self._put("quit")
  File "C:\path\to\AppData\Local\Programs\Python\Python39\lib\site-packages\stockfish\models.py", line 83, in _put
    self.stockfish.stdin.flush()
OSError: [Errno 22] Invalid argument

Just so you know, C:\path\to\stockfishbot.py, is referring to the file where I reference the Stockfish module.

Exception when creating stockfish instance with newest version 14.1

Since yesterday, stockfish 14.1 is online. With that version, calling the constructor, I get:

File "/usr/local/lib/python3.10/site-packages/stockfish/models.py", line 39, in init
self._stockfish_major_version: int = int(self._read_line().split(" ")[1])
ValueError: invalid literal for int() with base 10: '14.1'

getting position evaluation

  1. I could only see get_best_move(), but, how do we get the stockfish's evaluation?
  2. Do we have to close the stockfish after getting best move in every position? Because, the speed seems to be decreasing if I put get_best_move() in a loop

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.