Coder Social home page Coder Social logo

stockfish's Introduction

stockfish

CRAN status Codecov test coverage R-CMD-check

Overview

{stockfish} is an R package that implements the UCI open communication protocol and ships with Stockfish, a very popular, open source, powerful chess engine written in C++.

Installation

Install the released version of {stockfish} from CRAN:

install.packages("stockfish")

Or install the development version from GitHub:

# install.packages("remotes")
remotes::install_github("curso-r/stockfish")

You can also find more (and more recent) versions of the Stockfish engine to use with {stockfish} at their download page.

Example

{stockfish} is as simple to use as any other UCI package. You should start the engine with fish$new() and send commands with its internal methods, only remembering to run quit() once you’re done.

library(stockfish)

# Start the engine
engine <- fish$new()

# Examine background process
engine$process
#> PROCESS 'stockfish', running, pid 51774.

# Search for best move
engine$go()
#> [1] "info depth 10 seldepth 10 multipv 1 score cp 69 nodes 42240 nps 276078 tbhits 0 time 153 pv e2e4 b8c6 d2d4 d7d5 e4e5 e7e6 g1f3 g8e7 b1c3 h7h6"

# Setup a game from FEN
engine$ucinewgame()
engine$position("6rk/2Q3p1/5qBp/5P2/8/7P/6PK/8 w - - 15 51")
engine$go()
#> [1] "info depth 15 seldepth 18 multipv 1 score cp 53 nodes 585935 nps 264053 hashfull 259 tbhits 0 time 2219 pv e2e4 e7e5 b1c3 g8f6 g1f3 b8c6 f1c4 f6e4 c3e4 d7d5 c4d3 d5e4 d3e4 f8c5 e1g1"

# Stop the engine
engine$quit()

Usage

fish, this package’s main class, represents a Stockfish engine, allowing the user to send commands and receive outputs according to the UCI protocol. In short, a fish object, when created, spawns a detached Stockfish process and pipes into its stdin and stdout.

For more information, see its full documentation by running ?fish.

Bundled Stockfish

This package comes bundled with Stockfish, a very popular, open source, powerful chess engine written in C++. It can achieve an ELO of 3544, runs on Windows, macOS, Linux, iOS and Android, and can be compiled in less than a minute.

When installing {stockfish} (lower case), Stockfish’s (upper case) source code is compiled and the resulting executable is stored with your R packages. This is not a system-wide installation! You don’t have to give it administrative privileges to run or even worry about any additional software.

But there are two main downsides:

  1. While the bundled version of the engine (Stockfish 14.1) is up-to-date as of March 2022, it isn’t able to update itself. This means that, if I’m not able to port an upcomming version of Stockfish, the package will stay behind. Luckly, you can always download the version of your choosing and pass the executable as an argument to fish$new().

  2. Since version 12, Stockfish supports NNUE evaluation, but this requires some pretty heavy binaries. In order to avoid bundling large files with {stockfish}, I have decided to disable NNUE in the source code. Again, you are free to download a NNUE-capable version and use it instead of the bundled executable.

UCI Protocol

UCI (Universal Chess Interface) is an open communication protocol that enables chess engines to communicate with user interfaces. Strictly speaking, the fish class implements the UCI protocol as publicized by Stefan-Meyer Kahlen, just with a focus on the Stockfish engine. This means that some methods are not implemented (see Common Gotchas) and that all tests are run on Stockfish, but everything else should work fine with other engines.

The quoted text at the end of the documentation of each method was extracted directly from the official UCI protocol, so you can see exactly what that command can do. In general, the commands are pretty self-explanatory, except for long algebraic notation (LAN), the move notation used by UCI. In this notation, moves are recorded using the starting and ending positions of each piece, e.g. e2e4, e7e5, e1g1 (white short castling), e7e8q (for promotion), 0000 (nullmove).

Implementation

All the heavy lifting of the fish class is done by the {processx} package. The Stockfish process is created with processx::process$new and IO is done with write_input() and read_output(). An important aspect of the communication protocol of any UCI engine is waiting for replies, and here this is done with a loop that queries the process with poll_io() and stops once the output comes back empty.

Before implementing the UCI protocol manually, this package used {bigchess}. It is a great package created by @rosawojciech, but it has some dependencies that are beyond the scope of this package and ultimately I wanted more control over the API (e.g. using {R6}).

Common Gotchas

The fish class has some specifics that the user should keep in mind when trying to communicate with Stockfish. Some of them are due to implementation choices, but others are related to the UCI protocol itself. This is by no means a comprehensive list (and you should probably read UCI’s documentation), but here are a few things to look out for:

  • Not every UCI method is implemented: since {stockfish} was made with Stockfish in mind, a couple of UCI methods that don’t work with the engine were not implemented. They are debug() and register().

  • Most methods return silently: since most UCI commands don’t output anything or output boilerplate text, most methods return silently. The exceptions are run(), isready(), go() and stop(); you can see exactly what they return by reading their documentations.

  • Not every Stockfish option will work: at least when using the bundled version of Stockfish, not every documented option will work with setoption(). This happens because, as described above, the bundled version has some limitations. Options that will not work are labeled with an asterisk.

  • Times are in milliseconds: unlike most R functions, every method that takes a time interval expects them in milliseconds, not seconds.

Code of Conduct

Please note that the {stockfish} project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.

Copyright Notice

The C++ code of the {stockfish} project is derived from Stockfish 14.1, and its main authors are listed as contributors in the DESCRIPTION file. For a full list of Stockfish 14.1’s authors, please see their AUTHORS list. Finally, as per Stockfish’s terms of use, {stockfish} is also licensed under the GPL 3 (or any later version at your option). Check out LICENSE.md for the full text.

stockfish's People

Contributors

clente avatar dfalbel avatar gaborcsardi 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stockfish's Issues

Release stockfish 0.1.3

Prepare for release:

  • Check current CRAN check results
  • Polish NEWS
  • devtools::build_readme()
  • urlchecker::url_check()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • rhub::check(platform = "solaris-x86-patched-ods")
  • revdepcheck::revdep_check(num_workers = 4)
  • Update cran-comments.md

Submit to CRAN:

  • usethis::use_version('patch')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()

Release stockfish 0.1.2

Prepare for release:

  • Check current CRAN check results
  • Polish NEWS
  • devtools::build_readme()
  • urlchecker::url_check()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • revdepcheck::revdep_check(num_workers = 4)
  • Update cran-comments.md

Submit to CRAN:

  • usethis::use_version('patch')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()

Release stockfish 0.1.3

Prepare for release:

  • Check current CRAN check results
  • Polish NEWS
  • devtools::build_readme()
  • urlchecker::url_check()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • rhub::check(platform = "solaris-x86-patched-ods")
  • Update cran-comments.md

Submit to CRAN:

  • usethis::use_version('patch')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()

Release stockfish 1.0.0

Prepare for release:

  • Check current CRAN check results
  • Polish NEWS
  • devtools::build_readme()
  • urlchecker::url_check()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • revdepcheck::revdep_check(num_workers = 4)
  • Update cran-comments.md
  • Draft blog post

Submit to CRAN:

  • usethis::use_version('major')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()
  • Finish blog post
  • Tweet
  • Add link to blog post in pkgdown news menu

R CMD check failure on Solaris

Just a note, so we don't forget. I can submit a PR as well, soon.

> test_check("stockfish")
-- FAILURE (test-fish.R:18:3): engine works ------------------------------------
engine$process$is_alive() is not FALSE

`actual`:   TRUE
`expected`: FALSE

══ testthat results  ═══════════════════════════════════════════════════════════
FAILURE (test-fish.R:18:3): engine works

[ FAIL 1 | WARN 0 | SKIP 0 | PASS 20 ]
Error: Test failures
Execution halted

Error: <c_error in rethrow_call(c_processx_connection_write_bytes, con, str):
 Cannot write connection (system error 32, Broken pipe) @processx-connection.c:627 (processx_c_connection_write_bytes)>

 Stack trace:

 1. (function (e)  ...
 2. .subset2(e, ".__enclos_env__")$private$finalize()
 3. self$run("quit")
 4. self$process$write_input(paste0(command, "\n"))
 5. processx:::process_write_input(self, private, str, sep)
 6. rethrow_call(c_processx_connection_write_bytes, con, str)

 x Cannot write connection (system error 32, Broken pipe) @processx-connection.c:627 (processx_c_connection_write_bytes)


Error: <c_error in rethrow_call(c_processx_connection_write_bytes, con, str):
 Cannot write connection (system error 32, Broken pipe) @processx-connection.c:627 (processx_c_connection_write_bytes)>

 Stack trace:

 1. (function (e)  ...
 2. .subset2(e, ".__enclos_env__")$private$finalize()
 3. self$run("quit")
 4. self$process$write_input(paste0(command, "\n"))
 5. processx:::process_write_input(self, private, str, sep)
 6. rethrow_call(c_processx_connection_write_bytes, con, str)

 x Cannot write connection (system error 32, Broken pipe) @processx-connection.c:627 (processx_c_connection_write_bytes)

Release stockfish 0.1.0

Prepare for release:

  • Create hex sticker
  • Check that description is informative
  • Check licensing of included files
  • devtools::build_readme()
  • usethis::use_cran_comments()
  • Lint package
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • urlchecker::url_check()
  • Update cran-comments.md
  • Draft blog post

Submit to CRAN:

  • usethis::use_version('minor')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_news_md()
  • usethis::use_github_release()
  • usethis::use_dev_version()
  • Update install instructions in README
  • Finish blog post

Fix compilation on Solaris

Error persists on CRAN (even though GCC has been added as system requirement):

"bitboard.h", line 371: Error: #error "Compiler not supported.".

Cannot reproduce with rhub::check_on_solaris().

R6 class finalizer

You could have a R6 class finalizer in order to fix:

Don’t forget to assign: if you simply run fish$new() without assigning it to an object, you will have to either restart the session or kill the Stockfish process manually in order not to have dangling engines eating up your RAM.

fish$go returns output before analysis is complete

When looking at a position fish$go will return an info message prior to search completion. For example: "info depth 22 currmove a3d6 currmovenumber 1"

It isn't clear how you wait for results (e.g. search to depth x). If this is straight and I've missed it perhaps adding an example to the documentation is all that is needed.

Release stockfish 0.1.1

Prepare for release:

  • Check that description is informative
  • Check licensing of included files
  • devtools::build_readme()
  • usethis::use_cran_comments()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • rhub::check(platform = 'ubuntu-rchk')
  • rhub::check_with_sanitizers()
  • rhub::check_on_solaris()
  • urlchecker::url_check()
  • Update cran-comments.md

Submit to CRAN:

  • usethis::use_version('patch')
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()
  • Update install instructions in README

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.