{"id":13512246,"url":"https://github.com/thomasahle/sunfish","last_synced_at":"2026-10-18T20:08:54.834Z","repository":{"id":13989876,"uuid":"16690938","full_name":"thomasahle/sunfish","owner":"thomasahle","description":"Sunfish: a Python Chess Engine in 111 lines of code","archived":false,"fork":false,"pushed_at":"2026-08-27T12:09:21.000Z","size":16937,"stargazers_count":3299,"open_issues_count":4,"forks_count":582,"subscribers_count":76,"default_branch":"master","last_synced_at":"2026-10-17T09:41:24.653Z","etag":null,"topics":["ai","chess","chess-ai","chess-engine","python","sunfish"],"latest_commit_sha":null,"homepage":"https://www.chessprogramming.org/Sunfish","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasahle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"accessibility":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2014-02-10T09:45:07.000Z","updated_at":"2026-10-14T22:38:03.000Z","dependencies_parsed_at":"2026-10-17T04:22:38.435Z","dependency_job_id":null,"html_url":"https://github.com/thomasahle/sunfish","commit_stats":{"total_commits":238,"total_committers":21,"mean_commits":"11.333333333333334","dds":0.5294117647058824,"last_synced_commit":"10e93383eae345c2b700657afe33b862604af20a"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/thomasahle/sunfish","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasahle%2Fsunfish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasahle%2Fsunfish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasahle%2Fsunfish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasahle%2Fsunfish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasahle","download_url":"https://codeload.github.com/thomasahle/sunfish/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasahle%2Fsunfish/sbom","scorecard":{"id":882230,"data":{"date":"2025-08-11","repo":{"name":"github.com/thomasahle/sunfish","commit":"bd5ef7b508e8d87a1bb3404b1151f65343964caf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/27 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/python-app.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-app.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/thomasahle/sunfish/python-app.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/python-app.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/thomasahle/sunfish/python-app.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:26","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:27","Warn: pipCommand not pinned by hash: .github/workflows/python-app.yml:28","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-g7vv-2v7x-gj9p"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T08:38:26.134Z","repository_id":13989876,"created_at":"2025-08-24T08:38:26.135Z","updated_at":"2025-08-24T08:38:26.135Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38333079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-17T02:00:06.547Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","chess","chess-ai","chess-engine","python","sunfish"],"created_at":"2024-08-01T03:01:38.220Z","updated_at":"2026-10-18T20:08:54.775Z","avatar_url":"https://github.com/thomasahle.png","language":"Python","funding_links":[],"categories":["Graphics and Media","Python"],"sub_categories":["Game Development"],"readme":"![Sunfish logo](https://raw.github.com/thomasahle/sunfish/master/docs/logo/sunfish_large.png)\n\nSunfish is a simple, but strong chess engine, written in Python. With its simple\n[UCI](http://wbec-ridderkerk.nl/html/UCIProtocol.html) interface, and removing comments and whitespace,\nit takes up just [126 lines of code](compressed.py)!\n\nThere is also a (somewhat) stronger NNUE based sunfish, which you can also [play against on Lichess](https://lichess.org/@/sunfish-nnue-engine).\nIt's only 4096 bytes for the whole engine, so the neuron network is very small.\n\nBecause Sunfish is small and strives to be simple, the code provides a great platform for experimenting. People have used it for testing parallel search algorithms, experimenting with evaluation functions, and developing deep learning chess programs. Fork it today and see what you can do!\n\nThe name Sunfish refers to the [Pygmy Sunfish](http://en.wikipedia.org/wiki/Pygmy_sunfish), which is among the very few fish to start with the letters 'Py'. The use of a fish is in the spirit of great engines such as Stockfish, Zappa and Rybka. In terms of Heritage, Sunfish borrows much more from [Micro-Max by Geert Muller](http://home.hccnet.nl/h.g.muller/max-src2.html) and [PyChess](http://pychess.org).\n\n## Play against sunfish!\n\nThe easiest way to play against sunfish is [@sunfish-engine on Lichess](https://lichess.org/@/sunfish-engine), where you can also play against the stronger [@sunfish-nnue-engine](https://lichess.org/@/sunfish-nnue-engine) (see more below.)\n\nThe second easiest way is to play in your terminal:\n\u003cpre\u003e\n$ \u003cb\u003epip install sunfish\u003c/b\u003e\n$ \u003cb\u003esunfish\u003c/b\u003e\n\u003c/pre\u003e\n\n![Playing sunfish in the terminal](docs/screenshot.png)\n\nOr, from a repo checkout, just run `sunfish_ui/fancy.py -cmd ./sunfish.py`.\n\n### Using sunfish with GUIs and tournament tools\n\nThe engine speaks UCI: point any tool at `sunfish-uci` (after\n`pip install sunfish`) or `./sunfish.py` (from a checkout).\n\n* **UCI GUIs** ([Arena](http://www.playwitharena.de),\n  [Cute Chess](https://cutechess.com), [PyChess](http://pychess.org),\n  BanksiaGUI): add an engine, protocol UCI, command `sunfish-uci`.\n* **WinBoard / XBoard**: use the\n  [PolyGlot](https://github.com/ddugovic/polyglot) adapter with the\n  shipped config [`tools/polyglot.ini`](tools/polyglot.ini)\n  (tested with PolyGlot 2.0.4; CI drives a real adapter session).\n* **Command-line matches** with\n  [fastchess](https://github.com/Disservin/fastchess) or\n  [cutechess-cli](https://github.com/cutechess/cutechess):\n\n      fastchess -engine cmd=sunfish-uci name=sunfish \\\n                -engine cmd=\u003cother\u003e name=other \\\n                -each proto=uci tc=30+1 -rounds 10 -games 2\n\n  (see [`docs/TESTING.md`](docs/TESTING.md) for the full methodology).\n\n\n### Troubleshooting\n\n`./sunfish.py` automatically runs with `pypy3` if installed (recommended, much stronger), otherwise `python3`.\nIf the engine fails to start, run `sunfish_ui/fancy.py` with `-debug` to see the underlying error,\nand make sure `python3` is on your PATH. On Windows, `.py` engines are launched\nthrough your current Python interpreter automatically.\n\n### Packing\n\nSunfish can also be packed into a single self-extracting executable of about 3kb:\n\u003cpre\u003e\n$ \u003cb\u003etools/build/pack.sh sunfish.py packed.sh\u003c/b\u003e\nTotal length: 3310\n$ \u003cb\u003e./packed.sh\u003c/b\u003e\n\u003cb\u003ego wtime 1000 btime 1000 winc 1000 binc 1000\u003c/b\u003e\ninfo depth 1 score cp 0 pv d2d4\nbestmove d2d4\n\u003c/pre\u003e\n\nThe packed version uses a [simplified UCI protocol by the TCEC 4k rules](https://wiki.chessdom.org/TCEC_4k_Rules#:~:text=A%204K%20UCI%20protocol%20is%20used).\n\n### NNUE version\n\n[nnue_4k/](nnue_4k/) is a sunfish whose evaluation is classic's exact\npiece-square score plus a trained neural residual — with the whole\naccumulator and evaluation head packed into **one Python integer**, so a\nwide net costs a handful of big-int operations per node. It is measured\nabout +200 Elo over classic at tournament time controls, the engine\nstill packs to a few kilobytes, and every quantized net is *certified*\n(lane-exactness, incremental == from-scratch, exact antisymmetry) before\nit plays a game. See [nnue_4k/README.md](nnue_4k/README.md) for the\narchitecture, the training pipeline, and the measured results.\n\n# Features\n\n1. Built around the simple, but efficient MTD-bi search algorithm, also known as [C*](https://www.chessprogramming.org/NegaC*).\n2. Filled with classic \"chess engine tricks\" for simpler and faster code.\n3. Efficiently updatable evaluation function through [Piece Square Tables](https://www.chessprogramming.org/Piece-Square_Tables).\n4. Uses standard Python collections and data structures for clarity and efficiency.\n\n# Testing\n\nSunfish uses pytest for testing. To run the tests:\n\n```bash\npython3.12 -m pytest\n```\n\nYou can also run specific test files:\n\n```bash\npython3.12 -m pytest tests/test_mate_puzzles.py\n```\n\nOr even specific tests:\n\n```bash\npython3.12 -m pytest tests/test_mate_puzzles.py::test_mate_in_one\n```\n\nMake sure you have installed the required dependencies (defined in `pyproject.toml`):\n\n```bash\nuv sync  # or: pip install chess tqdm pytest pytest-asyncio\n```\n\n# Limitations\n\nSunfish supports all chess rules, except the 50-move draw rule.\n\nThere are many ways in which you may try to make Sunfish stronger. First you could change from a board representation to a mutable array and add a fast way to enumerate pieces. Then you could implement dedicated capture generation, check detection and check evasions. You could also move everything to bitboards, implement parts of the code in C or experiment with parallel search!\n\nThe other way to make Sunfish stronger is to give it more knowledge of chess. The current evaluation function only uses piece square tables - it doesn't even distinguish between midgame and endgame. You can also experiment with more pruning - currently only null move is done - and extensions - currently none are used. Finally Sunfish might benefit from a more advanced move ordering, MVV/LVA and SEE perhaps?\n\nAn easy way to get a strong Sunfish is to run it with the\n[PyPy Just-In-Time interpreter](https://pypy.org/) — the launcher at the top\nof `sunfish.py` picks `pypy3` automatically when installed. Measured on the\ncurrent engine (fixed-depth battery, identical node counts): **PyPy 3.11\nsearches ~2.7x faster than CPython 3.14** (81 vs 30 knps), worth on the\norder of 100 Elo at fast time controls.\n\n(Historical footnote: sunfish once ran fastest under PyPy 2.7, and an old\nversion of this table said so. Modern sunfish requires Python \u003e= 3.8 —\nthe code uses the walrus operator — and modern PyPy 3 has long since\nclosed the gap.)\n\n\n# Family\n\nThe sunfish family keeps growing.\nHere is a (very incomplete) list of interesting derivatives:\n\n* [μSunfish](https://github.com/fizban99/micropython-usunfish) - A heavily reworked MicroPython Sunfish derivative for ESP32-class microcontrollers, with bounded memory, stronger search, configurable skill levels, and UCI support.\n* [Numbfish](https://github.com/dimdano/numbfish) - A compact Sunfish-based Python engine that adds an incrementally updated NumPy NNUE evaluation.\n* [sunfish_rs](https://github.com/Recursing/sunfish_rs) - A Rust port of Sunfish that preserves much of its search architecture while using more native Rust representations. ([Lichess bot](https://github.com/Recursing/sunfish_rs)).\n* [Carnatus](https://github.com/zserge/carnatus) - A small Go port of Sunfish intended to keep the engine minimal but readable.\n* [Sunfish.js](https://github.com/foo123/sunfish.js) - A JavaScript port of Sunfish designed to run under Node.js or directly in a browser via a web worker.\n* [Chess.Mojo](https://github.com/vietanhdev/chess.mojo) - A Sunfish-based UCI chess engine used as a proof of concept for the Mojo programming language.\n* [sunfish.lua](https://github.com/soumith/sunfish.lua) - A direct human translation of the classic Sunfish implementation from Python into Lua.\n* [Solefish](https://github.com/asandwhich/solefish) - A C++ port that deliberately follows the original Sunfish program structure closely as a learning exercise.\n* [sunfishNNUE](https://github.com/kennyfrc/sunfishNNUE) - A Sunfish derivative that replaces its classical evaluation with NNUE evaluation using Stockfish-style neural networks.\n* [Moonfish](https://github.com/walker8088/moonfish) - A Sunfish-derived engine adapted from Western chess to Chinese chess/Xiangqi with UCCI support.\n* [ParallelChessAI](https://github.com/HarshithBolar/ParallelChessAI) - A Sunfish-derived experiment investigating parallelization of chess-engine search.\n* [numworks_usunfish](https://github.com/fizban99/numworks_usunfish) - A μSunfish adaptation designed to run as a playable chess engine on NumWorks calculators.\n* [chess-badger2040](https://github.com/niutech/chess-badger2040) - A standalone offline chess game that embeds a MicroPython Sunfish port on the RP2040-based Badger 2040 e-ink device.\n* [micropython-sunfish](https://github.com/jacklinquan/micropython-sunfish) - An early port of Sunfish to MicroPython for running the engine on constrained embedded hardware.\n* [peterhinch/micropython-sunfish](https://github.com/peterhinch/micropython-sunfish) - Another independent MicroPython adaptation that makes Sunfish usable as an embedded chess-engine component.\n* [Vector-Anki-Sunfish](https://github.com/mth75/Vector-Anki-Sunfish) - A project integrating Sunfish with the Anki Vector robot to let the robot participate in chess.\n* [chess-genetic-algorithm-sunfish](https://github.com/Daspy11/chess-genetic-algorithm-sunfish) - An experimental Sunfish derivative using genetic algorithms to evolve or tune chess-engine parameters.\n* [sunfishDDA](https://github.com/zqigolden/sunfishDDA) - A Sunfish experiment exploring dynamic difficulty adjustment rather than simply maximizing engine strength.\n* [Blindfold-Sunfish](https://github.com/sjqtentacles/Blindfold-Sunfish) - A Sunfish modification aimed at blindfold chess and alternative ways of interacting with the engine.\n* [Moonfish](https://moonfish.cc/) - A tiny C chess engine originally inspired by Sunfish that subsequently developed its own substantially different implementation and search approach.\n\n# License\n\n[GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasahle%2Fsunfish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasahle%2Fsunfish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasahle%2Fsunfish/lists"}