GithubHelp home page GithubHelp logo

zhelyabuzhsky / stockfish Goto Github PK

View Code? Open in Web Editor NEW
258.0 8.0 49.0 124 KB

Integrates the Stockfish chess engine with Python

Home Page: https://pypi.python.org/pypi/stockfish

License: MIT License

Python 100.00%
chess chess-engine stockfish

stockfish's Introduction

Stockfish

Implements an easy-to-use Stockfish class to integrates the Stockfish chess engine with Python.

Install

$ pip install stockfish

Ubuntu

$ sudo apt install stockfish

Mac OS

$ brew install stockfish

Features and usage examples

Initialize Stockfish class

You should install the stockfish engine in your operating system globally or specify path to binary file in class constructor

from stockfish import Stockfish

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

There are some default engine settings used by this wrapper. For increasing Stockfish's strength and speed, the "Threads" and "Hash" parameters can be modified.

{
    "Debug Log File": "",
    "Contempt": 0,
    "Min Split Depth": 0,
    "Threads": 1, # More threads will make the engine stronger, but should be kept at less than the number of logical processors on your computer.
    "Ponder": "false",
    "Hash": 16, # Default size is 16 MB. It's recommended that you increase this value, but keep it as some power of 2. E.g., if you're fine using 2 GB of RAM, set Hash to 2048 (11th power of 2).
    "MultiPV": 1,
    "Skill Level": 20,
    "Move Overhead": 10,
    "Minimum Thinking Time": 20,
    "Slow Mover": 100,
    "UCI_Chess960": "false",
    "UCI_LimitStrength": "false",
    "UCI_Elo": 1350
}

You can change them, as well as the default search depth, during your Stockfish class initialization:

stockfish = Stockfish(path="/Users/zhelyabuzhsky/Work/stockfish/stockfish-9-64", depth=18, parameters={"Threads": 2, "Minimum Thinking Time": 30})

These parameters can also be updated at any time by calling the "update_engine_parameters" function:

stockfish.update_engine_parameters({"Hash": 2048, "UCI_Chess960": "true"}) # Gets stockfish to use a 2GB hash table, and also to play Chess960.

When you're done using the Stockfish engine process, you can send the "quit" uci command to it with:

stockfish.send_quit_command()

The __del__() method of the Stockfish class will call send_quit_command(), but it's technically not guaranteed python will call __del__() when the Stockfish object goes out of scope. So even though it'll probably not be needed, it doesn't hurt to call send_quit_command() yourself.

Set position by a sequence of moves from the starting position

stockfish.set_position(["e2e4", "e7e6"])

Update position by making a sequence of moves from the current position

stockfish.make_moves_from_current_position(["g4d7", "a8b8", "f1d1"])

Set position by Forsyth–Edwards Notation (FEN)

If you'd like to first check if your fen is valid, call the is_fen_valid() function below.
Also, if you want to play Chess960, it's recommended you first update the "UCI_Chess960" engine parameter to be "true", before calling set_fen_position.

stockfish.set_fen_position("rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2")

Check whether the given FEN is valid

This function returns a bool saying whether the passed in FEN is valid (both syntax wise and whether the position represented is legal).
The function isn't perfect and won't catch all cases, but generally it should return the correct answer. For example, one exception is positions which are legal, but have no legal moves. I.e., for checkmates and stalemates, this function will incorrectly say the fen is invalid.

stockfish.is_fen_valid("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
True
stockfish.is_fen_valid("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -") # will return False, in this case because the FEN is missing two of the six required fields.
False

Get best move

stockfish.get_best_move()
d2d4

It's possible to specify remaining time on black and/or white clock. Time is in milliseconds.

stockfish.get_best_move(wtime=1000, btime=1000)

Get best move based on a time constraint

stockfish.get_best_move_time(1000)

Time constraint is in milliseconds

e2e4

Check is move correct with current position

stockfish.is_move_correct('a2a3')
True

Get info on the top n moves

stockfish.get_top_moves(3)
[
    {'Move': 'f5h7', 'Centipawn': None, 'Mate': 1},
    {'Move': 'f5d7', 'Centipawn': 713, 'Mate': None},
    {'Move': 'f5h5', 'Centipawn': -31, 'Mate': None}
]

Get Stockfish's win/draw/loss stats for the side to move in the current position

Before calling this function, it is recommended that you first check if your version of Stockfish is recent enough to display WDL stats. To do this,
use the "does_current_engine_version_have_wdl_option()" function below.

stockfish.get_wdl_stats()
[87, 894, 19]

Find if your version of Stockfish is recent enough to display WDL stats

stockfish.does_current_engine_version_have_wdl_option()
True

Set current engine's skill level (ignoring ELO rating)

stockfish.set_skill_level(15)

Set current engine's ELO rating (ignoring skill level)

stockfish.set_elo_rating(1350)

Set current engine's depth

stockfish.set_depth(15)

Get current engine's parameters

stockfish.get_parameters()
{
    "Debug Log File": "",
    "Contempt": 0,
    "Min Split Depth": 0,
    "Threads": 1,
    "Ponder": "false",
    "Hash": 16,
    "MultiPV": 1,
    "Skill Level": 20,
    "Move Overhead": 10,
    "Minimum Thinking Time": 20,
    "Slow Mover": 100,
    "UCI_Chess960": "false",
    "UCI_LimitStrength": "false",
    "UCI_Elo": 1350
}

Reset the engine's parameters to the default

stockfish.reset_engine_parameters()

Get current board position in Forsyth–Edwards notation (FEN)

stockfish.get_fen_position()
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

Get current board visual

stockfish.get_board_visual()
+---+---+---+---+---+---+---+---+
| r | n | b | q | k | b | n | r | 8
+---+---+---+---+---+---+---+---+
| p | p | p | p | p | p | p | p | 7
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 6
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 5
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 4
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 3
+---+---+---+---+---+---+---+---+
| P | P | P | P | P | P | P | P | 2
+---+---+---+---+---+---+---+---+
| R | N | B | Q | K | B | N | R | 1
+---+---+---+---+---+---+---+---+
  a   b   c   d   e   f   g   h

This function has an optional boolean (True by default) as a parameter that indicates whether the board should be seen from the view of white. So it is possible to get the board from black's point of view like this:

stockfish.get_board_visual(False)
+---+---+---+---+---+---+---+---+
| R | N | B | K | Q | B | N | R | 1
+---+---+---+---+---+---+---+---+
| P | P | P | P | P | P | P | P | 2
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 3
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 4
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 5
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 6
+---+---+---+---+---+---+---+---+
| p | p | p | p | p | p | p | p | 7
+---+---+---+---+---+---+---+---+
| r | n | b | k | q | b | n | r | 8
+---+---+---+---+---+---+---+---+
  h   g   f   e   d   c   b   a

Get current board evaluation in centipawns or mate in x

stockfish.get_evaluation()

Positive is advantage white, negative is advantage black

{"type":"cp", "value":12}
{"type":"mate", "value":-3}

Run benchmark

BenchmarkParameters

params = BenchmarkParameters(**kwargs)

parameters required to run the benchmark function. kwargs can be used to set custom values.

ttSize: range(1,128001)
threads: range(1,513)
limit: range(1,10001)
fenFile: "path/to/file.fen"
limitType: "depth", "perft", "nodes", "movetime"
evalType: "mixed", "classical", "NNUE"
stockfish.benchmark(params)

This will run the bench command with BenchmarkParameters. It is an additional custom non-UCI command, mainly for debugging. Do not use this command during a search!

Get current major version of stockfish engine

E.g., if the engine being used is Stockfish 14.1 or Stockfish 14, then the function would return 14. Meanwhile, if a development build of the engine is being used (not an official release), then the function returns an int with 5 or 6 digits, representing the date the engine was compiled on. For example, 20122 is returned for the development build compiled on January 2, 2022.

stockfish.get_stockfish_major_version()
15

Find if the version of Stockfish being used is a development build

stockfish.is_development_build_of_engine()
False

Find what is on a certain square

If the square is empty, the None object is returned. Otherwise, one of 12 enum members of a custom
Stockfish.Piece enum will be returned. Each of the 12 members of this enum is named in the following pattern:
colour followed by underscore followed by piece name, where the colour and piece name are in all caps.
For example, say the current position is the starting position:

stockfish.get_what_is_on_square("e1") # returns Stockfish.Piece.WHITE_KING
stockfish.get_what_is_on_square("d8") # returns Stockfish.Piece.BLACK_QUEEN
stockfish.get_what_is_on_square("h2") # returns Stockfish.Piece.WHITE_PAWN
stockfish.get_what_is_on_square("b5") # returns None

Find if a move will be a capture (and if so, what type of capture)

The argument must be a string that represents the move, using the notation that Stockfish uses (i.e., the coordinate of the starting square followed by the coordinate of the ending square).
The function will return one of the following enum members from a custom Stockfish.Capture enum: DIRECT_CAPTURE, EN_PASSANT, or NO_CAPTURE.
For example, say the current position is the one after 1.e4 Nf6 2.Nc3 e6 3.e5 d5.

stockfish.will_move_be_a_capture("c3d5")  # returns Stockfish.Capture.DIRECT_CAPTURE  
stockfish.will_move_be_a_capture("e5f6")  # returns Stockfish.Capture.DIRECT_CAPTURE  
stockfish.will_move_be_a_capture("e5d6")  # returns Stockfish.Capture.EN_PASSANT  
stockfish.will_move_be_a_capture("f1e2")  # returns Stockfish.Capture.NO_CAPTURE  

StockfishException

The StockfishException is a newly defined Exception type. It is thrown when the underlying Stockfish process created by the wrapper crashes. This can happen when an incorrect input like an invalid FEN (for example 8/8/8/3k4/3K4/8/8/8 w - - 0 1 with both kings next to each other) is given to Stockfish.
Not all invalid inputs will lead to a StockfishException, but only those which cause the Stockfish process to crash.
To handle a StockfishException when using this library, import the StockfishException from the library and use a try/except-block:

from stockfish import StockfishException

try:
    # Evaluation routine

except StockfishException:
    # Error handling

Testing

$ python setup.py test

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

MIT License. Please see License File for more information.

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

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.

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

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

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

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'

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?

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.

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?

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"

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

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'

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?

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 .

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

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.

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.

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

"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.

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

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?

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.

Checkmate detection

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

Thanks

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'

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

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

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

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.

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])

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'

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

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.

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)

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?

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.

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.

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

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

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

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

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.