Spaces:
Running
Running
Delete Fairy-Stockfish-master
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- Fairy-Stockfish-master/.gitattributes +0 -1
- Fairy-Stockfish-master/.github/FUNDING.yml +0 -2
- Fairy-Stockfish-master/.github/dependabot.yml +0 -13
- Fairy-Stockfish-master/.github/workflows/fairy.yml +0 -93
- Fairy-Stockfish-master/.github/workflows/ffishjs.yml +0 -90
- Fairy-Stockfish-master/.github/workflows/release.yml +0 -116
- Fairy-Stockfish-master/.github/workflows/stockfish.yml +0 -213
- Fairy-Stockfish-master/.github/workflows/wheels.yml +0 -57
- Fairy-Stockfish-master/.gitignore +0 -43
- Fairy-Stockfish-master/AGENTS.md +0 -158
- Fairy-Stockfish-master/AUTHORS +0 -231
- Fairy-Stockfish-master/Copying.txt +0 -674
- Fairy-Stockfish-master/MANIFEST.in +0 -2
- Fairy-Stockfish-master/README.md +0 -126
- Fairy-Stockfish-master/Top CPU Contributors.txt +0 -205
- Fairy-Stockfish-master/appveyor.yml +0 -91
- Fairy-Stockfish-master/pyffish.pyi +0 -39
- Fairy-Stockfish-master/setup.py +0 -56
- Fairy-Stockfish-master/src/Makefile +0 -982
- Fairy-Stockfish-master/src/Makefile_js +0 -95
- Fairy-Stockfish-master/src/apiutil.h +0 -1165
- Fairy-Stockfish-master/src/benchmark.cpp +0 -195
- Fairy-Stockfish-master/src/bitbase.cpp +0 -177
- Fairy-Stockfish-master/src/bitboard.cpp +0 -501
- Fairy-Stockfish-master/src/bitboard.h +0 -787
- Fairy-Stockfish-master/src/endgame.cpp +0 -1321
- Fairy-Stockfish-master/src/endgame.h +0 -148
- Fairy-Stockfish-master/src/evaluate.cpp +0 -1736
- Fairy-Stockfish-master/src/evaluate.h +0 -66
- Fairy-Stockfish-master/src/ffishjs.cpp +0 -767
- Fairy-Stockfish-master/src/incbin/UNLICENCE +0 -26
- Fairy-Stockfish-master/src/incbin/incbin.h +0 -368
- Fairy-Stockfish-master/src/magic.h +0 -1741
- Fairy-Stockfish-master/src/main.cpp +0 -63
- Fairy-Stockfish-master/src/material.cpp +0 -321
- Fairy-Stockfish-master/src/material.h +0 -75
- Fairy-Stockfish-master/src/misc.cpp +0 -656
- Fairy-Stockfish-master/src/misc.h +0 -200
- Fairy-Stockfish-master/src/movegen.cpp +0 -528
- Fairy-Stockfish-master/src/movegen.h +0 -107
- Fairy-Stockfish-master/src/movepick.cpp +0 -279
- Fairy-Stockfish-master/src/movepick.h +0 -169
- Fairy-Stockfish-master/src/nnue/evaluate_nnue.cpp +0 -443
- Fairy-Stockfish-master/src/nnue/evaluate_nnue.h +0 -59
- Fairy-Stockfish-master/src/nnue/features/half_ka_v2.cpp +0 -90
- Fairy-Stockfish-master/src/nnue/features/half_ka_v2.h +0 -152
- Fairy-Stockfish-master/src/nnue/features/half_ka_v2_variants.cpp +0 -112
- Fairy-Stockfish-master/src/nnue/features/half_ka_v2_variants.h +0 -94
- Fairy-Stockfish-master/src/nnue/layers/affine_transform.h +0 -435
- Fairy-Stockfish-master/src/nnue/layers/clipped_relu.h +0 -191
Fairy-Stockfish-master/.gitattributes
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
README.md merge=ours
|
|
|
|
|
|
Fairy-Stockfish-master/.github/FUNDING.yml
DELETED
|
@@ -1,2 +0,0 @@
|
|
| 1 |
-
# These are supported funding model platforms
|
| 2 |
-
github: ianfab
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/dependabot.yml
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
# Keep GitHub Actions up to date with GitHub's Dependabot...
|
| 2 |
-
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
|
| 3 |
-
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
|
| 4 |
-
version: 2
|
| 5 |
-
updates:
|
| 6 |
-
- package-ecosystem: github-actions
|
| 7 |
-
directory: /
|
| 8 |
-
groups:
|
| 9 |
-
github-actions:
|
| 10 |
-
patterns:
|
| 11 |
-
- "*" # Group all Actions updates into a single larger pull request
|
| 12 |
-
schedule:
|
| 13 |
-
interval: weekly
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/workflows/fairy.yml
DELETED
|
@@ -1,93 +0,0 @@
|
|
| 1 |
-
name: fairy
|
| 2 |
-
on:
|
| 3 |
-
push:
|
| 4 |
-
branches:
|
| 5 |
-
- master
|
| 6 |
-
pull_request:
|
| 7 |
-
branches:
|
| 8 |
-
- master
|
| 9 |
-
jobs:
|
| 10 |
-
fairy:
|
| 11 |
-
name: ${{ matrix.config.name }}
|
| 12 |
-
runs-on: ${{ matrix.config.os }}
|
| 13 |
-
env:
|
| 14 |
-
COMPILER: ${{ matrix.config.compiler }}
|
| 15 |
-
COMP: ${{ matrix.config.comp }}
|
| 16 |
-
CXXFLAGS: "-Werror"
|
| 17 |
-
strategy:
|
| 18 |
-
matrix:
|
| 19 |
-
config:
|
| 20 |
-
- {
|
| 21 |
-
name: "Ubuntu 24.04 GCC",
|
| 22 |
-
os: ubuntu-24.04,
|
| 23 |
-
compiler: g++,
|
| 24 |
-
comp: gcc,
|
| 25 |
-
run_expensive_tests: true
|
| 26 |
-
}
|
| 27 |
-
- {
|
| 28 |
-
name: "Ubuntu 24.04 Clang",
|
| 29 |
-
os: ubuntu-24.04,
|
| 30 |
-
compiler: clang++,
|
| 31 |
-
comp: clang,
|
| 32 |
-
run_expensive_tests: false
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
defaults:
|
| 36 |
-
run:
|
| 37 |
-
working-directory: src
|
| 38 |
-
steps:
|
| 39 |
-
- uses: actions/checkout@v6
|
| 40 |
-
with:
|
| 41 |
-
fetch-depth: 0
|
| 42 |
-
|
| 43 |
-
- name: Download required packages
|
| 44 |
-
run: |
|
| 45 |
-
sudo apt update
|
| 46 |
-
sudo apt install expect valgrind g++-multilib
|
| 47 |
-
|
| 48 |
-
- name: Download the used network from the fishtest framework
|
| 49 |
-
run: |
|
| 50 |
-
make net
|
| 51 |
-
|
| 52 |
-
- name: Test NNUE
|
| 53 |
-
run: |
|
| 54 |
-
make clean
|
| 55 |
-
make -j2 ARCH=x86-64 nnue=yes debug=yes build
|
| 56 |
-
./stockfish bench
|
| 57 |
-
|
| 58 |
-
- name: Test NNUE largeboards
|
| 59 |
-
run: |
|
| 60 |
-
make clean
|
| 61 |
-
make -j2 ARCH=x86-64 largeboards=yes nnue=yes debug=yes build
|
| 62 |
-
./stockfish bench
|
| 63 |
-
|
| 64 |
-
- name: Build all variants
|
| 65 |
-
run: |
|
| 66 |
-
make clean
|
| 67 |
-
make -j2 ARCH=x86-64 largeboards=yes all=yes debug=yes build
|
| 68 |
-
|
| 69 |
-
- name: Test protocols
|
| 70 |
-
run: |
|
| 71 |
-
../tests/protocol.sh
|
| 72 |
-
|
| 73 |
-
- name: Test variants.ini
|
| 74 |
-
run: |
|
| 75 |
-
! ./stockfish check variants.ini 2>&1 >/dev/null | grep -v "Parsing variant"
|
| 76 |
-
|
| 77 |
-
- name: Test variant perft
|
| 78 |
-
run: |
|
| 79 |
-
../tests/perft.sh all
|
| 80 |
-
|
| 81 |
-
- name: Test variant bench
|
| 82 |
-
run: |
|
| 83 |
-
./stockfish bench xiangqi
|
| 84 |
-
./stockfish bench shogi
|
| 85 |
-
./stockfish bench capablanca
|
| 86 |
-
./stockfish bench sittuyin
|
| 87 |
-
|
| 88 |
-
- name: Test 32bit largeboards
|
| 89 |
-
run: |
|
| 90 |
-
if [[ "$COMP" == "gcc" ]]; then export EXTRACXXFLAGS=-Wno-class-memaccess; fi
|
| 91 |
-
make clean
|
| 92 |
-
make -j2 ARCH=x86-32 largeboards=yes build
|
| 93 |
-
../tests/perft.sh largeboard
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/workflows/ffishjs.yml
DELETED
|
@@ -1,90 +0,0 @@
|
|
| 1 |
-
name: ffishjs
|
| 2 |
-
|
| 3 |
-
on:
|
| 4 |
-
push:
|
| 5 |
-
branches: [ master ]
|
| 6 |
-
pull_request:
|
| 7 |
-
branches: [ master ]
|
| 8 |
-
|
| 9 |
-
env:
|
| 10 |
-
EM_VERSION: 1.39.16
|
| 11 |
-
EM_CACHE_FOLDER: 'emsdk-cache'
|
| 12 |
-
|
| 13 |
-
jobs:
|
| 14 |
-
test:
|
| 15 |
-
runs-on: ubuntu-24.04
|
| 16 |
-
|
| 17 |
-
strategy:
|
| 18 |
-
matrix:
|
| 19 |
-
node-version: [12.x]
|
| 20 |
-
|
| 21 |
-
steps:
|
| 22 |
-
- uses: actions/checkout@v6
|
| 23 |
-
- name: Setup cache
|
| 24 |
-
id: cache-system-libraries
|
| 25 |
-
uses: actions/cache@v5
|
| 26 |
-
with:
|
| 27 |
-
path: ${{env.EM_CACHE_FOLDER}}
|
| 28 |
-
key: emsdk-${{env.EM_VERSION}}-${{ runner.os }}
|
| 29 |
-
- uses: mymindstorm/setup-emsdk@v16
|
| 30 |
-
with:
|
| 31 |
-
version: ${{env.EM_VERSION}}
|
| 32 |
-
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
| 33 |
-
- name: Use Node.js ${{ matrix.node-version }}
|
| 34 |
-
uses: actions/setup-node@v6
|
| 35 |
-
with:
|
| 36 |
-
node-version: ${{ matrix.node-version }}
|
| 37 |
-
- name: Build ffishjs
|
| 38 |
-
working-directory: src
|
| 39 |
-
run: make -f Makefile_js build debug=yes
|
| 40 |
-
- name: Install dependencies
|
| 41 |
-
working-directory: tests/js
|
| 42 |
-
run: npm install
|
| 43 |
-
- name: Run unit tests
|
| 44 |
-
working-directory: tests/js
|
| 45 |
-
run: npm test
|
| 46 |
-
|
| 47 |
-
build:
|
| 48 |
-
runs-on: ubuntu-24.04
|
| 49 |
-
needs: [test] #Building process must start after successful testing process
|
| 50 |
-
|
| 51 |
-
strategy:
|
| 52 |
-
matrix:
|
| 53 |
-
node-version: [12.x]
|
| 54 |
-
|
| 55 |
-
steps:
|
| 56 |
-
- uses: actions/checkout@v6
|
| 57 |
-
- name: Setup cache
|
| 58 |
-
id: cache-system-libraries
|
| 59 |
-
uses: actions/cache@v5
|
| 60 |
-
with:
|
| 61 |
-
path: ${{env.EM_CACHE_FOLDER}}
|
| 62 |
-
key: emsdk-${{env.EM_VERSION}}-${{ runner.os }}
|
| 63 |
-
- uses: mymindstorm/setup-emsdk@v16
|
| 64 |
-
with:
|
| 65 |
-
version: ${{env.EM_VERSION}}
|
| 66 |
-
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
| 67 |
-
- name: Use Node.js ${{ matrix.node-version }}
|
| 68 |
-
uses: actions/setup-node@v6
|
| 69 |
-
with:
|
| 70 |
-
node-version: ${{ matrix.node-version }}
|
| 71 |
-
- name: Build ffish.js ES6/ES2015 module
|
| 72 |
-
working-directory: src
|
| 73 |
-
run: rm -f ../tests/js/ffish.js & rm -f ../tests/js/ffish.wasm & make -f Makefile_js build es6=yes
|
| 74 |
-
- name: Upload ffish.js ES6/ES2015 module ZIP archive
|
| 75 |
-
uses: actions/upload-artifact@v7
|
| 76 |
-
with:
|
| 77 |
-
name: ffishjs-es6
|
| 78 |
-
path: tests/js/*
|
| 79 |
-
if-no-files-found: error
|
| 80 |
-
compression-level: 9
|
| 81 |
-
- name: Build ffish.js standard module
|
| 82 |
-
working-directory: src
|
| 83 |
-
run: rm -f ../tests/js/ffish.js & rm -f ../tests/js/ffish.wasm & make -f Makefile_js build
|
| 84 |
-
- name: Upload ffish.js standard module ZIP archive
|
| 85 |
-
uses: actions/upload-artifact@v7
|
| 86 |
-
with:
|
| 87 |
-
name: ffishjs-standard
|
| 88 |
-
path: tests/js/*
|
| 89 |
-
if-no-files-found: error
|
| 90 |
-
compression-level: 9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/workflows/release.yml
DELETED
|
@@ -1,116 +0,0 @@
|
|
| 1 |
-
name: Release
|
| 2 |
-
|
| 3 |
-
on:
|
| 4 |
-
push:
|
| 5 |
-
branches: [ master ]
|
| 6 |
-
pull_request:
|
| 7 |
-
branches: [ master ]
|
| 8 |
-
|
| 9 |
-
jobs:
|
| 10 |
-
windows:
|
| 11 |
-
strategy:
|
| 12 |
-
matrix:
|
| 13 |
-
arch: ["x86-64-bmi2", "x86-64-modern", "x86-64"]
|
| 14 |
-
runs-on: windows-2022
|
| 15 |
-
|
| 16 |
-
steps:
|
| 17 |
-
- uses: al-cheb/configure-pagefile-action@v1.5
|
| 18 |
-
with:
|
| 19 |
-
minimum-size: 16GB
|
| 20 |
-
maximum-size: 16GB
|
| 21 |
-
disk-root: "C:"
|
| 22 |
-
|
| 23 |
-
- uses: actions/checkout@v6
|
| 24 |
-
|
| 25 |
-
- name: make
|
| 26 |
-
run: cd src && make clean && make -j build COMP=mingw ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }}.exe && strip fairy-stockfish_${{ matrix.arch }}.exe
|
| 27 |
-
|
| 28 |
-
- name: make largeboards
|
| 29 |
-
run: cd src && make clean && make -j build COMP=mingw ARCH=${{ matrix.arch }} EXE=fairy-stockfish-largeboards_${{ matrix.arch }}.exe largeboards=yes && strip fairy-stockfish-largeboards_${{ matrix.arch }}.exe
|
| 30 |
-
|
| 31 |
-
- name: make all
|
| 32 |
-
if: ${{ matrix.arch == 'x86-64' }}
|
| 33 |
-
run: cd src && make clean && make -j build COMP=mingw ARCH=${{ matrix.arch }} EXE=fairy-stockfish-all_${{ matrix.arch }}.exe largeboards=yes all=yes && strip fairy-stockfish-all_${{ matrix.arch }}.exe
|
| 34 |
-
|
| 35 |
-
- uses: actions/upload-artifact@v7
|
| 36 |
-
with:
|
| 37 |
-
name: fairy-stockfish-windows-${{ matrix.arch }}
|
| 38 |
-
path: src/fairy-stockfish*.exe
|
| 39 |
-
if-no-files-found: error
|
| 40 |
-
compression-level: 9
|
| 41 |
-
|
| 42 |
-
linux:
|
| 43 |
-
strategy:
|
| 44 |
-
matrix:
|
| 45 |
-
arch: ["x86-64-bmi2", "x86-64-modern", "x86-64"]
|
| 46 |
-
runs-on: ubuntu-24.04
|
| 47 |
-
|
| 48 |
-
steps:
|
| 49 |
-
- uses: actions/checkout@v6
|
| 50 |
-
|
| 51 |
-
- name: make
|
| 52 |
-
run: cd src && make clean && make -j build COMP=gcc ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}
|
| 53 |
-
|
| 54 |
-
- name: make largeboards
|
| 55 |
-
run: cd src && make clean && make -j build COMP=gcc ARCH=${{ matrix.arch }} EXE=fairy-stockfish-largeboards_${{ matrix.arch }} largeboards=yes && strip fairy-stockfish-largeboards_${{ matrix.arch }}
|
| 56 |
-
|
| 57 |
-
- name: make all
|
| 58 |
-
if: ${{ matrix.arch == 'x86-64' }}
|
| 59 |
-
run: cd src && make clean && make -j build COMP=gcc ARCH=${{ matrix.arch }} EXE=fairy-stockfish-all_${{ matrix.arch }} largeboards=yes all=yes && strip fairy-stockfish-all_${{ matrix.arch }}
|
| 60 |
-
|
| 61 |
-
- uses: actions/upload-artifact@v7
|
| 62 |
-
with:
|
| 63 |
-
name: fairy-stockfish-linux-${{ matrix.arch }}
|
| 64 |
-
path: src/fairy-stockfish*
|
| 65 |
-
if-no-files-found: error
|
| 66 |
-
compression-level: 9
|
| 67 |
-
|
| 68 |
-
macos:
|
| 69 |
-
strategy:
|
| 70 |
-
matrix:
|
| 71 |
-
arch: ["x86-64"]
|
| 72 |
-
runs-on: macos-15-intel
|
| 73 |
-
|
| 74 |
-
steps:
|
| 75 |
-
- uses: actions/checkout@v6
|
| 76 |
-
|
| 77 |
-
- name: make
|
| 78 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}
|
| 79 |
-
|
| 80 |
-
- name: make largeboards
|
| 81 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish-largeboards_${{ matrix.arch }} largeboards=yes && strip fairy-stockfish-largeboards_${{ matrix.arch }}
|
| 82 |
-
|
| 83 |
-
- name: make all
|
| 84 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish-all_${{ matrix.arch }} largeboards=yes all=yes && strip fairy-stockfish-all_${{ matrix.arch }}
|
| 85 |
-
|
| 86 |
-
- uses: actions/upload-artifact@v7
|
| 87 |
-
with:
|
| 88 |
-
name: fairy-stockfish-macos-${{ matrix.arch }}
|
| 89 |
-
path: src/fairy-stockfish*
|
| 90 |
-
if-no-files-found: error
|
| 91 |
-
compression-level: 9
|
| 92 |
-
|
| 93 |
-
macos-m1:
|
| 94 |
-
strategy:
|
| 95 |
-
matrix:
|
| 96 |
-
arch: ["apple-silicon"]
|
| 97 |
-
runs-on: macos-14
|
| 98 |
-
|
| 99 |
-
steps:
|
| 100 |
-
- uses: actions/checkout@v6
|
| 101 |
-
|
| 102 |
-
- name: make
|
| 103 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}
|
| 104 |
-
|
| 105 |
-
- name: make largeboards
|
| 106 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish-largeboards_${{ matrix.arch }} largeboards=yes && strip fairy-stockfish-largeboards_${{ matrix.arch }}
|
| 107 |
-
|
| 108 |
-
- name: make all
|
| 109 |
-
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish-all_${{ matrix.arch }} largeboards=yes all=yes && strip fairy-stockfish-all_${{ matrix.arch }}
|
| 110 |
-
|
| 111 |
-
- uses: actions/upload-artifact@v7
|
| 112 |
-
with:
|
| 113 |
-
name: fairy-stockfish-macos-m1-${{ matrix.arch }}
|
| 114 |
-
path: src/fairy-stockfish*
|
| 115 |
-
if-no-files-found: error
|
| 116 |
-
compression-level: 9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/workflows/stockfish.yml
DELETED
|
@@ -1,213 +0,0 @@
|
|
| 1 |
-
name: Stockfish
|
| 2 |
-
on:
|
| 3 |
-
push:
|
| 4 |
-
branches:
|
| 5 |
-
- master
|
| 6 |
-
- tools
|
| 7 |
-
- github_ci
|
| 8 |
-
pull_request:
|
| 9 |
-
branches:
|
| 10 |
-
- master
|
| 11 |
-
- tools
|
| 12 |
-
jobs:
|
| 13 |
-
Stockfish:
|
| 14 |
-
name: ${{ matrix.config.name }}
|
| 15 |
-
runs-on: ${{ matrix.config.os }}
|
| 16 |
-
env:
|
| 17 |
-
COMPILER: ${{ matrix.config.compiler }}
|
| 18 |
-
COMP: ${{ matrix.config.comp }}
|
| 19 |
-
CXXFLAGS: "-Werror"
|
| 20 |
-
strategy:
|
| 21 |
-
matrix:
|
| 22 |
-
config:
|
| 23 |
-
- {
|
| 24 |
-
name: "Ubuntu 24.04 GCC",
|
| 25 |
-
os: ubuntu-24.04,
|
| 26 |
-
compiler: g++,
|
| 27 |
-
comp: gcc,
|
| 28 |
-
run_expensive_tests: true
|
| 29 |
-
}
|
| 30 |
-
- {
|
| 31 |
-
name: "Ubuntu 24.04 Clang",
|
| 32 |
-
os: ubuntu-24.04,
|
| 33 |
-
compiler: clang++,
|
| 34 |
-
comp: clang,
|
| 35 |
-
run_expensive_tests: false
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
defaults:
|
| 39 |
-
run:
|
| 40 |
-
working-directory: src
|
| 41 |
-
steps:
|
| 42 |
-
- uses: actions/checkout@v6
|
| 43 |
-
with:
|
| 44 |
-
fetch-depth: 0
|
| 45 |
-
|
| 46 |
-
- name: Download required packages
|
| 47 |
-
run: |
|
| 48 |
-
sudo apt update
|
| 49 |
-
sudo apt install expect valgrind g++-multilib llvm
|
| 50 |
-
|
| 51 |
-
- name: Download the used network from the fishtest framework
|
| 52 |
-
run: |
|
| 53 |
-
make net
|
| 54 |
-
|
| 55 |
-
- name: Extract the bench number from the commit history
|
| 56 |
-
run: |
|
| 57 |
-
git log HEAD | grep "\b[Bb]ench[ :]\+[0-9]\{7\}" | head -n 1 | sed "s/[^0-9]*\([0-9]*\).*/\1/g" > git_sig
|
| 58 |
-
[ -s git_sig ] && echo "benchref=$(cat git_sig)" >> $GITHUB_ENV && echo "Reference bench:" $(cat git_sig) || echo "No bench found"
|
| 59 |
-
|
| 60 |
-
- name: Check compiler
|
| 61 |
-
run: |
|
| 62 |
-
$COMPILER -v
|
| 63 |
-
|
| 64 |
-
- name: Test help target
|
| 65 |
-
run: |
|
| 66 |
-
make help
|
| 67 |
-
|
| 68 |
-
# x86-32 tests
|
| 69 |
-
|
| 70 |
-
- name: Test debug x86-32 build
|
| 71 |
-
run: |
|
| 72 |
-
export CXXFLAGS="-Werror -D_GLIBCXX_DEBUG"
|
| 73 |
-
make clean
|
| 74 |
-
make -j2 ARCH=x86-32 optimize=no debug=yes build
|
| 75 |
-
../tests/signature.sh $benchref
|
| 76 |
-
|
| 77 |
-
- name: Test debug x86-32 profile build (Optimization on, All features)
|
| 78 |
-
run: |
|
| 79 |
-
export CXXFLAGS=""
|
| 80 |
-
make clean
|
| 81 |
-
make -j2 ARCH=x86-32 optimize=yes all=yes largeboards=yes debug=yes profile-build
|
| 82 |
-
|
| 83 |
-
- name: Test x86-32 build
|
| 84 |
-
run: |
|
| 85 |
-
make clean
|
| 86 |
-
make -j2 ARCH=x86-32 build
|
| 87 |
-
../tests/signature.sh $benchref
|
| 88 |
-
|
| 89 |
-
- name: Test x86-32-sse41-popcnt build
|
| 90 |
-
run: |
|
| 91 |
-
make clean
|
| 92 |
-
make -j2 ARCH=x86-32-sse41-popcnt build
|
| 93 |
-
../tests/signature.sh $benchref
|
| 94 |
-
|
| 95 |
-
- name: Test x86-32-sse2 build
|
| 96 |
-
run: |
|
| 97 |
-
make clean
|
| 98 |
-
make -j2 ARCH=x86-32-sse2 build
|
| 99 |
-
../tests/signature.sh $benchref
|
| 100 |
-
|
| 101 |
-
- name: Test general-32 build
|
| 102 |
-
run: |
|
| 103 |
-
make clean
|
| 104 |
-
make -j2 ARCH=general-32 build
|
| 105 |
-
../tests/signature.sh $benchref
|
| 106 |
-
|
| 107 |
-
# x86-64 tests
|
| 108 |
-
|
| 109 |
-
- name: Test debug x86-64-modern build
|
| 110 |
-
run: |
|
| 111 |
-
export CXXFLAGS="-Werror -D_GLIBCXX_DEBUG"
|
| 112 |
-
make clean
|
| 113 |
-
make -j2 ARCH=x86-64-modern optimize=no debug=yes build
|
| 114 |
-
../tests/signature.sh $benchref
|
| 115 |
-
|
| 116 |
-
- name: Test debug x86-64-modern profile build (Optimization on, All features)
|
| 117 |
-
run: |
|
| 118 |
-
export CXXFLAGS=""
|
| 119 |
-
make clean
|
| 120 |
-
make -j2 ARCH=x86-64-modern optimize=yes all=yes largeboards=yes debug=yes profile-build
|
| 121 |
-
|
| 122 |
-
- name: Test x86-64-modern build
|
| 123 |
-
run: |
|
| 124 |
-
make clean
|
| 125 |
-
make -j2 ARCH=x86-64-modern build
|
| 126 |
-
../tests/signature.sh $benchref
|
| 127 |
-
|
| 128 |
-
- name: Test x86-64-ssse3 build
|
| 129 |
-
run: |
|
| 130 |
-
make clean
|
| 131 |
-
make -j2 ARCH=x86-64-ssse3 build
|
| 132 |
-
../tests/signature.sh $benchref
|
| 133 |
-
|
| 134 |
-
- name: Test x86-64-sse3-popcnt build
|
| 135 |
-
run: |
|
| 136 |
-
make clean
|
| 137 |
-
make -j2 ARCH=x86-64-sse3-popcnt build
|
| 138 |
-
../tests/signature.sh $benchref
|
| 139 |
-
|
| 140 |
-
- name: Test x86-64 build
|
| 141 |
-
run: |
|
| 142 |
-
make clean
|
| 143 |
-
make -j2 ARCH=x86-64 build
|
| 144 |
-
../tests/signature.sh $benchref
|
| 145 |
-
|
| 146 |
-
- name: Test general-64 build
|
| 147 |
-
run: |
|
| 148 |
-
make clean
|
| 149 |
-
make -j2 ARCH=general-64 build
|
| 150 |
-
../tests/signature.sh $benchref
|
| 151 |
-
|
| 152 |
-
# x86-64 with newer extensions tests
|
| 153 |
-
|
| 154 |
-
- name: Compile x86-64-avx2 build
|
| 155 |
-
run: |
|
| 156 |
-
make clean
|
| 157 |
-
make -j2 ARCH=x86-64-avx2 build
|
| 158 |
-
|
| 159 |
-
- name: Compile x86-64-bmi2 build
|
| 160 |
-
run: |
|
| 161 |
-
make clean
|
| 162 |
-
make -j2 ARCH=x86-64-bmi2 build
|
| 163 |
-
|
| 164 |
-
- name: Compile x86-64-avx512 build
|
| 165 |
-
run: |
|
| 166 |
-
make clean
|
| 167 |
-
make -j2 ARCH=x86-64-avx512 build
|
| 168 |
-
|
| 169 |
-
- name: Compile x86-64-vnni512 build
|
| 170 |
-
run: |
|
| 171 |
-
make clean
|
| 172 |
-
make -j2 ARCH=x86-64-vnni512 build
|
| 173 |
-
|
| 174 |
-
- name: Compile x86-64-vnni256 build
|
| 175 |
-
run: |
|
| 176 |
-
make clean
|
| 177 |
-
make -j2 ARCH=x86-64-vnni256 build
|
| 178 |
-
|
| 179 |
-
# Other tests
|
| 180 |
-
|
| 181 |
-
- name: Check perft and search reproducibility
|
| 182 |
-
run: |
|
| 183 |
-
make clean
|
| 184 |
-
make -j2 ARCH=x86-64-modern build
|
| 185 |
-
../tests/perft.sh
|
| 186 |
-
../tests/reprosearch.sh
|
| 187 |
-
|
| 188 |
-
# Sanitizers
|
| 189 |
-
|
| 190 |
-
- name: Run under valgrind
|
| 191 |
-
if: ${{ matrix.config.run_expensive_tests }}
|
| 192 |
-
run: |
|
| 193 |
-
export CXXFLAGS="-O1 -fno-inline"
|
| 194 |
-
make clean
|
| 195 |
-
make -j2 ARCH=x86-64-modern debug=yes optimize=no build > /dev/null
|
| 196 |
-
../tests/instrumented.sh --valgrind
|
| 197 |
-
../tests/instrumented.sh --valgrind-thread
|
| 198 |
-
|
| 199 |
-
- name: Run with UB sanitizer
|
| 200 |
-
if: ${{ matrix.config.run_expensive_tests }}
|
| 201 |
-
run: |
|
| 202 |
-
export CXXFLAGS="-O1 -fno-inline"
|
| 203 |
-
make clean
|
| 204 |
-
make -j2 ARCH=x86-64-modern sanitize=undefined optimize=no debug=yes build > /dev/null
|
| 205 |
-
../tests/instrumented.sh --sanitizer-undefined
|
| 206 |
-
|
| 207 |
-
- name: Run with thread sanitizer
|
| 208 |
-
if: ${{ matrix.config.run_expensive_tests }}
|
| 209 |
-
run: |
|
| 210 |
-
export CXXFLAGS="-O1 -fno-inline"
|
| 211 |
-
make clean
|
| 212 |
-
make -j2 ARCH=x86-64-modern sanitize=thread optimize=no debug=yes build > /dev/null
|
| 213 |
-
../tests/instrumented.sh --sanitizer-thread
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.github/workflows/wheels.yml
DELETED
|
@@ -1,57 +0,0 @@
|
|
| 1 |
-
name: Wheels
|
| 2 |
-
|
| 3 |
-
on:
|
| 4 |
-
push:
|
| 5 |
-
branches:
|
| 6 |
-
- master
|
| 7 |
-
pull_request:
|
| 8 |
-
branches:
|
| 9 |
-
- master
|
| 10 |
-
|
| 11 |
-
jobs:
|
| 12 |
-
build_wheels:
|
| 13 |
-
name: Build wheels on ${{ matrix.os }}
|
| 14 |
-
runs-on: ${{ matrix.os }}
|
| 15 |
-
strategy:
|
| 16 |
-
matrix:
|
| 17 |
-
os: [ubuntu-24.04, windows-2022, macos-14]
|
| 18 |
-
|
| 19 |
-
steps:
|
| 20 |
-
- uses: actions/checkout@v6
|
| 21 |
-
|
| 22 |
-
# Used to host cibuildwheel
|
| 23 |
-
- uses: actions/setup-python@v6
|
| 24 |
-
|
| 25 |
-
- name: Install cibuildwheel
|
| 26 |
-
run: python -m pip install cibuildwheel==3.4.0
|
| 27 |
-
|
| 28 |
-
- name: Build wheels
|
| 29 |
-
run: python -m cibuildwheel --output-dir wheelhouse
|
| 30 |
-
# to supply options, put them in 'env', like:
|
| 31 |
-
env:
|
| 32 |
-
MACOSX_DEPLOYMENT_TARGET: "10.14"
|
| 33 |
-
CIBW_ARCHS_MACOS: "x86_64 arm64"
|
| 34 |
-
CIBW_SKIP: "pp* *-win32 *-manylinux_i686 *-musllinux_* cp36-* cp37-* cp38"
|
| 35 |
-
CIBW_TEST_COMMAND: python {project}/test.py
|
| 36 |
-
|
| 37 |
-
- uses: actions/upload-artifact@v7
|
| 38 |
-
with:
|
| 39 |
-
name: dist-wheel-${{ matrix.os }}
|
| 40 |
-
path: ./wheelhouse/*.whl
|
| 41 |
-
|
| 42 |
-
build_sdist:
|
| 43 |
-
name: Build source distribution
|
| 44 |
-
runs-on: ubuntu-24.04
|
| 45 |
-
steps:
|
| 46 |
-
- uses: actions/checkout@v6
|
| 47 |
-
- uses: actions/setup-python@v6
|
| 48 |
-
with:
|
| 49 |
-
python-version: '3.9'
|
| 50 |
-
|
| 51 |
-
- name: Build sdist
|
| 52 |
-
run: python setup.py sdist
|
| 53 |
-
|
| 54 |
-
- uses: actions/upload-artifact@v7
|
| 55 |
-
with:
|
| 56 |
-
name: dist-source
|
| 57 |
-
path: dist/*.tar.gz
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/.gitignore
DELETED
|
@@ -1,43 +0,0 @@
|
|
| 1 |
-
# Ignore binaries in src/ that have no extension
|
| 2 |
-
/src/*
|
| 3 |
-
!/src/*.*
|
| 4 |
-
!/src/*/
|
| 5 |
-
|
| 6 |
-
# Files from build
|
| 7 |
-
**/*.o
|
| 8 |
-
**/*.s
|
| 9 |
-
src/.depend
|
| 10 |
-
|
| 11 |
-
# Built binary
|
| 12 |
-
src/stockfish*
|
| 13 |
-
src/-lstdc++.res
|
| 14 |
-
|
| 15 |
-
# Neural network for the NNUE evaluation
|
| 16 |
-
**/*.nnue
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
# Build/test artifacts
|
| 20 |
-
*.exe
|
| 21 |
-
tests/syzygy
|
| 22 |
-
|
| 23 |
-
# ffishjs
|
| 24 |
-
tests/js/node_modules
|
| 25 |
-
ffish.js
|
| 26 |
-
*.wasm
|
| 27 |
-
|
| 28 |
-
# pyffish
|
| 29 |
-
venv
|
| 30 |
-
*.so
|
| 31 |
-
pyffish.egg-info
|
| 32 |
-
__pycache__
|
| 33 |
-
*.pyc
|
| 34 |
-
|
| 35 |
-
# test artifacts
|
| 36 |
-
tests/*.exp
|
| 37 |
-
src/*.log
|
| 38 |
-
src/*.epd
|
| 39 |
-
src/*.txt
|
| 40 |
-
|
| 41 |
-
# IDEs
|
| 42 |
-
.vscode
|
| 43 |
-
.idea
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/AGENTS.md
DELETED
|
@@ -1,158 +0,0 @@
|
|
| 1 |
-
# Fairy-Stockfish Development Guide
|
| 2 |
-
|
| 3 |
-
## Repository Overview
|
| 4 |
-
|
| 5 |
-
**Fairy-Stockfish** is a chess variant engine derived from Stockfish, designed to support numerous chess variants and protocols. Written primarily in C++17, it includes Python and JavaScript bindings for library use.
|
| 6 |
-
|
| 7 |
-
**Repository Statistics:**
|
| 8 |
-
- **Languages:** C++17 (primary), Python, JavaScript, Shell scripts
|
| 9 |
-
- **Architecture:** Multi-protocol chess engine (UCI, UCCI, USI, XBoard/CECP)
|
| 10 |
-
- **Target Platforms:** Windows, Linux, macOS, Android, WebAssembly
|
| 11 |
-
- **Supported Variants:** 90+ chess variants including regional, historical, and modern variants
|
| 12 |
-
|
| 13 |
-
## Build System & Requirements
|
| 14 |
-
|
| 15 |
-
### Prerequisites
|
| 16 |
-
- **Compiler:** GCC, Clang, or MSVC with C++17 support
|
| 17 |
-
- **Build Tool:** GNU Make (required for C++ engine)
|
| 18 |
-
- **Python:** 3.7+ (for Python bindings)
|
| 19 |
-
- **Node.js:** (for JavaScript bindings)
|
| 20 |
-
- **Additional Tools:** expect utility (for testing)
|
| 21 |
-
|
| 22 |
-
### Core Build Process
|
| 23 |
-
|
| 24 |
-
Note: Run engine and test commands from the `src/` directory unless specified otherwise.
|
| 25 |
-
|
| 26 |
-
#### Basic Build Commands
|
| 27 |
-
```bash
|
| 28 |
-
# Standard release build (recommended for most users)
|
| 29 |
-
make -j2 ARCH=x86-64 build
|
| 30 |
-
|
| 31 |
-
# Debug build (for development)
|
| 32 |
-
make -j2 ARCH=x86-64 debug=yes build
|
| 33 |
-
|
| 34 |
-
# All variants including ones with large boards (up to 12x10) and large branching factor (all)
|
| 35 |
-
make -j2 ARCH=x86-64 largeboards=yes all=yes build
|
| 36 |
-
```
|
| 37 |
-
|
| 38 |
-
### Python Bindings (pyffish)
|
| 39 |
-
```bash
|
| 40 |
-
# Build Python bindings (from repository root)
|
| 41 |
-
python3 setup.py install
|
| 42 |
-
|
| 43 |
-
# Alternative: Install from PyPI
|
| 44 |
-
pip install pyffish
|
| 45 |
-
```
|
| 46 |
-
|
| 47 |
-
### JavaScript Bindings (ffish.js)
|
| 48 |
-
Also see the `tests/js/README.md`.
|
| 49 |
-
```bash
|
| 50 |
-
cd src/
|
| 51 |
-
|
| 52 |
-
# Build JavaScript bindings (requires emscripten)
|
| 53 |
-
make -f Makefile_js build
|
| 54 |
-
|
| 55 |
-
# Alternative: Install from npm
|
| 56 |
-
npm install ffish
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
## Testing & Validation
|
| 60 |
-
|
| 61 |
-
All test commands below assume the current directory is `src/`.
|
| 62 |
-
|
| 63 |
-
### Core Engine Tests
|
| 64 |
-
```bash
|
| 65 |
-
# Basic functionality test
|
| 66 |
-
./stockfish bench
|
| 67 |
-
|
| 68 |
-
# Variant-specific benchmarks
|
| 69 |
-
./stockfish bench xiangqi
|
| 70 |
-
./stockfish bench shogi
|
| 71 |
-
./stockfish bench capablanca
|
| 72 |
-
|
| 73 |
-
# Validate variants configuration
|
| 74 |
-
./stockfish check variants.ini
|
| 75 |
-
```
|
| 76 |
-
|
| 77 |
-
### Comprehensive Test Suite
|
| 78 |
-
```bash
|
| 79 |
-
# Protocol compliance tests
|
| 80 |
-
../tests/protocol.sh
|
| 81 |
-
|
| 82 |
-
# Move generation validation
|
| 83 |
-
../tests/perft.sh all
|
| 84 |
-
../tests/perft.sh chess # Chess only
|
| 85 |
-
../tests/perft.sh largeboard # Large board variants only
|
| 86 |
-
|
| 87 |
-
# Regression testing
|
| 88 |
-
../tests/regression.sh
|
| 89 |
-
|
| 90 |
-
# Reproducible search test
|
| 91 |
-
../tests/reprosearch.sh
|
| 92 |
-
|
| 93 |
-
# Build signature verification
|
| 94 |
-
../tests/signature.sh
|
| 95 |
-
```
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
## Project Architecture
|
| 99 |
-
|
| 100 |
-
### Directory Structure
|
| 101 |
-
```
|
| 102 |
-
src/ # Core C++ engine source
|
| 103 |
-
tests/ # Test scripts and data
|
| 104 |
-
.github/workflows/ # CI/CD configurations
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
### Configuration Files
|
| 108 |
-
- **`src/variants.ini`**: Defines examples for configuration of chess variants
|
| 109 |
-
- **`setup.py`**: Python package build configuration
|
| 110 |
-
- **`tests/js/package.json`**: JavaScript bindings configuration
|
| 111 |
-
|
| 112 |
-
### Key Source Files in `src/`
|
| 113 |
-
- **`variant.h`**: Variant rule properties
|
| 114 |
-
- **`variant.cpp`**: Variant-specific game rules
|
| 115 |
-
- **`variant.ini`**: Variant rule configuration examples and documentation of variant properties
|
| 116 |
-
- **`position.h`**: Position representation
|
| 117 |
-
- **`position.cpp`**: Board logic
|
| 118 |
-
- **`movegen.cpp`**: Move generation logic
|
| 119 |
-
- **`parser.cpp`**: Variant rule configuration parsing
|
| 120 |
-
- **`piece.cpp`**: Piece type definitions and behavior
|
| 121 |
-
- **`pyffish.cpp`**: Python bindings
|
| 122 |
-
- **`ffishjs.cpp`**: JavaScript bindings
|
| 123 |
-
|
| 124 |
-
## Continuous Integration
|
| 125 |
-
|
| 126 |
-
### GitHub Actions Workflows
|
| 127 |
-
- **`fairy.yml`**: Core engine testing (perft, protocols, variants)
|
| 128 |
-
- **`stockfish.yml`**: Standard Stockfish compatibility tests
|
| 129 |
-
- **`release.yml`**: Binary releases for multiple platforms
|
| 130 |
-
- **`wheels.yml`**: Python package builds
|
| 131 |
-
- **`ffishjs.yml`**: JavaScript binding builds
|
| 132 |
-
|
| 133 |
-
## Common Development Patterns
|
| 134 |
-
|
| 135 |
-
### Making Engine Changes
|
| 136 |
-
1. **Always test basic functionality:** `./stockfish bench` after changes
|
| 137 |
-
2. **Validate variant compatibility:** `./stockfish check variants.ini`
|
| 138 |
-
3. **Run relevant tests:** `../tests/perft.sh all` for move generation changes
|
| 139 |
-
|
| 140 |
-
### Adding New Configurable Variants
|
| 141 |
-
1. **Edit `src/variants.ini`**: Add variant configuration
|
| 142 |
-
2. **Test parsing:** `./stockfish check variants.ini`
|
| 143 |
-
|
| 144 |
-
### Relevant websites for researching chess variant rules
|
| 145 |
-
- [Chess Variants on Wikipedia](https://en.wikipedia.org/wiki/List_of_chess_variants)
|
| 146 |
-
- [Chess Variants Wiki](https://www.chessvariants.com/)
|
| 147 |
-
- [Variant Chess on BoardGameGeek](https://boardgamegeek.com/boardgamefamily/4024/traditional-games-chess)
|
| 148 |
-
- [PyChess Variants](https://www.pychess.org/variants)
|
| 149 |
-
- [Ludii](https://ludii.games/library.php)
|
| 150 |
-
- [Lichess.org Variants](https://lichess.org/variant)
|
| 151 |
-
- [Greenchess](https://greenchess.net/variants.php)
|
| 152 |
-
- [Chess Variants on Chess.com](https://www.chess.com/variants)
|
| 153 |
-
|
| 154 |
-
### Development Best Practices
|
| 155 |
-
* Make sure to only stage and commit changes that were changed as part of the task, do not simply add all changes.
|
| 156 |
-
* Keep changes minimal and focused on the task at hand.
|
| 157 |
-
* After applying changes make sure that all places related to the task have been identified.
|
| 158 |
-
* Stay consistent with the existing code style and conventions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/AUTHORS
DELETED
|
@@ -1,231 +0,0 @@
|
|
| 1 |
-
# Fairy-Stockfish authors
|
| 2 |
-
|
| 3 |
-
# Main author
|
| 4 |
-
Fabian Fichter (ianfab)
|
| 5 |
-
|
| 6 |
-
# Contributors in alphabetical order
|
| 7 |
-
alwey
|
| 8 |
-
Belzedar94
|
| 9 |
-
cloudfish
|
| 10 |
-
CouchTomato87
|
| 11 |
-
dpldgr
|
| 12 |
-
Fulmene
|
| 13 |
-
gbtami
|
| 14 |
-
gnunicode
|
| 15 |
-
johndoknjas
|
| 16 |
-
kz04px
|
| 17 |
-
majormink
|
| 18 |
-
mtaktikos
|
| 19 |
-
QueensGambit
|
| 20 |
-
RainRat
|
| 21 |
-
rkb97
|
| 22 |
-
romstad
|
| 23 |
-
Snowmoondaphne
|
| 24 |
-
SriMethan
|
| 25 |
-
thearst3rd
|
| 26 |
-
TheYoBots
|
| 27 |
-
tttak
|
| 28 |
-
yjf2002ghty
|
| 29 |
-
yoav-rozin
|
| 30 |
-
ydirson
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
# List of authors for Stockfish, as of June 14, 2021
|
| 35 |
-
|
| 36 |
-
# Founders of the Stockfish project and fishtest infrastructure
|
| 37 |
-
Tord Romstad (romstad)
|
| 38 |
-
Marco Costalba (mcostalba)
|
| 39 |
-
Joona Kiiski (zamar)
|
| 40 |
-
Gary Linscott (glinscott)
|
| 41 |
-
|
| 42 |
-
# Authors and inventors of NNUE, training, NNUE port
|
| 43 |
-
Yu Nasu (ynasu87)
|
| 44 |
-
Motohiro Isozaki (yaneurao)
|
| 45 |
-
Hisayori Noda (nodchip)
|
| 46 |
-
|
| 47 |
-
# all other authors of the code in alphabetical order
|
| 48 |
-
Aditya (absimaldata)
|
| 49 |
-
Adrian Petrescu (apetresc)
|
| 50 |
-
Ajith Chandy Jose (ajithcj)
|
| 51 |
-
Alain Savard (Rocky640)
|
| 52 |
-
Alayan Feh (Alayan-stk-2)
|
| 53 |
-
Alexander Kure
|
| 54 |
-
Alexander Pagel (Lolligerhans)
|
| 55 |
-
Alfredo Menezes (lonfom169)
|
| 56 |
-
Ali AlZhrani (Cooffe)
|
| 57 |
-
Andrew Grant (AndyGrant)
|
| 58 |
-
Andrey Neporada (nepal)
|
| 59 |
-
Andy Duplain
|
| 60 |
-
Antoine Champion (antoinechampion)
|
| 61 |
-
Aram Tumanian (atumanian)
|
| 62 |
-
Arjun Temurnikar
|
| 63 |
-
Artem Solopiy (EntityFX)
|
| 64 |
-
Auguste Pop
|
| 65 |
-
Balint Pfliegel
|
| 66 |
-
Ben Koshy (BKSpurgeon)
|
| 67 |
-
Bill Henry (VoyagerOne)
|
| 68 |
-
Bojun Guo (noobpwnftw, Nooby)
|
| 69 |
-
braich
|
| 70 |
-
Brian Sheppard (SapphireBrand, briansheppard-toast)
|
| 71 |
-
Bruno de Melo Costa (BM123499)
|
| 72 |
-
Bryan Cross (crossbr)
|
| 73 |
-
candirufish
|
| 74 |
-
Chess13234
|
| 75 |
-
Chris Cain (ceebo)
|
| 76 |
-
Dale Weiler (graphitemaster)
|
| 77 |
-
Dan Schmidt (dfannius)
|
| 78 |
-
Daniel Axtens (daxtens)
|
| 79 |
-
Daniel Dugovic (ddugovic)
|
| 80 |
-
Dariusz Orzechowski (dorzechowski)
|
| 81 |
-
David Zar
|
| 82 |
-
Daylen Yang (daylen)
|
| 83 |
-
Deshawn Mohan-Smith (GoldenRare)
|
| 84 |
-
Dieter Dobbelaere (ddobbelaere)
|
| 85 |
-
DiscanX
|
| 86 |
-
Dominik Schlösser (domschl)
|
| 87 |
-
double-beep
|
| 88 |
-
Douglas Matos Gomes (dsmsgms)
|
| 89 |
-
Eduardo Cáceres (eduherminio)
|
| 90 |
-
Eelco de Groot (KingDefender)
|
| 91 |
-
Elvin Liu (solarlight2)
|
| 92 |
-
erbsenzaehler
|
| 93 |
-
Ernesto Gatti
|
| 94 |
-
Linmiao Xu (linrock)
|
| 95 |
-
Fabian Beuke (madnight)
|
| 96 |
-
Fabian Fichter (ianfab)
|
| 97 |
-
Fanael Linithien (Fanael)
|
| 98 |
-
fanon
|
| 99 |
-
Fauzi Akram Dabat (FauziAkram)
|
| 100 |
-
Felix Wittmann
|
| 101 |
-
gamander
|
| 102 |
-
Gary Heckman (gheckman)
|
| 103 |
-
George Sobala (gsobala)
|
| 104 |
-
gguliash
|
| 105 |
-
Gian-Carlo Pascutto (gcp)
|
| 106 |
-
Gontran Lemaire (gonlem)
|
| 107 |
-
Goodkov Vasiliy Aleksandrovich (goodkov)
|
| 108 |
-
Gregor Cramer
|
| 109 |
-
GuardianRM
|
| 110 |
-
Günther Demetz (pb00067, pb00068)
|
| 111 |
-
Guy Vreuls (gvreuls)
|
| 112 |
-
Henri Wiechers
|
| 113 |
-
Hiraoka Takuya (HiraokaTakuya)
|
| 114 |
-
homoSapiensSapiens
|
| 115 |
-
Hongzhi Cheng
|
| 116 |
-
Ivan Ivec (IIvec)
|
| 117 |
-
Jacques B. (Timshel)
|
| 118 |
-
Jan Ondruš (hxim)
|
| 119 |
-
Jared Kish (Kurtbusch)
|
| 120 |
-
Jarrod Torriero (DU-jdto)
|
| 121 |
-
Jean Gauthier (OuaisBla)
|
| 122 |
-
Jean-Francois Romang (jromang)
|
| 123 |
-
Jekaa
|
| 124 |
-
Jerry Donald Watson (jerrydonaldwatson)
|
| 125 |
-
jjoshua2
|
| 126 |
-
Jonathan Calovski (Mysseno)
|
| 127 |
-
Jonathan Buladas Dumale (SFisGOD)
|
| 128 |
-
Joost VandeVondele (vondele)
|
| 129 |
-
Jörg Oster (joergoster)
|
| 130 |
-
Joseph Ellis (jhellis3)
|
| 131 |
-
Joseph R. Prostko
|
| 132 |
-
Julian Willemer (NightlyKing)
|
| 133 |
-
jundery
|
| 134 |
-
Justin Blanchard (UncombedCoconut)
|
| 135 |
-
Kelly Wilson
|
| 136 |
-
Ken Takusagawa
|
| 137 |
-
kinderchocolate
|
| 138 |
-
Kiran Panditrao (Krgp)
|
| 139 |
-
Kojirion
|
| 140 |
-
Krystian Kuzniarek (kuzkry)
|
| 141 |
-
Leonardo Ljubičić (ICCF World Champion)
|
| 142 |
-
Leonid Pechenik (lp--)
|
| 143 |
-
Linus Arver (listx)
|
| 144 |
-
loco-loco
|
| 145 |
-
Lub van den Berg (ElbertoOne)
|
| 146 |
-
Luca Brivio (lucabrivio)
|
| 147 |
-
Lucas Braesch (lucasart)
|
| 148 |
-
Lyudmil Antonov (lantonov)
|
| 149 |
-
Maciej Żenczykowski (zenczykowski)
|
| 150 |
-
Malcolm Campbell (xoto10)
|
| 151 |
-
Mark Tenzer (31m059)
|
| 152 |
-
marotear
|
| 153 |
-
Matt Ginsberg (mattginsberg)
|
| 154 |
-
Matthew Lai (matthewlai)
|
| 155 |
-
Matthew Sullivan (Matt14916)
|
| 156 |
-
Maxim Molchanov (Maxim)
|
| 157 |
-
Michael An (man)
|
| 158 |
-
Michael Byrne (MichaelB7)
|
| 159 |
-
Michael Chaly (Vizvezdenec)
|
| 160 |
-
Michael Stembera (mstembera)
|
| 161 |
-
Michael Whiteley (protonspring)
|
| 162 |
-
Michel Van den Bergh (vdbergh)
|
| 163 |
-
Miguel Lahoz (miguel-l)
|
| 164 |
-
Mikael Bäckman (mbootsector)
|
| 165 |
-
Mira
|
| 166 |
-
Miroslav Fontán (Hexik)
|
| 167 |
-
Moez Jellouli (MJZ1977)
|
| 168 |
-
Mohammed Li (tthsqe12)
|
| 169 |
-
Nathan Rugg (nmrugg)
|
| 170 |
-
Nick Pelling (nickpelling)
|
| 171 |
-
Nicklas Persson (NicklasPersson)
|
| 172 |
-
Niklas Fiekas (niklasf)
|
| 173 |
-
Nikolay Kostov (NikolayIT)
|
| 174 |
-
Nguyen Pham (nguyenpham)
|
| 175 |
-
Norman Schmidt (FireFather)
|
| 176 |
-
notruck
|
| 177 |
-
Ondrej Mosnáček (WOnder93)
|
| 178 |
-
Oskar Werkelin Ahlin
|
| 179 |
-
Pablo Vazquez
|
| 180 |
-
Panthee
|
| 181 |
-
Pascal Romaret
|
| 182 |
-
Pasquale Pigazzini (ppigazzini)
|
| 183 |
-
Patrick Jansen (mibere)
|
| 184 |
-
pellanda
|
| 185 |
-
Peter Zsifkovits (CoffeeOne)
|
| 186 |
-
Praveen Kumar Tummala (praveentml)
|
| 187 |
-
Rahul Dsilva (silversolver1)
|
| 188 |
-
Ralph Stößer (Ralph Stoesser)
|
| 189 |
-
Raminder Singh
|
| 190 |
-
renouve
|
| 191 |
-
Reuven Peleg
|
| 192 |
-
Richard Lloyd
|
| 193 |
-
Rodrigo Exterckötter Tjäder
|
| 194 |
-
Ron Britvich (Britvich)
|
| 195 |
-
Ronald de Man (syzygy1, syzygy)
|
| 196 |
-
rqs
|
| 197 |
-
Ryan Schmitt
|
| 198 |
-
Ryan Takker
|
| 199 |
-
Sami Kiminki (skiminki)
|
| 200 |
-
Sebastian Buchwald (UniQP)
|
| 201 |
-
Sergei Antonov (saproj)
|
| 202 |
-
Sergei Ivanov (svivanov72)
|
| 203 |
-
Sergio Vieri (sergiovieri)
|
| 204 |
-
sf-x
|
| 205 |
-
Shane Booth (shane31)
|
| 206 |
-
Shawn Varghese (xXH4CKST3RXx)
|
| 207 |
-
Siad Daboul (Topologist)
|
| 208 |
-
Stefan Geschwentner (locutus2)
|
| 209 |
-
Stefano Cardanobile (Stefano80)
|
| 210 |
-
Steinar Gunderson (sesse)
|
| 211 |
-
Stéphane Nicolet (snicolet)
|
| 212 |
-
Prokop Randáček (ProkopRandacek)
|
| 213 |
-
Thanar2
|
| 214 |
-
thaspel
|
| 215 |
-
theo77186
|
| 216 |
-
Tom Truscott
|
| 217 |
-
Tom Vijlbrief (tomtor)
|
| 218 |
-
Tomasz Sobczyk (Sopel97)
|
| 219 |
-
Torsten Franz (torfranz, tfranzer)
|
| 220 |
-
Tracey Emery (basepr1me)
|
| 221 |
-
tttak
|
| 222 |
-
Unai Corzo (unaiic)
|
| 223 |
-
Uri Blass (uriblass)
|
| 224 |
-
Vince Negri (cuddlestmonkey)
|
| 225 |
-
zz4032
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
# Additionally, we acknowledge the authors and maintainers of fishtest,
|
| 229 |
-
# an amazing and essential framework for the development of Stockfish!
|
| 230 |
-
#
|
| 231 |
-
# https://github.com/glinscott/fishtest/blob/master/AUTHORS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/Copying.txt
DELETED
|
@@ -1,674 +0,0 @@
|
|
| 1 |
-
GNU GENERAL PUBLIC LICENSE
|
| 2 |
-
Version 3, 29 June 2007
|
| 3 |
-
|
| 4 |
-
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
| 5 |
-
Everyone is permitted to copy and distribute verbatim copies
|
| 6 |
-
of this license document, but changing it is not allowed.
|
| 7 |
-
|
| 8 |
-
Preamble
|
| 9 |
-
|
| 10 |
-
The GNU General Public License is a free, copyleft license for
|
| 11 |
-
software and other kinds of works.
|
| 12 |
-
|
| 13 |
-
The licenses for most software and other practical works are designed
|
| 14 |
-
to take away your freedom to share and change the works. By contrast,
|
| 15 |
-
the GNU General Public License is intended to guarantee your freedom to
|
| 16 |
-
share and change all versions of a program--to make sure it remains free
|
| 17 |
-
software for all its users. We, the Free Software Foundation, use the
|
| 18 |
-
GNU General Public License for most of our software; it applies also to
|
| 19 |
-
any other work released this way by its authors. You can apply it to
|
| 20 |
-
your programs, too.
|
| 21 |
-
|
| 22 |
-
When we speak of free software, we are referring to freedom, not
|
| 23 |
-
price. Our General Public Licenses are designed to make sure that you
|
| 24 |
-
have the freedom to distribute copies of free software (and charge for
|
| 25 |
-
them if you wish), that you receive source code or can get it if you
|
| 26 |
-
want it, that you can change the software or use pieces of it in new
|
| 27 |
-
free programs, and that you know you can do these things.
|
| 28 |
-
|
| 29 |
-
To protect your rights, we need to prevent others from denying you
|
| 30 |
-
these rights or asking you to surrender the rights. Therefore, you have
|
| 31 |
-
certain responsibilities if you distribute copies of the software, or if
|
| 32 |
-
you modify it: responsibilities to respect the freedom of others.
|
| 33 |
-
|
| 34 |
-
For example, if you distribute copies of such a program, whether
|
| 35 |
-
gratis or for a fee, you must pass on to the recipients the same
|
| 36 |
-
freedoms that you received. You must make sure that they, too, receive
|
| 37 |
-
or can get the source code. And you must show them these terms so they
|
| 38 |
-
know their rights.
|
| 39 |
-
|
| 40 |
-
Developers that use the GNU GPL protect your rights with two steps:
|
| 41 |
-
(1) assert copyright on the software, and (2) offer you this License
|
| 42 |
-
giving you legal permission to copy, distribute and/or modify it.
|
| 43 |
-
|
| 44 |
-
For the developers' and authors' protection, the GPL clearly explains
|
| 45 |
-
that there is no warranty for this free software. For both users' and
|
| 46 |
-
authors' sake, the GPL requires that modified versions be marked as
|
| 47 |
-
changed, so that their problems will not be attributed erroneously to
|
| 48 |
-
authors of previous versions.
|
| 49 |
-
|
| 50 |
-
Some devices are designed to deny users access to install or run
|
| 51 |
-
modified versions of the software inside them, although the manufacturer
|
| 52 |
-
can do so. This is fundamentally incompatible with the aim of
|
| 53 |
-
protecting users' freedom to change the software. The systematic
|
| 54 |
-
pattern of such abuse occurs in the area of products for individuals to
|
| 55 |
-
use, which is precisely where it is most unacceptable. Therefore, we
|
| 56 |
-
have designed this version of the GPL to prohibit the practice for those
|
| 57 |
-
products. If such problems arise substantially in other domains, we
|
| 58 |
-
stand ready to extend this provision to those domains in future versions
|
| 59 |
-
of the GPL, as needed to protect the freedom of users.
|
| 60 |
-
|
| 61 |
-
Finally, every program is threatened constantly by software patents.
|
| 62 |
-
States should not allow patents to restrict development and use of
|
| 63 |
-
software on general-purpose computers, but in those that do, we wish to
|
| 64 |
-
avoid the special danger that patents applied to a free program could
|
| 65 |
-
make it effectively proprietary. To prevent this, the GPL assures that
|
| 66 |
-
patents cannot be used to render the program non-free.
|
| 67 |
-
|
| 68 |
-
The precise terms and conditions for copying, distribution and
|
| 69 |
-
modification follow.
|
| 70 |
-
|
| 71 |
-
TERMS AND CONDITIONS
|
| 72 |
-
|
| 73 |
-
0. Definitions.
|
| 74 |
-
|
| 75 |
-
"This License" refers to version 3 of the GNU General Public License.
|
| 76 |
-
|
| 77 |
-
"Copyright" also means copyright-like laws that apply to other kinds of
|
| 78 |
-
works, such as semiconductor masks.
|
| 79 |
-
|
| 80 |
-
"The Program" refers to any copyrightable work licensed under this
|
| 81 |
-
License. Each licensee is addressed as "you". "Licensees" and
|
| 82 |
-
"recipients" may be individuals or organizations.
|
| 83 |
-
|
| 84 |
-
To "modify" a work means to copy from or adapt all or part of the work
|
| 85 |
-
in a fashion requiring copyright permission, other than the making of an
|
| 86 |
-
exact copy. The resulting work is called a "modified version" of the
|
| 87 |
-
earlier work or a work "based on" the earlier work.
|
| 88 |
-
|
| 89 |
-
A "covered work" means either the unmodified Program or a work based
|
| 90 |
-
on the Program.
|
| 91 |
-
|
| 92 |
-
To "propagate" a work means to do anything with it that, without
|
| 93 |
-
permission, would make you directly or secondarily liable for
|
| 94 |
-
infringement under applicable copyright law, except executing it on a
|
| 95 |
-
computer or modifying a private copy. Propagation includes copying,
|
| 96 |
-
distribution (with or without modification), making available to the
|
| 97 |
-
public, and in some countries other activities as well.
|
| 98 |
-
|
| 99 |
-
To "convey" a work means any kind of propagation that enables other
|
| 100 |
-
parties to make or receive copies. Mere interaction with a user through
|
| 101 |
-
a computer network, with no transfer of a copy, is not conveying.
|
| 102 |
-
|
| 103 |
-
An interactive user interface displays "Appropriate Legal Notices"
|
| 104 |
-
to the extent that it includes a convenient and prominently visible
|
| 105 |
-
feature that (1) displays an appropriate copyright notice, and (2)
|
| 106 |
-
tells the user that there is no warranty for the work (except to the
|
| 107 |
-
extent that warranties are provided), that licensees may convey the
|
| 108 |
-
work under this License, and how to view a copy of this License. If
|
| 109 |
-
the interface presents a list of user commands or options, such as a
|
| 110 |
-
menu, a prominent item in the list meets this criterion.
|
| 111 |
-
|
| 112 |
-
1. Source Code.
|
| 113 |
-
|
| 114 |
-
The "source code" for a work means the preferred form of the work
|
| 115 |
-
for making modifications to it. "Object code" means any non-source
|
| 116 |
-
form of a work.
|
| 117 |
-
|
| 118 |
-
A "Standard Interface" means an interface that either is an official
|
| 119 |
-
standard defined by a recognized standards body, or, in the case of
|
| 120 |
-
interfaces specified for a particular programming language, one that
|
| 121 |
-
is widely used among developers working in that language.
|
| 122 |
-
|
| 123 |
-
The "System Libraries" of an executable work include anything, other
|
| 124 |
-
than the work as a whole, that (a) is included in the normal form of
|
| 125 |
-
packaging a Major Component, but which is not part of that Major
|
| 126 |
-
Component, and (b) serves only to enable use of the work with that
|
| 127 |
-
Major Component, or to implement a Standard Interface for which an
|
| 128 |
-
implementation is available to the public in source code form. A
|
| 129 |
-
"Major Component", in this context, means a major essential component
|
| 130 |
-
(kernel, window system, and so on) of the specific operating system
|
| 131 |
-
(if any) on which the executable work runs, or a compiler used to
|
| 132 |
-
produce the work, or an object code interpreter used to run it.
|
| 133 |
-
|
| 134 |
-
The "Corresponding Source" for a work in object code form means all
|
| 135 |
-
the source code needed to generate, install, and (for an executable
|
| 136 |
-
work) run the object code and to modify the work, including scripts to
|
| 137 |
-
control those activities. However, it does not include the work's
|
| 138 |
-
System Libraries, or general-purpose tools or generally available free
|
| 139 |
-
programs which are used unmodified in performing those activities but
|
| 140 |
-
which are not part of the work. For example, Corresponding Source
|
| 141 |
-
includes interface definition files associated with source files for
|
| 142 |
-
the work, and the source code for shared libraries and dynamically
|
| 143 |
-
linked subprograms that the work is specifically designed to require,
|
| 144 |
-
such as by intimate data communication or control flow between those
|
| 145 |
-
subprograms and other parts of the work.
|
| 146 |
-
|
| 147 |
-
The Corresponding Source need not include anything that users
|
| 148 |
-
can regenerate automatically from other parts of the Corresponding
|
| 149 |
-
Source.
|
| 150 |
-
|
| 151 |
-
The Corresponding Source for a work in source code form is that
|
| 152 |
-
same work.
|
| 153 |
-
|
| 154 |
-
2. Basic Permissions.
|
| 155 |
-
|
| 156 |
-
All rights granted under this License are granted for the term of
|
| 157 |
-
copyright on the Program, and are irrevocable provided the stated
|
| 158 |
-
conditions are met. This License explicitly affirms your unlimited
|
| 159 |
-
permission to run the unmodified Program. The output from running a
|
| 160 |
-
covered work is covered by this License only if the output, given its
|
| 161 |
-
content, constitutes a covered work. This License acknowledges your
|
| 162 |
-
rights of fair use or other equivalent, as provided by copyright law.
|
| 163 |
-
|
| 164 |
-
You may make, run and propagate covered works that you do not
|
| 165 |
-
convey, without conditions so long as your license otherwise remains
|
| 166 |
-
in force. You may convey covered works to others for the sole purpose
|
| 167 |
-
of having them make modifications exclusively for you, or provide you
|
| 168 |
-
with facilities for running those works, provided that you comply with
|
| 169 |
-
the terms of this License in conveying all material for which you do
|
| 170 |
-
not control copyright. Those thus making or running the covered works
|
| 171 |
-
for you must do so exclusively on your behalf, under your direction
|
| 172 |
-
and control, on terms that prohibit them from making any copies of
|
| 173 |
-
your copyrighted material outside their relationship with you.
|
| 174 |
-
|
| 175 |
-
Conveying under any other circumstances is permitted solely under
|
| 176 |
-
the conditions stated below. Sublicensing is not allowed; section 10
|
| 177 |
-
makes it unnecessary.
|
| 178 |
-
|
| 179 |
-
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
| 180 |
-
|
| 181 |
-
No covered work shall be deemed part of an effective technological
|
| 182 |
-
measure under any applicable law fulfilling obligations under article
|
| 183 |
-
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
| 184 |
-
similar laws prohibiting or restricting circumvention of such
|
| 185 |
-
measures.
|
| 186 |
-
|
| 187 |
-
When you convey a covered work, you waive any legal power to forbid
|
| 188 |
-
circumvention of technological measures to the extent such circumvention
|
| 189 |
-
is effected by exercising rights under this License with respect to
|
| 190 |
-
the covered work, and you disclaim any intention to limit operation or
|
| 191 |
-
modification of the work as a means of enforcing, against the work's
|
| 192 |
-
users, your or third parties' legal rights to forbid circumvention of
|
| 193 |
-
technological measures.
|
| 194 |
-
|
| 195 |
-
4. Conveying Verbatim Copies.
|
| 196 |
-
|
| 197 |
-
You may convey verbatim copies of the Program's source code as you
|
| 198 |
-
receive it, in any medium, provided that you conspicuously and
|
| 199 |
-
appropriately publish on each copy an appropriate copyright notice;
|
| 200 |
-
keep intact all notices stating that this License and any
|
| 201 |
-
non-permissive terms added in accord with section 7 apply to the code;
|
| 202 |
-
keep intact all notices of the absence of any warranty; and give all
|
| 203 |
-
recipients a copy of this License along with the Program.
|
| 204 |
-
|
| 205 |
-
You may charge any price or no price for each copy that you convey,
|
| 206 |
-
and you may offer support or warranty protection for a fee.
|
| 207 |
-
|
| 208 |
-
5. Conveying Modified Source Versions.
|
| 209 |
-
|
| 210 |
-
You may convey a work based on the Program, or the modifications to
|
| 211 |
-
produce it from the Program, in the form of source code under the
|
| 212 |
-
terms of section 4, provided that you also meet all of these conditions:
|
| 213 |
-
|
| 214 |
-
a) The work must carry prominent notices stating that you modified
|
| 215 |
-
it, and giving a relevant date.
|
| 216 |
-
|
| 217 |
-
b) The work must carry prominent notices stating that it is
|
| 218 |
-
released under this License and any conditions added under section
|
| 219 |
-
7. This requirement modifies the requirement in section 4 to
|
| 220 |
-
"keep intact all notices".
|
| 221 |
-
|
| 222 |
-
c) You must license the entire work, as a whole, under this
|
| 223 |
-
License to anyone who comes into possession of a copy. This
|
| 224 |
-
License will therefore apply, along with any applicable section 7
|
| 225 |
-
additional terms, to the whole of the work, and all its parts,
|
| 226 |
-
regardless of how they are packaged. This License gives no
|
| 227 |
-
permission to license the work in any other way, but it does not
|
| 228 |
-
invalidate such permission if you have separately received it.
|
| 229 |
-
|
| 230 |
-
d) If the work has interactive user interfaces, each must display
|
| 231 |
-
Appropriate Legal Notices; however, if the Program has interactive
|
| 232 |
-
interfaces that do not display Appropriate Legal Notices, your
|
| 233 |
-
work need not make them do so.
|
| 234 |
-
|
| 235 |
-
A compilation of a covered work with other separate and independent
|
| 236 |
-
works, which are not by their nature extensions of the covered work,
|
| 237 |
-
and which are not combined with it such as to form a larger program,
|
| 238 |
-
in or on a volume of a storage or distribution medium, is called an
|
| 239 |
-
"aggregate" if the compilation and its resulting copyright are not
|
| 240 |
-
used to limit the access or legal rights of the compilation's users
|
| 241 |
-
beyond what the individual works permit. Inclusion of a covered work
|
| 242 |
-
in an aggregate does not cause this License to apply to the other
|
| 243 |
-
parts of the aggregate.
|
| 244 |
-
|
| 245 |
-
6. Conveying Non-Source Forms.
|
| 246 |
-
|
| 247 |
-
You may convey a covered work in object code form under the terms
|
| 248 |
-
of sections 4 and 5, provided that you also convey the
|
| 249 |
-
machine-readable Corresponding Source under the terms of this License,
|
| 250 |
-
in one of these ways:
|
| 251 |
-
|
| 252 |
-
a) Convey the object code in, or embodied in, a physical product
|
| 253 |
-
(including a physical distribution medium), accompanied by the
|
| 254 |
-
Corresponding Source fixed on a durable physical medium
|
| 255 |
-
customarily used for software interchange.
|
| 256 |
-
|
| 257 |
-
b) Convey the object code in, or embodied in, a physical product
|
| 258 |
-
(including a physical distribution medium), accompanied by a
|
| 259 |
-
written offer, valid for at least three years and valid for as
|
| 260 |
-
long as you offer spare parts or customer support for that product
|
| 261 |
-
model, to give anyone who possesses the object code either (1) a
|
| 262 |
-
copy of the Corresponding Source for all the software in the
|
| 263 |
-
product that is covered by this License, on a durable physical
|
| 264 |
-
medium customarily used for software interchange, for a price no
|
| 265 |
-
more than your reasonable cost of physically performing this
|
| 266 |
-
conveying of source, or (2) access to copy the
|
| 267 |
-
Corresponding Source from a network server at no charge.
|
| 268 |
-
|
| 269 |
-
c) Convey individual copies of the object code with a copy of the
|
| 270 |
-
written offer to provide the Corresponding Source. This
|
| 271 |
-
alternative is allowed only occasionally and noncommercially, and
|
| 272 |
-
only if you received the object code with such an offer, in accord
|
| 273 |
-
with subsection 6b.
|
| 274 |
-
|
| 275 |
-
d) Convey the object code by offering access from a designated
|
| 276 |
-
place (gratis or for a charge), and offer equivalent access to the
|
| 277 |
-
Corresponding Source in the same way through the same place at no
|
| 278 |
-
further charge. You need not require recipients to copy the
|
| 279 |
-
Corresponding Source along with the object code. If the place to
|
| 280 |
-
copy the object code is a network server, the Corresponding Source
|
| 281 |
-
may be on a different server (operated by you or a third party)
|
| 282 |
-
that supports equivalent copying facilities, provided you maintain
|
| 283 |
-
clear directions next to the object code saying where to find the
|
| 284 |
-
Corresponding Source. Regardless of what server hosts the
|
| 285 |
-
Corresponding Source, you remain obligated to ensure that it is
|
| 286 |
-
available for as long as needed to satisfy these requirements.
|
| 287 |
-
|
| 288 |
-
e) Convey the object code using peer-to-peer transmission, provided
|
| 289 |
-
you inform other peers where the object code and Corresponding
|
| 290 |
-
Source of the work are being offered to the general public at no
|
| 291 |
-
charge under subsection 6d.
|
| 292 |
-
|
| 293 |
-
A separable portion of the object code, whose source code is excluded
|
| 294 |
-
from the Corresponding Source as a System Library, need not be
|
| 295 |
-
included in conveying the object code work.
|
| 296 |
-
|
| 297 |
-
A "User Product" is either (1) a "consumer product", which means any
|
| 298 |
-
tangible personal property which is normally used for personal, family,
|
| 299 |
-
or household purposes, or (2) anything designed or sold for incorporation
|
| 300 |
-
into a dwelling. In determining whether a product is a consumer product,
|
| 301 |
-
doubtful cases shall be resolved in favor of coverage. For a particular
|
| 302 |
-
product received by a particular user, "normally used" refers to a
|
| 303 |
-
typical or common use of that class of product, regardless of the status
|
| 304 |
-
of the particular user or of the way in which the particular user
|
| 305 |
-
actually uses, or expects or is expected to use, the product. A product
|
| 306 |
-
is a consumer product regardless of whether the product has substantial
|
| 307 |
-
commercial, industrial or non-consumer uses, unless such uses represent
|
| 308 |
-
the only significant mode of use of the product.
|
| 309 |
-
|
| 310 |
-
"Installation Information" for a User Product means any methods,
|
| 311 |
-
procedures, authorization keys, or other information required to install
|
| 312 |
-
and execute modified versions of a covered work in that User Product from
|
| 313 |
-
a modified version of its Corresponding Source. The information must
|
| 314 |
-
suffice to ensure that the continued functioning of the modified object
|
| 315 |
-
code is in no case prevented or interfered with solely because
|
| 316 |
-
modification has been made.
|
| 317 |
-
|
| 318 |
-
If you convey an object code work under this section in, or with, or
|
| 319 |
-
specifically for use in, a User Product, and the conveying occurs as
|
| 320 |
-
part of a transaction in which the right of possession and use of the
|
| 321 |
-
User Product is transferred to the recipient in perpetuity or for a
|
| 322 |
-
fixed term (regardless of how the transaction is characterized), the
|
| 323 |
-
Corresponding Source conveyed under this section must be accompanied
|
| 324 |
-
by the Installation Information. But this requirement does not apply
|
| 325 |
-
if neither you nor any third party retains the ability to install
|
| 326 |
-
modified object code on the User Product (for example, the work has
|
| 327 |
-
been installed in ROM).
|
| 328 |
-
|
| 329 |
-
The requirement to provide Installation Information does not include a
|
| 330 |
-
requirement to continue to provide support service, warranty, or updates
|
| 331 |
-
for a work that has been modified or installed by the recipient, or for
|
| 332 |
-
the User Product in which it has been modified or installed. Access to a
|
| 333 |
-
network may be denied when the modification itself materially and
|
| 334 |
-
adversely affects the operation of the network or violates the rules and
|
| 335 |
-
protocols for communication across the network.
|
| 336 |
-
|
| 337 |
-
Corresponding Source conveyed, and Installation Information provided,
|
| 338 |
-
in accord with this section must be in a format that is publicly
|
| 339 |
-
documented (and with an implementation available to the public in
|
| 340 |
-
source code form), and must require no special password or key for
|
| 341 |
-
unpacking, reading or copying.
|
| 342 |
-
|
| 343 |
-
7. Additional Terms.
|
| 344 |
-
|
| 345 |
-
"Additional permissions" are terms that supplement the terms of this
|
| 346 |
-
License by making exceptions from one or more of its conditions.
|
| 347 |
-
Additional permissions that are applicable to the entire Program shall
|
| 348 |
-
be treated as though they were included in this License, to the extent
|
| 349 |
-
that they are valid under applicable law. If additional permissions
|
| 350 |
-
apply only to part of the Program, that part may be used separately
|
| 351 |
-
under those permissions, but the entire Program remains governed by
|
| 352 |
-
this License without regard to the additional permissions.
|
| 353 |
-
|
| 354 |
-
When you convey a copy of a covered work, you may at your option
|
| 355 |
-
remove any additional permissions from that copy, or from any part of
|
| 356 |
-
it. (Additional permissions may be written to require their own
|
| 357 |
-
removal in certain cases when you modify the work.) You may place
|
| 358 |
-
additional permissions on material, added by you to a covered work,
|
| 359 |
-
for which you have or can give appropriate copyright permission.
|
| 360 |
-
|
| 361 |
-
Notwithstanding any other provision of this License, for material you
|
| 362 |
-
add to a covered work, you may (if authorized by the copyright holders of
|
| 363 |
-
that material) supplement the terms of this License with terms:
|
| 364 |
-
|
| 365 |
-
a) Disclaiming warranty or limiting liability differently from the
|
| 366 |
-
terms of sections 15 and 16 of this License; or
|
| 367 |
-
|
| 368 |
-
b) Requiring preservation of specified reasonable legal notices or
|
| 369 |
-
author attributions in that material or in the Appropriate Legal
|
| 370 |
-
Notices displayed by works containing it; or
|
| 371 |
-
|
| 372 |
-
c) Prohibiting misrepresentation of the origin of that material, or
|
| 373 |
-
requiring that modified versions of such material be marked in
|
| 374 |
-
reasonable ways as different from the original version; or
|
| 375 |
-
|
| 376 |
-
d) Limiting the use for publicity purposes of names of licensors or
|
| 377 |
-
authors of the material; or
|
| 378 |
-
|
| 379 |
-
e) Declining to grant rights under trademark law for use of some
|
| 380 |
-
trade names, trademarks, or service marks; or
|
| 381 |
-
|
| 382 |
-
f) Requiring indemnification of licensors and authors of that
|
| 383 |
-
material by anyone who conveys the material (or modified versions of
|
| 384 |
-
it) with contractual assumptions of liability to the recipient, for
|
| 385 |
-
any liability that these contractual assumptions directly impose on
|
| 386 |
-
those licensors and authors.
|
| 387 |
-
|
| 388 |
-
All other non-permissive additional terms are considered "further
|
| 389 |
-
restrictions" within the meaning of section 10. If the Program as you
|
| 390 |
-
received it, or any part of it, contains a notice stating that it is
|
| 391 |
-
governed by this License along with a term that is a further
|
| 392 |
-
restriction, you may remove that term. If a license document contains
|
| 393 |
-
a further restriction but permits relicensing or conveying under this
|
| 394 |
-
License, you may add to a covered work material governed by the terms
|
| 395 |
-
of that license document, provided that the further restriction does
|
| 396 |
-
not survive such relicensing or conveying.
|
| 397 |
-
|
| 398 |
-
If you add terms to a covered work in accord with this section, you
|
| 399 |
-
must place, in the relevant source files, a statement of the
|
| 400 |
-
additional terms that apply to those files, or a notice indicating
|
| 401 |
-
where to find the applicable terms.
|
| 402 |
-
|
| 403 |
-
Additional terms, permissive or non-permissive, may be stated in the
|
| 404 |
-
form of a separately written license, or stated as exceptions;
|
| 405 |
-
the above requirements apply either way.
|
| 406 |
-
|
| 407 |
-
8. Termination.
|
| 408 |
-
|
| 409 |
-
You may not propagate or modify a covered work except as expressly
|
| 410 |
-
provided under this License. Any attempt otherwise to propagate or
|
| 411 |
-
modify it is void, and will automatically terminate your rights under
|
| 412 |
-
this License (including any patent licenses granted under the third
|
| 413 |
-
paragraph of section 11).
|
| 414 |
-
|
| 415 |
-
However, if you cease all violation of this License, then your
|
| 416 |
-
license from a particular copyright holder is reinstated (a)
|
| 417 |
-
provisionally, unless and until the copyright holder explicitly and
|
| 418 |
-
finally terminates your license, and (b) permanently, if the copyright
|
| 419 |
-
holder fails to notify you of the violation by some reasonable means
|
| 420 |
-
prior to 60 days after the cessation.
|
| 421 |
-
|
| 422 |
-
Moreover, your license from a particular copyright holder is
|
| 423 |
-
reinstated permanently if the copyright holder notifies you of the
|
| 424 |
-
violation by some reasonable means, this is the first time you have
|
| 425 |
-
received notice of violation of this License (for any work) from that
|
| 426 |
-
copyright holder, and you cure the violation prior to 30 days after
|
| 427 |
-
your receipt of the notice.
|
| 428 |
-
|
| 429 |
-
Termination of your rights under this section does not terminate the
|
| 430 |
-
licenses of parties who have received copies or rights from you under
|
| 431 |
-
this License. If your rights have been terminated and not permanently
|
| 432 |
-
reinstated, you do not qualify to receive new licenses for the same
|
| 433 |
-
material under section 10.
|
| 434 |
-
|
| 435 |
-
9. Acceptance Not Required for Having Copies.
|
| 436 |
-
|
| 437 |
-
You are not required to accept this License in order to receive or
|
| 438 |
-
run a copy of the Program. Ancillary propagation of a covered work
|
| 439 |
-
occurring solely as a consequence of using peer-to-peer transmission
|
| 440 |
-
to receive a copy likewise does not require acceptance. However,
|
| 441 |
-
nothing other than this License grants you permission to propagate or
|
| 442 |
-
modify any covered work. These actions infringe copyright if you do
|
| 443 |
-
not accept this License. Therefore, by modifying or propagating a
|
| 444 |
-
covered work, you indicate your acceptance of this License to do so.
|
| 445 |
-
|
| 446 |
-
10. Automatic Licensing of Downstream Recipients.
|
| 447 |
-
|
| 448 |
-
Each time you convey a covered work, the recipient automatically
|
| 449 |
-
receives a license from the original licensors, to run, modify and
|
| 450 |
-
propagate that work, subject to this License. You are not responsible
|
| 451 |
-
for enforcing compliance by third parties with this License.
|
| 452 |
-
|
| 453 |
-
An "entity transaction" is a transaction transferring control of an
|
| 454 |
-
organization, or substantially all assets of one, or subdividing an
|
| 455 |
-
organization, or merging organizations. If propagation of a covered
|
| 456 |
-
work results from an entity transaction, each party to that
|
| 457 |
-
transaction who receives a copy of the work also receives whatever
|
| 458 |
-
licenses to the work the party's predecessor in interest had or could
|
| 459 |
-
give under the previous paragraph, plus a right to possession of the
|
| 460 |
-
Corresponding Source of the work from the predecessor in interest, if
|
| 461 |
-
the predecessor has it or can get it with reasonable efforts.
|
| 462 |
-
|
| 463 |
-
You may not impose any further restrictions on the exercise of the
|
| 464 |
-
rights granted or affirmed under this License. For example, you may
|
| 465 |
-
not impose a license fee, royalty, or other charge for exercise of
|
| 466 |
-
rights granted under this License, and you may not initiate litigation
|
| 467 |
-
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
| 468 |
-
any patent claim is infringed by making, using, selling, offering for
|
| 469 |
-
sale, or importing the Program or any portion of it.
|
| 470 |
-
|
| 471 |
-
11. Patents.
|
| 472 |
-
|
| 473 |
-
A "contributor" is a copyright holder who authorizes use under this
|
| 474 |
-
License of the Program or a work on which the Program is based. The
|
| 475 |
-
work thus licensed is called the contributor's "contributor version".
|
| 476 |
-
|
| 477 |
-
A contributor's "essential patent claims" are all patent claims
|
| 478 |
-
owned or controlled by the contributor, whether already acquired or
|
| 479 |
-
hereafter acquired, that would be infringed by some manner, permitted
|
| 480 |
-
by this License, of making, using, or selling its contributor version,
|
| 481 |
-
but do not include claims that would be infringed only as a
|
| 482 |
-
consequence of further modification of the contributor version. For
|
| 483 |
-
purposes of this definition, "control" includes the right to grant
|
| 484 |
-
patent sublicenses in a manner consistent with the requirements of
|
| 485 |
-
this License.
|
| 486 |
-
|
| 487 |
-
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
| 488 |
-
patent license under the contributor's essential patent claims, to
|
| 489 |
-
make, use, sell, offer for sale, import and otherwise run, modify and
|
| 490 |
-
propagate the contents of its contributor version.
|
| 491 |
-
|
| 492 |
-
In the following three paragraphs, a "patent license" is any express
|
| 493 |
-
agreement or commitment, however denominated, not to enforce a patent
|
| 494 |
-
(such as an express permission to practice a patent or covenant not to
|
| 495 |
-
sue for patent infringement). To "grant" such a patent license to a
|
| 496 |
-
party means to make such an agreement or commitment not to enforce a
|
| 497 |
-
patent against the party.
|
| 498 |
-
|
| 499 |
-
If you convey a covered work, knowingly relying on a patent license,
|
| 500 |
-
and the Corresponding Source of the work is not available for anyone
|
| 501 |
-
to copy, free of charge and under the terms of this License, through a
|
| 502 |
-
publicly available network server or other readily accessible means,
|
| 503 |
-
then you must either (1) cause the Corresponding Source to be so
|
| 504 |
-
available, or (2) arrange to deprive yourself of the benefit of the
|
| 505 |
-
patent license for this particular work, or (3) arrange, in a manner
|
| 506 |
-
consistent with the requirements of this License, to extend the patent
|
| 507 |
-
license to downstream recipients. "Knowingly relying" means you have
|
| 508 |
-
actual knowledge that, but for the patent license, your conveying the
|
| 509 |
-
covered work in a country, or your recipient's use of the covered work
|
| 510 |
-
in a country, would infringe one or more identifiable patents in that
|
| 511 |
-
country that you have reason to believe are valid.
|
| 512 |
-
|
| 513 |
-
If, pursuant to or in connection with a single transaction or
|
| 514 |
-
arrangement, you convey, or propagate by procuring conveyance of, a
|
| 515 |
-
covered work, and grant a patent license to some of the parties
|
| 516 |
-
receiving the covered work authorizing them to use, propagate, modify
|
| 517 |
-
or convey a specific copy of the covered work, then the patent license
|
| 518 |
-
you grant is automatically extended to all recipients of the covered
|
| 519 |
-
work and works based on it.
|
| 520 |
-
|
| 521 |
-
A patent license is "discriminatory" if it does not include within
|
| 522 |
-
the scope of its coverage, prohibits the exercise of, or is
|
| 523 |
-
conditioned on the non-exercise of one or more of the rights that are
|
| 524 |
-
specifically granted under this License. You may not convey a covered
|
| 525 |
-
work if you are a party to an arrangement with a third party that is
|
| 526 |
-
in the business of distributing software, under which you make payment
|
| 527 |
-
to the third party based on the extent of your activity of conveying
|
| 528 |
-
the work, and under which the third party grants, to any of the
|
| 529 |
-
parties who would receive the covered work from you, a discriminatory
|
| 530 |
-
patent license (a) in connection with copies of the covered work
|
| 531 |
-
conveyed by you (or copies made from those copies), or (b) primarily
|
| 532 |
-
for and in connection with specific products or compilations that
|
| 533 |
-
contain the covered work, unless you entered into that arrangement,
|
| 534 |
-
or that patent license was granted, prior to 28 March 2007.
|
| 535 |
-
|
| 536 |
-
Nothing in this License shall be construed as excluding or limiting
|
| 537 |
-
any implied license or other defenses to infringement that may
|
| 538 |
-
otherwise be available to you under applicable patent law.
|
| 539 |
-
|
| 540 |
-
12. No Surrender of Others' Freedom.
|
| 541 |
-
|
| 542 |
-
If conditions are imposed on you (whether by court order, agreement or
|
| 543 |
-
otherwise) that contradict the conditions of this License, they do not
|
| 544 |
-
excuse you from the conditions of this License. If you cannot convey a
|
| 545 |
-
covered work so as to satisfy simultaneously your obligations under this
|
| 546 |
-
License and any other pertinent obligations, then as a consequence you may
|
| 547 |
-
not convey it at all. For example, if you agree to terms that obligate you
|
| 548 |
-
to collect a royalty for further conveying from those to whom you convey
|
| 549 |
-
the Program, the only way you could satisfy both those terms and this
|
| 550 |
-
License would be to refrain entirely from conveying the Program.
|
| 551 |
-
|
| 552 |
-
13. Use with the GNU Affero General Public License.
|
| 553 |
-
|
| 554 |
-
Notwithstanding any other provision of this License, you have
|
| 555 |
-
permission to link or combine any covered work with a work licensed
|
| 556 |
-
under version 3 of the GNU Affero General Public License into a single
|
| 557 |
-
combined work, and to convey the resulting work. The terms of this
|
| 558 |
-
License will continue to apply to the part which is the covered work,
|
| 559 |
-
but the special requirements of the GNU Affero General Public License,
|
| 560 |
-
section 13, concerning interaction through a network will apply to the
|
| 561 |
-
combination as such.
|
| 562 |
-
|
| 563 |
-
14. Revised Versions of this License.
|
| 564 |
-
|
| 565 |
-
The Free Software Foundation may publish revised and/or new versions of
|
| 566 |
-
the GNU General Public License from time to time. Such new versions will
|
| 567 |
-
be similar in spirit to the present version, but may differ in detail to
|
| 568 |
-
address new problems or concerns.
|
| 569 |
-
|
| 570 |
-
Each version is given a distinguishing version number. If the
|
| 571 |
-
Program specifies that a certain numbered version of the GNU General
|
| 572 |
-
Public License "or any later version" applies to it, you have the
|
| 573 |
-
option of following the terms and conditions either of that numbered
|
| 574 |
-
version or of any later version published by the Free Software
|
| 575 |
-
Foundation. If the Program does not specify a version number of the
|
| 576 |
-
GNU General Public License, you may choose any version ever published
|
| 577 |
-
by the Free Software Foundation.
|
| 578 |
-
|
| 579 |
-
If the Program specifies that a proxy can decide which future
|
| 580 |
-
versions of the GNU General Public License can be used, that proxy's
|
| 581 |
-
public statement of acceptance of a version permanently authorizes you
|
| 582 |
-
to choose that version for the Program.
|
| 583 |
-
|
| 584 |
-
Later license versions may give you additional or different
|
| 585 |
-
permissions. However, no additional obligations are imposed on any
|
| 586 |
-
author or copyright holder as a result of your choosing to follow a
|
| 587 |
-
later version.
|
| 588 |
-
|
| 589 |
-
15. Disclaimer of Warranty.
|
| 590 |
-
|
| 591 |
-
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
| 592 |
-
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
| 593 |
-
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
| 594 |
-
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
| 595 |
-
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| 596 |
-
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
| 597 |
-
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
| 598 |
-
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
| 599 |
-
|
| 600 |
-
16. Limitation of Liability.
|
| 601 |
-
|
| 602 |
-
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
| 603 |
-
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
| 604 |
-
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
| 605 |
-
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
| 606 |
-
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
| 607 |
-
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
| 608 |
-
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
| 609 |
-
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
| 610 |
-
SUCH DAMAGES.
|
| 611 |
-
|
| 612 |
-
17. Interpretation of Sections 15 and 16.
|
| 613 |
-
|
| 614 |
-
If the disclaimer of warranty and limitation of liability provided
|
| 615 |
-
above cannot be given local legal effect according to their terms,
|
| 616 |
-
reviewing courts shall apply local law that most closely approximates
|
| 617 |
-
an absolute waiver of all civil liability in connection with the
|
| 618 |
-
Program, unless a warranty or assumption of liability accompanies a
|
| 619 |
-
copy of the Program in return for a fee.
|
| 620 |
-
|
| 621 |
-
END OF TERMS AND CONDITIONS
|
| 622 |
-
|
| 623 |
-
How to Apply These Terms to Your New Programs
|
| 624 |
-
|
| 625 |
-
If you develop a new program, and you want it to be of the greatest
|
| 626 |
-
possible use to the public, the best way to achieve this is to make it
|
| 627 |
-
free software which everyone can redistribute and change under these terms.
|
| 628 |
-
|
| 629 |
-
To do so, attach the following notices to the program. It is safest
|
| 630 |
-
to attach them to the start of each source file to most effectively
|
| 631 |
-
state the exclusion of warranty; and each file should have at least
|
| 632 |
-
the "copyright" line and a pointer to where the full notice is found.
|
| 633 |
-
|
| 634 |
-
<one line to give the program's name and a brief idea of what it does.>
|
| 635 |
-
Copyright (C) <year> <name of author>
|
| 636 |
-
|
| 637 |
-
This program is free software: you can redistribute it and/or modify
|
| 638 |
-
it under the terms of the GNU General Public License as published by
|
| 639 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 640 |
-
(at your option) any later version.
|
| 641 |
-
|
| 642 |
-
This program is distributed in the hope that it will be useful,
|
| 643 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 644 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 645 |
-
GNU General Public License for more details.
|
| 646 |
-
|
| 647 |
-
You should have received a copy of the GNU General Public License
|
| 648 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 649 |
-
|
| 650 |
-
Also add information on how to contact you by electronic and paper mail.
|
| 651 |
-
|
| 652 |
-
If the program does terminal interaction, make it output a short
|
| 653 |
-
notice like this when it starts in an interactive mode:
|
| 654 |
-
|
| 655 |
-
<program> Copyright (C) <year> <name of author>
|
| 656 |
-
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
| 657 |
-
This is free software, and you are welcome to redistribute it
|
| 658 |
-
under certain conditions; type `show c' for details.
|
| 659 |
-
|
| 660 |
-
The hypothetical commands `show w' and `show c' should show the appropriate
|
| 661 |
-
parts of the General Public License. Of course, your program's commands
|
| 662 |
-
might be different; for a GUI interface, you would use an "about box".
|
| 663 |
-
|
| 664 |
-
You should also get your employer (if you work as a programmer) or school,
|
| 665 |
-
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
| 666 |
-
For more information on this, and how to apply and follow the GNU GPL, see
|
| 667 |
-
<http://www.gnu.org/licenses/>.
|
| 668 |
-
|
| 669 |
-
The GNU General Public License does not permit incorporating your program
|
| 670 |
-
into proprietary programs. If your program is a subroutine library, you
|
| 671 |
-
may consider it more useful to permit linking proprietary applications with
|
| 672 |
-
the library. If this is what you want to do, use the GNU Lesser General
|
| 673 |
-
Public License instead of this License. But first, please read
|
| 674 |
-
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/MANIFEST.in
DELETED
|
@@ -1,2 +0,0 @@
|
|
| 1 |
-
include AUTHORS Copying.txt Readme.md test.py
|
| 2 |
-
recursive-include src *.h *.cpp
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/README.md
DELETED
|
@@ -1,126 +0,0 @@
|
|
| 1 |
-
# Fairy-Stockfish
|
| 2 |
-
|
| 3 |
-
## Overview
|
| 4 |
-
|
| 5 |
-
[](https://github.com/fairy-stockfish/Fairy-Stockfish/actions?query=workflow%3ARelease)
|
| 6 |
-
[](https://github.com/fairy-stockfish/Fairy-Stockfish/actions?query=workflow%3Afairy)
|
| 7 |
-
[](https://ci.appveyor.com/project/ianfab/Fairy-Stockfish/branch/master)
|
| 8 |
-
[](https://badge.fury.io/py/pyffish)
|
| 9 |
-
[](https://www.npmjs.com/package/ffish)
|
| 10 |
-
|
| 11 |
-
Fairy-Stockfish is a chess variant engine derived from [Stockfish](https://github.com/official-stockfish/Stockfish/) designed for the support of fairy chess variants and easy extensibility with more games. It can play various regional, historical, and modern chess variants as well as [games with user-defined rules](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Variant-configuration). For [compatibility with graphical user interfaces](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Graphical-user-interfaces) it supports the UCI, UCCI, USI, UCI-cyclone, and CECP/XBoard protocols.
|
| 12 |
-
|
| 13 |
-
The goal of the project is to create an engine supporting a large variety of chess-like games, equipped with the powerful search of Stockfish. Despite its generality the [playing strength](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Playing-strength) is on a very high level in almost all supported variants. Due to its multi-protocol support Fairy-Stockfish works with almost any chess variant GUI.
|
| 14 |
-
|
| 15 |
-
## Installation
|
| 16 |
-
You can download the [Windows executable](https://github.com/fairy-stockfish/Fairy-Stockfish/releases/latest/download/fairy-stockfish-largeboard_x86-64.exe) or [Linux binary](https://github.com/fairy-stockfish/Fairy-Stockfish/releases/latest/download/fairy-stockfish-largeboard_x86-64) from the [latest release](https://github.com/fairy-stockfish/Fairy-Stockfish/releases/latest) or [compile the program from source](https://github.com/fairy-stockfish/Fairy-Stockfish#compiling-stockfish-yourself-from-the-sources). The program comes without a graphical user interface, so you perhaps want to use it together with a [compatible GUI](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Graphical-user-interfaces), or [play against it online](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Online) at [pychess](https://www.pychess.org/), [lishogi](https://lishogi.org/@/Fairy-Stockfish), or [lichess](https://lichess.org/@/Fairy-Stockfish). Read more about [how to use](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Usage) Fairy-Stockfish in the wiki.
|
| 17 |
-
|
| 18 |
-
If you want to preview the functionality of Fairy-Stockfish before downloading, you can try it out on the [Fairy-Stockfish playground](https://fairyground.vercel.app/) in the browser.
|
| 19 |
-
|
| 20 |
-
Optional NNUE evaluation parameter files to improve playing strength for many variants are in the [list of NNUE networks](https://fairy-stockfish.github.io/nnue/#current-best-nnue-networks).
|
| 21 |
-
For the regional variants Xiangqi, Janggi, and Makruk [dedicated releases with built-in NNUE networks](https://github.com/fairy-stockfish/Fairy-Stockfish-NNUE) are available. See the [wiki](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/NNUE) for more details on NNUE.
|
| 22 |
-
|
| 23 |
-
## Contributing
|
| 24 |
-
|
| 25 |
-
If you like this project, please support its development via [patreon](https://www.patreon.com/ianfab), [paypal](https://paypal.me/FairyStockfish), or [github](https://github.com/sponsors/ianfab), or by [contributing to the code](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Contributing) or documentation. An [introduction to the code base](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Understanding-the-code) can be found in the wiki.
|
| 26 |
-
|
| 27 |
-
## Supported games
|
| 28 |
-
|
| 29 |
-
The games currently supported besides chess are listed below. Fairy-Stockfish can also play user-defined variants loaded via a variant configuration file, see the file [`src/variants.ini`](https://github.com/ianfab/Fairy-Stockfish/blob/master/src/variants.ini) and the [wiki](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Variant-configuration).
|
| 30 |
-
|
| 31 |
-
### Regional and historical games
|
| 32 |
-
- [Xiangqi](https://en.wikipedia.org/wiki/Xiangqi), [Manchu](https://en.wikipedia.org/wiki/Manchu_chess), [Minixiangqi](https://www.pychess.org/variants/minixiangqi), [Supply chess](https://en.wikipedia.org/wiki/Xiangqi#Variations)
|
| 33 |
-
- [Shogi](https://en.wikipedia.org/wiki/Shogi), [Shogi variants](https://github.com/fairy-stockfish/Fairy-Stockfish#shogi-variants)
|
| 34 |
-
- [Janggi](https://en.wikipedia.org/wiki/Janggi)
|
| 35 |
-
- [Makruk](https://en.wikipedia.org/wiki/Makruk), [ASEAN](http://hgm.nubati.net/rules/ASEAN.html), Makpong, Ai-Wok
|
| 36 |
-
- [Ouk Chatrang](https://en.wikipedia.org/wiki/Makruk#Cambodian_chess), [Kar Ouk](https://en.wikipedia.org/wiki/Makruk#Cambodian_chess)
|
| 37 |
-
- [Sittuyin](https://en.wikipedia.org/wiki/Sittuyin)
|
| 38 |
-
- [Shatar](https://en.wikipedia.org/wiki/Shatar), [Jeson Mor](https://en.wikipedia.org/wiki/Jeson_Mor)
|
| 39 |
-
- [Shatranj](https://en.wikipedia.org/wiki/Shatranj), [Courier](https://en.wikipedia.org/wiki/Courier_chess)
|
| 40 |
-
- [Raazuvaa](https://www.reddit.com/r/chess/comments/sj7y3n/raazuvaa_the_chess_of_the_maldives)
|
| 41 |
-
|
| 42 |
-
### Chess variants
|
| 43 |
-
- [Capablanca](https://en.wikipedia.org/wiki/Capablanca_Chess), [Janus](https://en.wikipedia.org/wiki/Janus_Chess), [Modern](https://en.wikipedia.org/wiki/Modern_Chess_(chess_variant)), [Chancellor](https://en.wikipedia.org/wiki/Chancellor_Chess), [Embassy](https://en.wikipedia.org/wiki/Embassy_Chess), [Gothic](https://www.chessvariants.com/large.dir/gothicchess.html), [Capablanca random chess](https://en.wikipedia.org/wiki/Capablanca_Random_Chess)
|
| 44 |
-
- [Grand](https://en.wikipedia.org/wiki/Grand_Chess), [Shako](https://www.chessvariants.com/large.dir/shako.html), [Centaur](https://www.chessvariants.com/large.dir/contest/royalcourt.html), [Tencubed](https://www.chessvariants.com/contests/10/tencubedchess.html), [Opulent](https://www.chessvariants.com/rules/opulent-chess)
|
| 45 |
-
- [Chess960](https://en.wikipedia.org/wiki/Chess960), [Placement/Pre-Chess](https://www.chessvariants.com/link/placement-chess)
|
| 46 |
-
- [Crazyhouse](https://en.wikipedia.org/wiki/Crazyhouse), [Loop](https://en.wikipedia.org/wiki/Crazyhouse#Variations), [Chessgi](https://en.wikipedia.org/wiki/Crazyhouse#Variations), [Pocket Knight](http://www.chessvariants.com/other.dir/pocket.html), Capablanca-Crazyhouse
|
| 47 |
-
- [Bughouse](https://en.wikipedia.org/wiki/Bughouse_chess), [Koedem](http://schachclub-oetigheim.de/wp-content/uploads/2016/04/Koedem-rules.pdf)
|
| 48 |
-
- [Seirawan](https://en.wikipedia.org/wiki/Seirawan_chess), Seirawan-Crazyhouse, [Dragon Chess](https://www.edami.com/dragonchess/)
|
| 49 |
-
- [Amazon](https://www.chessvariants.com/diffmove.dir/amazone.html), [Chigorin](https://www.chessvariants.com/diffsetup.dir/chigorin.html), [Almost chess](https://en.wikipedia.org/wiki/Almost_Chess)
|
| 50 |
-
- [Hoppel-Poppel](http://www.chessvariants.com/diffmove.dir/hoppel-poppel.html), New Zealand
|
| 51 |
-
- [Antichess](https://lichess.org/variant/antichess), [Giveaway](http://www.chessvariants.com/diffobjective.dir/giveaway.old.html), [Suicide](https://www.freechess.org/Help/HelpFiles/suicide_chess.html), [Losers](https://www.chessclub.com/help/Wild17), [Codrus](http://www.binnewirtz.com/Schlagschach1.htm)
|
| 52 |
-
- [Extinction](https://en.wikipedia.org/wiki/Extinction_chess), [Kinglet](https://en.wikipedia.org/wiki/V._R._Parton#Kinglet_chess), Three Kings, [Coregal](https://www.chessvariants.com/winning.dir/coregal.html)
|
| 53 |
-
- [King of the Hill](https://en.wikipedia.org/wiki/King_of_the_Hill_(chess)), [Racing Kings](https://en.wikipedia.org/wiki/V._R._Parton#Racing_Kings)
|
| 54 |
-
- [Three-check](https://en.wikipedia.org/wiki/Three-check_chess), Five-check
|
| 55 |
-
- [Los Alamos](https://en.wikipedia.org/wiki/Los_Alamos_chess), [Gardner's Minichess](https://en.wikipedia.org/wiki/Minichess#5%C3%975_chess)
|
| 56 |
-
- [Atomic](https://en.wikipedia.org/wiki/Atomic_chess)
|
| 57 |
-
- [Horde](https://en.wikipedia.org/wiki/Dunsany%27s_Chess#Horde_Chess), [Maharajah and the Sepoys](https://en.wikipedia.org/wiki/Maharajah_and_the_Sepoys)
|
| 58 |
-
- [Knightmate](https://www.chessvariants.com/diffobjective.dir/knightmate.html), [Nightrider](https://en.wikipedia.org/wiki/Nightrider_(chess)), [Grasshopper](https://en.wikipedia.org/wiki/Grasshopper_chess)
|
| 59 |
-
- [Duck chess](https://duckchess.com/), [Omicron](http://www.eglebbk.dds.nl/program/chess-omicron.html), [Gustav III](https://www.chessvariants.com/play/gustav-iiis-chess)
|
| 60 |
-
- [Berolina Chess](https://en.wikipedia.org/wiki/Berolina_pawn#Berolina_chess), [Pawn-Sideways](https://arxiv.org/abs/2009.04374), [Pawn-Back](https://arxiv.org/abs/2009.04374), [Torpedo](https://arxiv.org/abs/2009.04374), [Legan Chess](https://en.wikipedia.org/wiki/Legan_chess)
|
| 61 |
-
- [Spartan Chess](https://www.chessvariants.com/rules/spartan-chess)
|
| 62 |
-
- [Wolf Chess](https://en.wikipedia.org/wiki/Wolf_chess)
|
| 63 |
-
- [Troitzky Chess](https://www.chessvariants.com/play/troitzky-chess)
|
| 64 |
-
|
| 65 |
-
### Shogi variants
|
| 66 |
-
- [Minishogi](https://en.wikipedia.org/wiki/Minishogi), [EuroShogi](https://en.wikipedia.org/wiki/EuroShogi), [Judkins shogi](https://en.wikipedia.org/wiki/Judkins_shogi)
|
| 67 |
-
- [Kyoto shogi](https://en.wikipedia.org/wiki/Kyoto_shogi), [Microshogi](https://en.wikipedia.org/wiki/Micro_shogi)
|
| 68 |
-
- [Dobutsu shogi](https://en.wikipedia.org/wiki/Dōbutsu_shōgi), [Goro goro shogi](https://en.wikipedia.org/wiki/D%C5%8Dbutsu_sh%C5%8Dgi#Variation)
|
| 69 |
-
- [Tori shogi](https://en.wikipedia.org/wiki/Tori_shogi)
|
| 70 |
-
- [Yari shogi](https://en.wikipedia.org/wiki/Yari_shogi)
|
| 71 |
-
- [Okisaki shogi](https://en.wikipedia.org/wiki/Okisaki_shogi)
|
| 72 |
-
- [Sho shogi](https://en.wikipedia.org/wiki/Sho_shogi)
|
| 73 |
-
|
| 74 |
-
### Related games
|
| 75 |
-
- [Amazons](https://en.wikipedia.org/wiki/Game_of_the_Amazons)
|
| 76 |
-
- [Ataxx](https://en.wikipedia.org/wiki/Ataxx)
|
| 77 |
-
- [Breakthrough](https://en.wikipedia.org/wiki/Breakthrough_(board_game))
|
| 78 |
-
- [Clobber](https://en.wikipedia.org/wiki/Clobber)
|
| 79 |
-
- [Cfour](https://en.wikipedia.org/wiki/Connect_Four), [Tic-tac-toe](https://en.wikipedia.org/wiki/Tic-tac-toe)
|
| 80 |
-
- [Five Field Kono](https://en.wikipedia.org/wiki/Five_Field_Kono)
|
| 81 |
-
- [Flipersi](https://en.wikipedia.org/wiki/Reversi), [Flipello](https://en.wikipedia.org/wiki/Reversi#Othello)
|
| 82 |
-
- [Fox and Hounds](https://boardgamegeek.com/boardgame/148180/fox-and-hounds)
|
| 83 |
-
- [Isolation](https://boardgamegeek.com/boardgame/1875/isolation)
|
| 84 |
-
- [Joust](https://www.chessvariants.com/programs.dir/joust.html)
|
| 85 |
-
- [Snailtrail](https://boardgamegeek.com/boardgame/37135/snailtrail)
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
## Help
|
| 89 |
-
|
| 90 |
-
See the [Fairy-Stockfish Wiki](https://github.com/fairy-stockfish/Fairy-Stockfish/wiki) for more info, or if the required information is not available, open an [issue](https://github.com/fairy-stockfish/Fairy-Stockfish/issues) or join our [discord server](https://discord.gg/FYUGgmCFB4).
|
| 91 |
-
|
| 92 |
-
## Bindings
|
| 93 |
-
|
| 94 |
-
Besides the C++ engine, this project also includes bindings for other programming languages in order to be able to use it as a library for chess variants. They support move, SAN, and FEN generation, as well as checking of game end conditions for all variants supported by Fairy-Stockfish. Since the bindings are using the C++ code, they are very performant compared to libraries directly written in the respective target language.
|
| 95 |
-
|
| 96 |
-
### Python
|
| 97 |
-
|
| 98 |
-
The python binding [pyffish](https://pypi.org/project/pyffish/) contributed by [@gbtami](https://github.com/gbtami) is implemented in [pyffish.cpp](https://github.com/fairy-stockfish/Fairy-Stockfish/blob/master/src/pyffish.cpp). It is e.g. used in the backend for the [pychess server](https://github.com/gbtami/pychess-variants).
|
| 99 |
-
|
| 100 |
-
### Javascript
|
| 101 |
-
|
| 102 |
-
The javascript binding [ffish.js](https://www.npmjs.com/package/ffish) contributed by [@QueensGambit](https://github.com/QueensGambit) is implemented in [ffishjs.cpp](https://github.com/fairy-stockfish/Fairy-Stockfish/blob/master/src/ffishjs.cpp). The compilation/binding to javascript is done using emscripten, see the [readme](https://github.com/fairy-stockfish/Fairy-Stockfish/tree/master/tests/js).
|
| 103 |
-
|
| 104 |
-
## Ports
|
| 105 |
-
|
| 106 |
-
### WebAssembly
|
| 107 |
-
|
| 108 |
-
For in-browser use a [port of Fairy-Stockfish to WebAssembly](https://github.com/fairy-stockfish/fairy-stockfish.wasm) is available at [npm](https://www.npmjs.com/package/fairy-stockfish-nnue.wasm). It is e.g. used for local analysis on [pychess.org](https://www.pychess.org/analysis/chess). Also see the [Fairy-Stockfish WASM demo](https://github.com/ianfab/fairy-stockfish-nnue-wasm-demo) available at https://fairy-stockfish-nnue-wasm.vercel.app/.
|
| 109 |
-
|
| 110 |
-
## Terms of use
|
| 111 |
-
|
| 112 |
-
Fairy-Stockfish is free, and distributed under the **GNU General Public License version 3**
|
| 113 |
-
(GPL v3). Essentially, this means you are free to do almost exactly
|
| 114 |
-
what you want with the program, including distributing it among your
|
| 115 |
-
friends, making it available for download from your website, selling
|
| 116 |
-
it (either by itself or as part of some bigger software package), or
|
| 117 |
-
using it as the starting point for a software project of your own.
|
| 118 |
-
|
| 119 |
-
The only real limitation is that whenever you distribute Fairy-Stockfish in
|
| 120 |
-
some way, you MUST always include the full source code, or a pointer
|
| 121 |
-
to where the source code can be found, to generate the exact binary
|
| 122 |
-
you are distributing. If you make any changes to the source code,
|
| 123 |
-
these changes must also be made available under the GPL.
|
| 124 |
-
|
| 125 |
-
For full details, read the copy of the GPL v3 found in the file named
|
| 126 |
-
[*Copying.txt*](https://github.com/fairy-stockfish/Fairy-Stockfish/blob/master/Copying.txt).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/Top CPU Contributors.txt
DELETED
|
@@ -1,205 +0,0 @@
|
|
| 1 |
-
Contributors to Fishtest with >10,000 CPU hours, as of Jun 29, 2021.
|
| 2 |
-
Thank you!
|
| 3 |
-
|
| 4 |
-
Username CPU Hours Games played
|
| 5 |
-
-----------------------------------------------------
|
| 6 |
-
noobpwnftw 27649494 1834734733
|
| 7 |
-
mlang 1426107 89454622
|
| 8 |
-
dew 1380910 82831648
|
| 9 |
-
mibere 703840 46867607
|
| 10 |
-
grandphish2 692707 41737913
|
| 11 |
-
tvijlbrief 669642 42371594
|
| 12 |
-
JojoM 597778 35297180
|
| 13 |
-
TueRens 519226 31823562
|
| 14 |
-
cw 458421 30307421
|
| 15 |
-
fastgm 439667 25950040
|
| 16 |
-
gvreuls 436599 28177460
|
| 17 |
-
crunchy 427035 27344275
|
| 18 |
-
CSU_Dynasty 374765 25106278
|
| 19 |
-
Fisherman 326901 21822979
|
| 20 |
-
ctoks 325477 21767943
|
| 21 |
-
velislav 295343 18844324
|
| 22 |
-
linrock 292789 10624427
|
| 23 |
-
bcross 278584 19488961
|
| 24 |
-
okrout 262818 13803272
|
| 25 |
-
pemo 245982 11376085
|
| 26 |
-
glinscott 217799 13780820
|
| 27 |
-
leszek 212346 12959025
|
| 28 |
-
nordlandia 211692 13484886
|
| 29 |
-
bking_US 198894 11876016
|
| 30 |
-
drabel 196463 13450602
|
| 31 |
-
robal 195473 12375650
|
| 32 |
-
mgrabiak 187226 12016564
|
| 33 |
-
Dantist 183202 10990484
|
| 34 |
-
Thanar 179852 12365359
|
| 35 |
-
vdv 175274 9889046
|
| 36 |
-
spams 157128 10319326
|
| 37 |
-
marrco 150295 9402141
|
| 38 |
-
sqrt2 147963 9724586
|
| 39 |
-
mhoram 141278 8901241
|
| 40 |
-
CoffeeOne 137100 5024116
|
| 41 |
-
vdbergh 137041 8926915
|
| 42 |
-
malala 136182 8002293
|
| 43 |
-
xoto 133702 9156676
|
| 44 |
-
davar 122092 7960001
|
| 45 |
-
dsmith 122059 7570238
|
| 46 |
-
Data 113305 8220352
|
| 47 |
-
BrunoBanani 112960 7436849
|
| 48 |
-
MaZePallas 102823 6633619
|
| 49 |
-
sterni1971 100532 5880772
|
| 50 |
-
ElbertoOne 99028 7023771
|
| 51 |
-
brabos 92118 6186135
|
| 52 |
-
oz 92100 6486640
|
| 53 |
-
psk 89957 5984901
|
| 54 |
-
amicic 89156 5392305
|
| 55 |
-
sunu 88851 6028873
|
| 56 |
-
Vizvezdenec 83761 5344740
|
| 57 |
-
0x3C33 82614 5271253
|
| 58 |
-
BRAVONE 81239 5054681
|
| 59 |
-
racerschmacer 80899 5759262
|
| 60 |
-
cuistot 80300 4606144
|
| 61 |
-
nssy 76497 5259388
|
| 62 |
-
teddybaer 75125 5407666
|
| 63 |
-
Pking_cda 73776 5293873
|
| 64 |
-
jromang 72192 5057715
|
| 65 |
-
solarlight 70517 5028306
|
| 66 |
-
dv8silencer 70287 3883992
|
| 67 |
-
Bobo1239 68515 4652287
|
| 68 |
-
manap 66273 4121774
|
| 69 |
-
skiminki 65088 4023328
|
| 70 |
-
tinker 64333 4268790
|
| 71 |
-
sschnee 60767 3500800
|
| 72 |
-
qurashee 57344 3168264
|
| 73 |
-
robnjr 57262 4053117
|
| 74 |
-
Freja 56938 3733019
|
| 75 |
-
ttruscott 56010 3680085
|
| 76 |
-
rkl 55132 4164467
|
| 77 |
-
renouve 53811 3501516
|
| 78 |
-
finfish 51360 3370515
|
| 79 |
-
eva42 51272 3599691
|
| 80 |
-
rap 49985 3219146
|
| 81 |
-
pb00067 49727 3298270
|
| 82 |
-
ronaldjerum 47654 3240695
|
| 83 |
-
bigpen0r 47653 3335327
|
| 84 |
-
eastorwest 47585 3221629
|
| 85 |
-
biffhero 46564 3111352
|
| 86 |
-
VoyagerOne 45476 3452465
|
| 87 |
-
yurikvelo 44834 3034550
|
| 88 |
-
speedycpu 43842 3003273
|
| 89 |
-
jbwiebe 43305 2805433
|
| 90 |
-
Spprtr 42279 2680153
|
| 91 |
-
DesolatedDodo 42007 2447516
|
| 92 |
-
Antihistamine 41788 2761312
|
| 93 |
-
mhunt 41735 2691355
|
| 94 |
-
homyur 39893 2850481
|
| 95 |
-
gri 39871 2515779
|
| 96 |
-
Fifis 38776 2529121
|
| 97 |
-
oryx 38724 2966648
|
| 98 |
-
SC 37290 2731014
|
| 99 |
-
csnodgrass 36207 2688994
|
| 100 |
-
jmdana 36157 2210661
|
| 101 |
-
strelock 34716 2074055
|
| 102 |
-
rpngn 33951 2057395
|
| 103 |
-
Garf 33922 2751802
|
| 104 |
-
EthanOConnor 33370 2090311
|
| 105 |
-
slakovv 32915 2021889
|
| 106 |
-
manapbk 30987 1810399
|
| 107 |
-
Prcuvu 30377 2170122
|
| 108 |
-
anst 30301 2190091
|
| 109 |
-
jkiiski 30136 1904470
|
| 110 |
-
hyperbolic.tom 29840 2017394
|
| 111 |
-
Pyafue 29650 1902349
|
| 112 |
-
Wolfgang 29260 1658936
|
| 113 |
-
zeryl 28156 1579911
|
| 114 |
-
OuaisBla 27636 1578800
|
| 115 |
-
DMBK 27051 1999456
|
| 116 |
-
chriswk 26902 1868317
|
| 117 |
-
achambord 26582 1767323
|
| 118 |
-
Patrick_G 26276 1801617
|
| 119 |
-
yorkman 26193 1992080
|
| 120 |
-
SFTUser 25182 1675689
|
| 121 |
-
nabildanial 24942 1519409
|
| 122 |
-
Sharaf_DG 24765 1786697
|
| 123 |
-
ncfish1 24411 1520927
|
| 124 |
-
rodneyc 24227 1409514
|
| 125 |
-
agg177 23890 1395014
|
| 126 |
-
JanErik 23408 1703875
|
| 127 |
-
Isidor 23388 1680691
|
| 128 |
-
Norabor 23164 1591830
|
| 129 |
-
cisco2015 22897 1762669
|
| 130 |
-
Zirie 22542 1472937
|
| 131 |
-
team-oh 22272 1636708
|
| 132 |
-
MazeOfGalious 21978 1629593
|
| 133 |
-
sg4032 21947 1643265
|
| 134 |
-
ianh2105 21725 1632562
|
| 135 |
-
xor12 21628 1680365
|
| 136 |
-
dex 21612 1467203
|
| 137 |
-
nesoneg 21494 1463031
|
| 138 |
-
sphinx 21211 1384728
|
| 139 |
-
jjoshua2 21001 1423089
|
| 140 |
-
horst.prack 20878 1465656
|
| 141 |
-
Ente 20865 1477066
|
| 142 |
-
0xB00B1ES 20590 1208666
|
| 143 |
-
j3corre 20405 941444
|
| 144 |
-
Adrian.Schmidt123 20316 1281436
|
| 145 |
-
wei 19973 1745989
|
| 146 |
-
MaxKlaxxMiner 19850 1009176
|
| 147 |
-
rstoesser 19569 1293588
|
| 148 |
-
gopeto 19491 1174952
|
| 149 |
-
eudhan 19274 1283717
|
| 150 |
-
jundery 18445 1115855
|
| 151 |
-
megaman7de 18377 1067540
|
| 152 |
-
iisiraider 18247 1101015
|
| 153 |
-
ville 17883 1384026
|
| 154 |
-
chris 17698 1487385
|
| 155 |
-
purplefishies 17595 1092533
|
| 156 |
-
dju 17353 978595
|
| 157 |
-
DragonLord 17014 1162790
|
| 158 |
-
IgorLeMasson 16064 1147232
|
| 159 |
-
ako027ako 15671 1173203
|
| 160 |
-
chuckstablers 15289 891576
|
| 161 |
-
Nikolay.IT 15154 1068349
|
| 162 |
-
Andrew Grant 15114 895539
|
| 163 |
-
OssumOpossum 14857 1007129
|
| 164 |
-
Karby 14808 867120
|
| 165 |
-
enedene 14476 905279
|
| 166 |
-
bpfliegel 14298 884523
|
| 167 |
-
mpx86 14019 759568
|
| 168 |
-
jpulman 13982 870599
|
| 169 |
-
crocogoat 13803 1117422
|
| 170 |
-
joster 13794 950160
|
| 171 |
-
Nesa92 13786 1114691
|
| 172 |
-
Hjax 13535 915487
|
| 173 |
-
jsys14 13459 785000
|
| 174 |
-
Dark_wizzie 13422 1007152
|
| 175 |
-
mabichito 12903 749391
|
| 176 |
-
thijsk 12886 722107
|
| 177 |
-
AdrianSA 12860 804972
|
| 178 |
-
Flopzee 12698 894821
|
| 179 |
-
fatmurphy 12547 853210
|
| 180 |
-
Rudolphous 12520 832340
|
| 181 |
-
scuzzi 12511 845761
|
| 182 |
-
SapphireBrand 12416 969604
|
| 183 |
-
modolief 12386 896470
|
| 184 |
-
Machariel 12335 810784
|
| 185 |
-
pgontarz 12151 848794
|
| 186 |
-
stocky 11954 699440
|
| 187 |
-
mschmidt 11941 803401
|
| 188 |
-
Maxim 11543 836024
|
| 189 |
-
infinity 11470 727027
|
| 190 |
-
torbjo 11395 729145
|
| 191 |
-
Thomas A. Anderson 11372 732094
|
| 192 |
-
savage84 11358 670860
|
| 193 |
-
d64 11263 789184
|
| 194 |
-
MooTheCow 11237 720174
|
| 195 |
-
snicolet 11106 869170
|
| 196 |
-
ali-al-zhrani 11086 767926
|
| 197 |
-
AndreasKrug 10875 887457
|
| 198 |
-
pirt 10806 836519
|
| 199 |
-
basepi 10637 744851
|
| 200 |
-
michaelrpg 10508 739039
|
| 201 |
-
dzjp 10343 732529
|
| 202 |
-
aga 10302 622975
|
| 203 |
-
ols 10259 570669
|
| 204 |
-
lbraesch 10252 647825
|
| 205 |
-
FormazChar 10059 757283
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/appveyor.yml
DELETED
|
@@ -1,91 +0,0 @@
|
|
| 1 |
-
version: 1.0.{build}
|
| 2 |
-
clone_depth: 50
|
| 3 |
-
|
| 4 |
-
branches:
|
| 5 |
-
only:
|
| 6 |
-
- master
|
| 7 |
-
- merge
|
| 8 |
-
- appveyor
|
| 9 |
-
|
| 10 |
-
# Operating system (build VM template)
|
| 11 |
-
os: Visual Studio 2019
|
| 12 |
-
|
| 13 |
-
# Build platform, i.e. x86, x64, AnyCPU. This setting is optional.
|
| 14 |
-
platform:
|
| 15 |
-
- x86
|
| 16 |
-
- x64
|
| 17 |
-
|
| 18 |
-
# build Configuration, i.e. Debug, Release, etc.
|
| 19 |
-
configuration:
|
| 20 |
-
- Debug
|
| 21 |
-
- Release
|
| 22 |
-
|
| 23 |
-
matrix:
|
| 24 |
-
# The build fail immediately once one of the job fails
|
| 25 |
-
fast_finish: true
|
| 26 |
-
|
| 27 |
-
# Scripts that are called at very beginning, before repo cloning
|
| 28 |
-
init:
|
| 29 |
-
- cmake --version
|
| 30 |
-
- msbuild /version
|
| 31 |
-
|
| 32 |
-
before_build:
|
| 33 |
-
- ps: |
|
| 34 |
-
# Get sources
|
| 35 |
-
$src = get-childitem -Path *.cpp -Recurse -Exclude pyffish.cpp,ffishjs.cpp | select -ExpandProperty FullName
|
| 36 |
-
$src = $src -join ' '
|
| 37 |
-
$src = $src.Replace("\", "/")
|
| 38 |
-
|
| 39 |
-
# Build CMakeLists.txt
|
| 40 |
-
$t = 'cmake_minimum_required(VERSION 3.17)',
|
| 41 |
-
'project(Stockfish)',
|
| 42 |
-
'set(CMAKE_CXX_STANDARD 17)',
|
| 43 |
-
'set(CMAKE_CXX_STANDARD_REQUIRED ON)',
|
| 44 |
-
'set (CMAKE_CXX_EXTENSIONS OFF)',
|
| 45 |
-
'set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src)',
|
| 46 |
-
'set(source_files', $src, ')',
|
| 47 |
-
'add_compile_definitions(NNUE_EMBEDDING_OFF)',
|
| 48 |
-
'add_executable(stockfish ${source_files})'
|
| 49 |
-
|
| 50 |
-
# Write CMakeLists.txt without BOM
|
| 51 |
-
$MyPath = (Get-Item -Path "." -Verbose).FullName + '\CMakeLists.txt'
|
| 52 |
-
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
|
| 53 |
-
[System.IO.File]::WriteAllLines($MyPath, $t, $Utf8NoBomEncoding)
|
| 54 |
-
|
| 55 |
-
# Obtain bench reference from git log
|
| 56 |
-
$b = git log HEAD | sls "\b[Bb]ench[ :]+[0-9]{7}" | select -first 1
|
| 57 |
-
$bench = $b -match '\D+(\d+)' | % { $matches[1] }
|
| 58 |
-
Write-Host "Reference bench:" $bench
|
| 59 |
-
$g = "Visual Studio 16 2019"
|
| 60 |
-
If (${env:PLATFORM} -eq 'x64') { $a = "x64" }
|
| 61 |
-
If (${env:PLATFORM} -eq 'x86') { $a = "Win32" }
|
| 62 |
-
cmake -G "${g}" -A ${a} .
|
| 63 |
-
Write-Host "Generated files for: " $g $a
|
| 64 |
-
|
| 65 |
-
build_script:
|
| 66 |
-
- cmake --build . --config %CONFIGURATION% -- /verbosity:minimal
|
| 67 |
-
- ps: |
|
| 68 |
-
# Download default NNUE net from fishtest
|
| 69 |
-
$nnuenet = Get-Content -Path src\evaluate.h | Select-String -CaseSensitive -Pattern "EvalFileDefaultName" | Select-String -CaseSensitive -Pattern "nn-[a-z0-9]{12}.nnue"
|
| 70 |
-
$dummy = $nnuenet -match "(?<nnuenet>nn-[a-z0-9]{12}.nnue)"
|
| 71 |
-
$nnuenet = $Matches.nnuenet
|
| 72 |
-
Write-Host "Default net:" $nnuenet
|
| 73 |
-
$nnuedownloadurl = "https://github.com/official-stockfish/networks/raw/master/$nnuenet"
|
| 74 |
-
$nnuefilepath = "src\${env:CONFIGURATION}\$nnuenet"
|
| 75 |
-
if (Test-Path -Path $nnuefilepath) {
|
| 76 |
-
Write-Host "Already available."
|
| 77 |
-
} else {
|
| 78 |
-
Write-Host "Downloading $nnuedownloadurl to $nnuefilepath"
|
| 79 |
-
Invoke-WebRequest -Uri $nnuedownloadurl -OutFile $nnuefilepath
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
before_test:
|
| 83 |
-
- cd src/%CONFIGURATION%
|
| 84 |
-
- stockfish bench 2> out.txt >NUL
|
| 85 |
-
- ps: |
|
| 86 |
-
# Verify bench number
|
| 87 |
-
$s = (gc "./out.txt" | out-string)
|
| 88 |
-
$r = ($s -match 'Nodes searched \D+(\d+)' | % { $matches[1] })
|
| 89 |
-
Write-Host "Engine bench:" $r
|
| 90 |
-
Write-Host "Reference bench:" $bench
|
| 91 |
-
If ($r -ne $bench) { exit 1 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/pyffish.pyi
DELETED
|
@@ -1,39 +0,0 @@
|
|
| 1 |
-
from typing import Any
|
| 2 |
-
|
| 3 |
-
FEN_OK: int
|
| 4 |
-
NOTATION_DEFAULT: int
|
| 5 |
-
NOTATION_JANGGI: int
|
| 6 |
-
NOTATION_LAN: int
|
| 7 |
-
NOTATION_SAN: int
|
| 8 |
-
NOTATION_SHOGI_HODGES: int
|
| 9 |
-
NOTATION_SHOGI_HODGES_NUMBER: int
|
| 10 |
-
NOTATION_SHOGI_HOSKING: int
|
| 11 |
-
NOTATION_THAI_LAN: int
|
| 12 |
-
NOTATION_THAI_SAN: int
|
| 13 |
-
NOTATION_XIANGQI_WXF: int
|
| 14 |
-
VALUE_DRAW: int
|
| 15 |
-
VALUE_MATE: int
|
| 16 |
-
|
| 17 |
-
class error(Exception): ...
|
| 18 |
-
|
| 19 |
-
def version() -> tuple[int, int, int]: ...
|
| 20 |
-
def info() -> str: ...
|
| 21 |
-
def variants() -> list[str]: ...
|
| 22 |
-
def set_option(name: str, value: Any) -> None: ...
|
| 23 |
-
def load_variant_config(config: str) -> None: ...
|
| 24 |
-
def start_fen(variant: str) -> str: ...
|
| 25 |
-
def two_boards(variant: str) -> bool: ...
|
| 26 |
-
def captures_to_hand(variant: str) -> bool: ...
|
| 27 |
-
def get_san(variant: str, fen: str, move: str, chess960: bool = False, notation: int = NOTATION_DEFAULT) -> str: ...
|
| 28 |
-
def get_san_moves(variant: str, fen: str, movelist: list[str], chess960: bool = False, notation: int = NOTATION_DEFAULT) -> list[str]: ...
|
| 29 |
-
def legal_moves(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> list[str]: ...
|
| 30 |
-
def get_fen(variant: str, fen: str, movelist: list[str], chess960: bool = False, sfen: bool = False, show_promoted: bool = False, count_started: int = 0) -> str: ...
|
| 31 |
-
def gives_check(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> bool: ...
|
| 32 |
-
def is_capture(variant: str, fen: str, movelist: list[str], move: str, chess960: bool = False) -> bool: ...
|
| 33 |
-
def piece_to_partner(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> str: ...
|
| 34 |
-
def game_result(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> int: ...
|
| 35 |
-
def is_immediate_game_end(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> tuple[bool, int]: ...
|
| 36 |
-
def is_optional_game_end(variant: str, fen: str, movelist: list[str], chess960: bool = False, count_started: int = 0) -> tuple[bool, int]: ...
|
| 37 |
-
def has_insufficient_material(variant: str, fen: str, movelist: list[str], chess960: bool = False) -> tuple[bool, bool]: ...
|
| 38 |
-
def validate_fen(fen: str, variant: str, chess960: bool = False) -> int: ...
|
| 39 |
-
def get_fog_fen(fen: str, variant: str, chess960: bool = False) -> str: ...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/setup.py
DELETED
|
@@ -1,56 +0,0 @@
|
|
| 1 |
-
# -*- coding: utf-8 -*-
|
| 2 |
-
|
| 3 |
-
from setuptools import setup, Extension
|
| 4 |
-
from glob import glob
|
| 5 |
-
import platform
|
| 6 |
-
import io
|
| 7 |
-
import os
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
if platform.python_compiler().startswith("MSC"):
|
| 11 |
-
args = ["/std:c++17"]
|
| 12 |
-
else:
|
| 13 |
-
args = ["-std=c++17", "-flto", "-Wno-date-time"]
|
| 14 |
-
|
| 15 |
-
args.extend(["-DLARGEBOARDS", "-DALLVARS", "-DPRECOMPUTED_MAGICS", "-DNNUE_EMBEDDING_OFF"])
|
| 16 |
-
|
| 17 |
-
if "64bit" in platform.architecture():
|
| 18 |
-
args.append("-DIS_64BIT")
|
| 19 |
-
|
| 20 |
-
CLASSIFIERS = [
|
| 21 |
-
"Development Status :: 3 - Alpha",
|
| 22 |
-
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
| 23 |
-
"Programming Language :: Python :: 3",
|
| 24 |
-
"Operating System :: OS Independent",
|
| 25 |
-
]
|
| 26 |
-
|
| 27 |
-
with io.open("README.md", "r", encoding="utf8") as fh:
|
| 28 |
-
long_description = fh.read().strip()
|
| 29 |
-
|
| 30 |
-
sources = glob("src/*.cpp") + glob("src/syzygy/*.cpp") + glob("src/nnue/*.cpp") + glob("src/nnue/features/*.cpp")
|
| 31 |
-
headers = glob("src/*.h") + glob("src/syzygy/*.h") + glob("src/nnue/*.h") + glob("src/nnue/features/*.h")
|
| 32 |
-
ffish_source_file = os.path.normcase("src/ffishjs.cpp")
|
| 33 |
-
try:
|
| 34 |
-
sources.remove(ffish_source_file)
|
| 35 |
-
except ValueError:
|
| 36 |
-
print(f"ffish_source_file {ffish_source_file} was not found in sources {sources}.")
|
| 37 |
-
|
| 38 |
-
pyffish_module = Extension(
|
| 39 |
-
"pyffish",
|
| 40 |
-
sources=sources,
|
| 41 |
-
depends=headers,
|
| 42 |
-
extra_compile_args=args)
|
| 43 |
-
|
| 44 |
-
setup(name="pyffish", version="0.0.89",
|
| 45 |
-
description="Fairy-Stockfish Python wrapper",
|
| 46 |
-
long_description=long_description,
|
| 47 |
-
long_description_content_type="text/markdown",
|
| 48 |
-
author="Bajusz Tamás",
|
| 49 |
-
author_email="gbtami@gmail.com",
|
| 50 |
-
license="GPL3",
|
| 51 |
-
classifiers=CLASSIFIERS,
|
| 52 |
-
url="https://github.com/gbtami/Fairy-Stockfish",
|
| 53 |
-
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
|
| 54 |
-
ext_modules=[pyffish_module],
|
| 55 |
-
data_files=[("", ["pyffish.pyi"])]
|
| 56 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/Makefile
DELETED
|
@@ -1,982 +0,0 @@
|
|
| 1 |
-
# Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 2 |
-
# Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 3 |
-
#
|
| 4 |
-
# Stockfish is free software: you can redistribute it and/or modify
|
| 5 |
-
# it under the terms of the GNU General Public License as published by
|
| 6 |
-
# the Free Software Foundation, either version 3 of the License, or
|
| 7 |
-
# (at your option) any later version.
|
| 8 |
-
#
|
| 9 |
-
# Stockfish is distributed in the hope that it will be useful,
|
| 10 |
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
-
# GNU General Public License for more details.
|
| 13 |
-
#
|
| 14 |
-
# You should have received a copy of the GNU General Public License
|
| 15 |
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
### ==========================================================================
|
| 19 |
-
### Section 1. General Configuration
|
| 20 |
-
### ==========================================================================
|
| 21 |
-
|
| 22 |
-
### Executable name
|
| 23 |
-
ifeq ($(COMP),mingw)
|
| 24 |
-
EXE = stockfish.exe
|
| 25 |
-
else
|
| 26 |
-
EXE = stockfish
|
| 27 |
-
endif
|
| 28 |
-
|
| 29 |
-
### Installation dir definitions
|
| 30 |
-
PREFIX = /usr/local
|
| 31 |
-
BINDIR = $(PREFIX)/bin
|
| 32 |
-
|
| 33 |
-
### Built-in benchmark for pgo-builds
|
| 34 |
-
ifeq ($(SDE_PATH),)
|
| 35 |
-
PGOBENCH = ./$(EXE) bench
|
| 36 |
-
else
|
| 37 |
-
PGOBENCH = $(SDE_PATH) -- ./$(EXE) bench
|
| 38 |
-
endif
|
| 39 |
-
|
| 40 |
-
### Source and object files
|
| 41 |
-
SRCS = benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp main.cpp \
|
| 42 |
-
material.cpp misc.cpp movegen.cpp movepick.cpp pawns.cpp position.cpp psqt.cpp \
|
| 43 |
-
search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \
|
| 44 |
-
nnue/evaluate_nnue.cpp nnue/features/half_ka_v2.cpp \
|
| 45 |
-
partner.cpp parser.cpp piece.cpp variant.cpp xboard.cpp \
|
| 46 |
-
nnue/features/half_ka_v2_variants.cpp
|
| 47 |
-
|
| 48 |
-
OBJS = $(notdir $(SRCS:.cpp=.o))
|
| 49 |
-
|
| 50 |
-
VPATH = syzygy:nnue:nnue/features
|
| 51 |
-
|
| 52 |
-
### Establish the operating system name
|
| 53 |
-
KERNEL = $(shell uname -s)
|
| 54 |
-
ifeq ($(KERNEL),Linux)
|
| 55 |
-
OS = $(shell uname -o)
|
| 56 |
-
endif
|
| 57 |
-
|
| 58 |
-
### ==========================================================================
|
| 59 |
-
### Section 2. High-level Configuration
|
| 60 |
-
### ==========================================================================
|
| 61 |
-
#
|
| 62 |
-
# flag --- Comp switch --- Description
|
| 63 |
-
# ----------------------------------------------------------------------------
|
| 64 |
-
#
|
| 65 |
-
# debug = yes/no --- -DNDEBUG --- Enable/Disable debug mode
|
| 66 |
-
# sanitize = none/<sanitizer> ... (-fsanitize )
|
| 67 |
-
# --- ( undefined ) --- enable undefined behavior checks
|
| 68 |
-
# --- ( thread ) --- enable threading error checks
|
| 69 |
-
# --- ( address ) --- enable memory access checks
|
| 70 |
-
# --- ...etc... --- see compiler documentation for supported sanitizers
|
| 71 |
-
# optimize = yes/no --- (-O3/-fast etc.) --- Enable/Disable optimizations
|
| 72 |
-
# arch = (name) --- (-arch) --- Target architecture
|
| 73 |
-
# bits = 64/32 --- -DIS_64BIT --- 64-/32-bit operating system
|
| 74 |
-
# prefetch = yes/no --- -DUSE_PREFETCH --- Use prefetch asm-instruction
|
| 75 |
-
# popcnt = yes/no --- -DUSE_POPCNT --- Use popcnt asm-instruction
|
| 76 |
-
# pext = yes/no --- -DUSE_PEXT --- Use pext x86_64 asm-instruction
|
| 77 |
-
# sse = yes/no --- -msse --- Use Intel Streaming SIMD Extensions
|
| 78 |
-
# mmx = yes/no --- -mmmx --- Use Intel MMX instructions
|
| 79 |
-
# sse2 = yes/no --- -msse2 --- Use Intel Streaming SIMD Extensions 2
|
| 80 |
-
# ssse3 = yes/no --- -mssse3 --- Use Intel Supplemental Streaming SIMD Extensions 3
|
| 81 |
-
# sse41 = yes/no --- -msse4.1 --- Use Intel Streaming SIMD Extensions 4.1
|
| 82 |
-
# avx2 = yes/no --- -mavx2 --- Use Intel Advanced Vector Extensions 2
|
| 83 |
-
# avx512 = yes/no --- -mavx512bw --- Use Intel Advanced Vector Extensions 512
|
| 84 |
-
# vnni256 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 256
|
| 85 |
-
# vnni512 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 512
|
| 86 |
-
# neon = yes/no --- -DUSE_NEON --- Use ARM SIMD architecture
|
| 87 |
-
#
|
| 88 |
-
# Note that Makefile is space sensitive, so when adding new architectures
|
| 89 |
-
# or modifying existing flags, you have to make sure there are no extra spaces
|
| 90 |
-
# at the end of the line for flag values.
|
| 91 |
-
#
|
| 92 |
-
# Example of use for these flags:
|
| 93 |
-
# make build ARCH=x86-64-avx512 debug=on sanitize="address undefined"
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
### 2.1. General and architecture defaults
|
| 97 |
-
largeboards = no
|
| 98 |
-
all = no
|
| 99 |
-
precomputedmagics = yes
|
| 100 |
-
nnue = no
|
| 101 |
-
load_net = $(if $(filter $(nnue),yes),net)
|
| 102 |
-
|
| 103 |
-
ifeq ($(ARCH),)
|
| 104 |
-
ARCH = x86-64-modern
|
| 105 |
-
help_skip_sanity = yes
|
| 106 |
-
endif
|
| 107 |
-
# explicitly check for the list of supported architectures (as listed with make help),
|
| 108 |
-
# the user can override with `make ARCH=x86-32-vnni256 SUPPORTED_ARCH=true`
|
| 109 |
-
ifeq ($(ARCH), $(filter $(ARCH), \
|
| 110 |
-
x86-64-vnni512 x86-64-vnni256 x86-64-avx512 x86-64-bmi2 x86-64-avx2 \
|
| 111 |
-
x86-64-sse41-popcnt x86-64-modern x86-64-ssse3 x86-64-sse3-popcnt \
|
| 112 |
-
x86-64 x86-32-sse41-popcnt x86-32-sse2 x86-32 ppc-64 ppc-32 e2k \
|
| 113 |
-
armv7 armv7-neon armv8 apple-silicon general-64 general-32))
|
| 114 |
-
SUPPORTED_ARCH=true
|
| 115 |
-
else
|
| 116 |
-
SUPPORTED_ARCH=false
|
| 117 |
-
endif
|
| 118 |
-
|
| 119 |
-
optimize = yes
|
| 120 |
-
debug = no
|
| 121 |
-
sanitize = none
|
| 122 |
-
bits = 64
|
| 123 |
-
prefetch = no
|
| 124 |
-
popcnt = no
|
| 125 |
-
pext = no
|
| 126 |
-
sse = no
|
| 127 |
-
mmx = no
|
| 128 |
-
sse2 = no
|
| 129 |
-
ssse3 = no
|
| 130 |
-
sse41 = no
|
| 131 |
-
avx2 = no
|
| 132 |
-
avx512 = no
|
| 133 |
-
vnni256 = no
|
| 134 |
-
vnni512 = no
|
| 135 |
-
neon = no
|
| 136 |
-
STRIP = strip
|
| 137 |
-
|
| 138 |
-
### 2.2 Architecture specific
|
| 139 |
-
|
| 140 |
-
ifeq ($(findstring x86,$(ARCH)),x86)
|
| 141 |
-
|
| 142 |
-
# x86-32/64
|
| 143 |
-
|
| 144 |
-
ifeq ($(findstring x86-32,$(ARCH)),x86-32)
|
| 145 |
-
arch = i386
|
| 146 |
-
bits = 32
|
| 147 |
-
sse = yes
|
| 148 |
-
mmx = yes
|
| 149 |
-
else
|
| 150 |
-
arch = x86_64
|
| 151 |
-
sse = yes
|
| 152 |
-
sse2 = yes
|
| 153 |
-
endif
|
| 154 |
-
|
| 155 |
-
ifeq ($(findstring -sse,$(ARCH)),-sse)
|
| 156 |
-
sse = yes
|
| 157 |
-
endif
|
| 158 |
-
|
| 159 |
-
ifeq ($(findstring -popcnt,$(ARCH)),-popcnt)
|
| 160 |
-
popcnt = yes
|
| 161 |
-
endif
|
| 162 |
-
|
| 163 |
-
ifeq ($(findstring -mmx,$(ARCH)),-mmx)
|
| 164 |
-
mmx = yes
|
| 165 |
-
endif
|
| 166 |
-
|
| 167 |
-
ifeq ($(findstring -sse2,$(ARCH)),-sse2)
|
| 168 |
-
sse = yes
|
| 169 |
-
sse2 = yes
|
| 170 |
-
endif
|
| 171 |
-
|
| 172 |
-
ifeq ($(findstring -ssse3,$(ARCH)),-ssse3)
|
| 173 |
-
sse = yes
|
| 174 |
-
sse2 = yes
|
| 175 |
-
ssse3 = yes
|
| 176 |
-
endif
|
| 177 |
-
|
| 178 |
-
ifeq ($(findstring -sse41,$(ARCH)),-sse41)
|
| 179 |
-
sse = yes
|
| 180 |
-
sse2 = yes
|
| 181 |
-
ssse3 = yes
|
| 182 |
-
sse41 = yes
|
| 183 |
-
endif
|
| 184 |
-
|
| 185 |
-
ifeq ($(findstring -modern,$(ARCH)),-modern)
|
| 186 |
-
popcnt = yes
|
| 187 |
-
sse = yes
|
| 188 |
-
sse2 = yes
|
| 189 |
-
ssse3 = yes
|
| 190 |
-
sse41 = yes
|
| 191 |
-
endif
|
| 192 |
-
|
| 193 |
-
ifeq ($(findstring -avx2,$(ARCH)),-avx2)
|
| 194 |
-
popcnt = yes
|
| 195 |
-
sse = yes
|
| 196 |
-
sse2 = yes
|
| 197 |
-
ssse3 = yes
|
| 198 |
-
sse41 = yes
|
| 199 |
-
avx2 = yes
|
| 200 |
-
endif
|
| 201 |
-
|
| 202 |
-
ifeq ($(findstring -bmi2,$(ARCH)),-bmi2)
|
| 203 |
-
popcnt = yes
|
| 204 |
-
sse = yes
|
| 205 |
-
sse2 = yes
|
| 206 |
-
ssse3 = yes
|
| 207 |
-
sse41 = yes
|
| 208 |
-
avx2 = yes
|
| 209 |
-
pext = yes
|
| 210 |
-
endif
|
| 211 |
-
|
| 212 |
-
ifeq ($(findstring -avx512,$(ARCH)),-avx512)
|
| 213 |
-
popcnt = yes
|
| 214 |
-
sse = yes
|
| 215 |
-
sse2 = yes
|
| 216 |
-
ssse3 = yes
|
| 217 |
-
sse41 = yes
|
| 218 |
-
avx2 = yes
|
| 219 |
-
pext = yes
|
| 220 |
-
avx512 = yes
|
| 221 |
-
endif
|
| 222 |
-
|
| 223 |
-
ifeq ($(findstring -vnni256,$(ARCH)),-vnni256)
|
| 224 |
-
popcnt = yes
|
| 225 |
-
sse = yes
|
| 226 |
-
sse2 = yes
|
| 227 |
-
ssse3 = yes
|
| 228 |
-
sse41 = yes
|
| 229 |
-
avx2 = yes
|
| 230 |
-
pext = yes
|
| 231 |
-
vnni256 = yes
|
| 232 |
-
endif
|
| 233 |
-
|
| 234 |
-
ifeq ($(findstring -vnni512,$(ARCH)),-vnni512)
|
| 235 |
-
popcnt = yes
|
| 236 |
-
sse = yes
|
| 237 |
-
sse2 = yes
|
| 238 |
-
ssse3 = yes
|
| 239 |
-
sse41 = yes
|
| 240 |
-
avx2 = yes
|
| 241 |
-
pext = yes
|
| 242 |
-
avx512 = yes
|
| 243 |
-
vnni512 = yes
|
| 244 |
-
endif
|
| 245 |
-
|
| 246 |
-
ifeq ($(sse),yes)
|
| 247 |
-
prefetch = yes
|
| 248 |
-
endif
|
| 249 |
-
|
| 250 |
-
# 64-bit pext is not available on x86-32
|
| 251 |
-
ifeq ($(bits),32)
|
| 252 |
-
pext = no
|
| 253 |
-
endif
|
| 254 |
-
|
| 255 |
-
else
|
| 256 |
-
|
| 257 |
-
# all other architectures
|
| 258 |
-
|
| 259 |
-
ifeq ($(ARCH),general-32)
|
| 260 |
-
arch = any
|
| 261 |
-
bits = 32
|
| 262 |
-
endif
|
| 263 |
-
|
| 264 |
-
ifeq ($(ARCH),general-64)
|
| 265 |
-
arch = any
|
| 266 |
-
endif
|
| 267 |
-
|
| 268 |
-
ifeq ($(ARCH),armv7)
|
| 269 |
-
arch = armv7
|
| 270 |
-
prefetch = yes
|
| 271 |
-
bits = 32
|
| 272 |
-
endif
|
| 273 |
-
|
| 274 |
-
ifeq ($(ARCH),armv7-neon)
|
| 275 |
-
arch = armv7
|
| 276 |
-
prefetch = yes
|
| 277 |
-
popcnt = yes
|
| 278 |
-
neon = yes
|
| 279 |
-
bits = 32
|
| 280 |
-
endif
|
| 281 |
-
|
| 282 |
-
ifeq ($(ARCH),armv8)
|
| 283 |
-
arch = armv8
|
| 284 |
-
prefetch = yes
|
| 285 |
-
popcnt = yes
|
| 286 |
-
neon = yes
|
| 287 |
-
endif
|
| 288 |
-
|
| 289 |
-
ifeq ($(ARCH),apple-silicon)
|
| 290 |
-
arch = arm64
|
| 291 |
-
prefetch = yes
|
| 292 |
-
popcnt = yes
|
| 293 |
-
neon = yes
|
| 294 |
-
endif
|
| 295 |
-
|
| 296 |
-
ifeq ($(ARCH),ppc-32)
|
| 297 |
-
arch = ppc
|
| 298 |
-
bits = 32
|
| 299 |
-
endif
|
| 300 |
-
|
| 301 |
-
ifeq ($(ARCH),ppc-64)
|
| 302 |
-
arch = ppc64
|
| 303 |
-
popcnt = yes
|
| 304 |
-
prefetch = yes
|
| 305 |
-
endif
|
| 306 |
-
|
| 307 |
-
ifeq ($(findstring e2k,$(ARCH)),e2k)
|
| 308 |
-
arch = e2k
|
| 309 |
-
mmx = yes
|
| 310 |
-
bits = 64
|
| 311 |
-
sse = yes
|
| 312 |
-
sse2 = yes
|
| 313 |
-
ssse3 = yes
|
| 314 |
-
sse41 = yes
|
| 315 |
-
popcnt = yes
|
| 316 |
-
endif
|
| 317 |
-
|
| 318 |
-
endif
|
| 319 |
-
|
| 320 |
-
# Disable precomputed magics when 64-bit PEXT is available
|
| 321 |
-
ifeq ($(pext),yes)
|
| 322 |
-
precomputedmagics = no
|
| 323 |
-
endif
|
| 324 |
-
|
| 325 |
-
### ==========================================================================
|
| 326 |
-
### Section 3. Low-level Configuration
|
| 327 |
-
### ==========================================================================
|
| 328 |
-
|
| 329 |
-
### 3.1 Selecting compiler (default = gcc)
|
| 330 |
-
CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -std=c++17 $(EXTRACXXFLAGS)
|
| 331 |
-
DEPENDFLAGS += -std=c++17
|
| 332 |
-
LDFLAGS += $(EXTRALDFLAGS)
|
| 333 |
-
|
| 334 |
-
# Ignore warning due to missing profile information from unused NNUE features
|
| 335 |
-
CXXFLAGS += -Wno-profile-instr-out-of-date
|
| 336 |
-
|
| 337 |
-
# Compile version with support for large board variants
|
| 338 |
-
# Use precomputed magics by default if pext is not available
|
| 339 |
-
ifneq ($(largeboards),no)
|
| 340 |
-
CXXFLAGS += -DLARGEBOARDS
|
| 341 |
-
ifeq ($(precomputedmagics),yes)
|
| 342 |
-
CXXFLAGS += -DPRECOMPUTED_MAGICS
|
| 343 |
-
endif
|
| 344 |
-
endif
|
| 345 |
-
|
| 346 |
-
# Embed and enable NNUE
|
| 347 |
-
ifeq ($(nnue),no)
|
| 348 |
-
CXXFLAGS += -DNNUE_EMBEDDING_OFF
|
| 349 |
-
endif
|
| 350 |
-
|
| 351 |
-
# Enable all variants, even heavyweight ones like duck and amazons
|
| 352 |
-
ifneq ($(all),no)
|
| 353 |
-
CXXFLAGS += -DALLVARS
|
| 354 |
-
endif
|
| 355 |
-
|
| 356 |
-
ifeq ($(COMP),)
|
| 357 |
-
COMP=gcc
|
| 358 |
-
endif
|
| 359 |
-
|
| 360 |
-
ifeq ($(COMP),gcc)
|
| 361 |
-
comp=gcc
|
| 362 |
-
CXX=g++
|
| 363 |
-
CXXFLAGS += -Wextra -Wshadow
|
| 364 |
-
ifeq ($(largeboards),no)
|
| 365 |
-
CXXFLAGS += -pedantic
|
| 366 |
-
endif
|
| 367 |
-
|
| 368 |
-
ifeq ($(arch),$(filter $(arch),armv7 armv8))
|
| 369 |
-
ifeq ($(OS),Android)
|
| 370 |
-
CXXFLAGS += -m$(bits)
|
| 371 |
-
LDFLAGS += -m$(bits)
|
| 372 |
-
endif
|
| 373 |
-
else
|
| 374 |
-
CXXFLAGS += -m$(bits)
|
| 375 |
-
LDFLAGS += -m$(bits)
|
| 376 |
-
endif
|
| 377 |
-
|
| 378 |
-
ifeq ($(arch),$(filter $(arch),armv7))
|
| 379 |
-
LDFLAGS += -latomic
|
| 380 |
-
endif
|
| 381 |
-
|
| 382 |
-
ifneq ($(KERNEL),Darwin)
|
| 383 |
-
LDFLAGS += -Wl,--no-as-needed
|
| 384 |
-
endif
|
| 385 |
-
endif
|
| 386 |
-
|
| 387 |
-
ifeq ($(COMP),mingw)
|
| 388 |
-
comp=mingw
|
| 389 |
-
|
| 390 |
-
ifeq ($(KERNEL),Linux)
|
| 391 |
-
ifeq ($(bits),64)
|
| 392 |
-
ifeq ($(shell which x86_64-w64-mingw32-c++-posix),)
|
| 393 |
-
CXX=x86_64-w64-mingw32-c++
|
| 394 |
-
else
|
| 395 |
-
CXX=x86_64-w64-mingw32-c++-posix
|
| 396 |
-
endif
|
| 397 |
-
else
|
| 398 |
-
ifeq ($(shell which i686-w64-mingw32-c++-posix),)
|
| 399 |
-
CXX=i686-w64-mingw32-c++
|
| 400 |
-
else
|
| 401 |
-
CXX=i686-w64-mingw32-c++-posix
|
| 402 |
-
endif
|
| 403 |
-
endif
|
| 404 |
-
else
|
| 405 |
-
CXX=g++
|
| 406 |
-
endif
|
| 407 |
-
|
| 408 |
-
CXXFLAGS += -Wextra -Wshadow
|
| 409 |
-
LDFLAGS += -static
|
| 410 |
-
endif
|
| 411 |
-
|
| 412 |
-
ifeq ($(COMP),icc)
|
| 413 |
-
comp=icc
|
| 414 |
-
CXX=icpc
|
| 415 |
-
CXXFLAGS += -diag-disable 1476,10120 -Wcheck -Wabi -Wdeprecated -strict-ansi
|
| 416 |
-
endif
|
| 417 |
-
|
| 418 |
-
ifeq ($(COMP),clang)
|
| 419 |
-
comp=clang
|
| 420 |
-
CXX=clang++
|
| 421 |
-
CXXFLAGS += -pedantic -Wextra -Wshadow
|
| 422 |
-
|
| 423 |
-
ifneq ($(KERNEL),Darwin)
|
| 424 |
-
ifneq ($(KERNEL),OpenBSD)
|
| 425 |
-
ifneq ($(KERNEL),FreeBSD)
|
| 426 |
-
LDFLAGS += -latomic
|
| 427 |
-
endif
|
| 428 |
-
endif
|
| 429 |
-
endif
|
| 430 |
-
|
| 431 |
-
ifeq ($(arch),$(filter $(arch),armv7 armv8))
|
| 432 |
-
ifeq ($(OS),Android)
|
| 433 |
-
CXXFLAGS += -m$(bits)
|
| 434 |
-
LDFLAGS += -m$(bits)
|
| 435 |
-
endif
|
| 436 |
-
else
|
| 437 |
-
CXXFLAGS += -m$(bits)
|
| 438 |
-
LDFLAGS += -m$(bits)
|
| 439 |
-
endif
|
| 440 |
-
endif
|
| 441 |
-
|
| 442 |
-
ifeq ($(KERNEL),Darwin)
|
| 443 |
-
CXXFLAGS += -arch $(arch) -mmacosx-version-min=10.14
|
| 444 |
-
LDFLAGS += -arch $(arch) -mmacosx-version-min=10.14
|
| 445 |
-
XCRUN = xcrun
|
| 446 |
-
endif
|
| 447 |
-
|
| 448 |
-
# To cross-compile for Android, NDK version r21 or later is recommended.
|
| 449 |
-
# In earlier NDK versions, you'll need to pass -fno-addrsig if using GNU binutils.
|
| 450 |
-
# Currently we don't know how to make PGO builds with the NDK yet.
|
| 451 |
-
ifeq ($(COMP),ndk)
|
| 452 |
-
CXXFLAGS += -stdlib=libc++ -fPIE
|
| 453 |
-
comp=clang
|
| 454 |
-
ifeq ($(arch),armv7)
|
| 455 |
-
CXX=armv7a-linux-androideabi16-clang++
|
| 456 |
-
CXXFLAGS += -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon
|
| 457 |
-
STRIP=arm-linux-androideabi-strip
|
| 458 |
-
endif
|
| 459 |
-
ifeq ($(arch),armv8)
|
| 460 |
-
CXX=aarch64-linux-android21-clang++
|
| 461 |
-
STRIP=aarch64-linux-android-strip
|
| 462 |
-
endif
|
| 463 |
-
LDFLAGS += -static-libstdc++ -pie -lm -latomic
|
| 464 |
-
endif
|
| 465 |
-
|
| 466 |
-
ifeq ($(comp),icc)
|
| 467 |
-
profile_make = icc-profile-make
|
| 468 |
-
profile_use = icc-profile-use
|
| 469 |
-
else ifeq ($(comp),clang)
|
| 470 |
-
profile_make = clang-profile-make
|
| 471 |
-
profile_use = clang-profile-use
|
| 472 |
-
else
|
| 473 |
-
profile_make = gcc-profile-make
|
| 474 |
-
profile_use = gcc-profile-use
|
| 475 |
-
endif
|
| 476 |
-
|
| 477 |
-
### Travis CI script uses COMPILER to overwrite CXX
|
| 478 |
-
ifdef COMPILER
|
| 479 |
-
COMPCXX=$(COMPILER)
|
| 480 |
-
endif
|
| 481 |
-
|
| 482 |
-
### Allow overwriting CXX from command line
|
| 483 |
-
ifdef COMPCXX
|
| 484 |
-
CXX=$(COMPCXX)
|
| 485 |
-
endif
|
| 486 |
-
|
| 487 |
-
### Sometimes gcc is really clang
|
| 488 |
-
ifeq ($(COMP),gcc)
|
| 489 |
-
gccversion = $(shell $(CXX) --version)
|
| 490 |
-
gccisclang = $(findstring clang,$(gccversion))
|
| 491 |
-
ifneq ($(gccisclang),)
|
| 492 |
-
profile_make = clang-profile-make
|
| 493 |
-
profile_use = clang-profile-use
|
| 494 |
-
endif
|
| 495 |
-
endif
|
| 496 |
-
|
| 497 |
-
### On mingw use Windows threads, otherwise POSIX
|
| 498 |
-
ifneq ($(comp),mingw)
|
| 499 |
-
CXXFLAGS += -DUSE_PTHREADS
|
| 500 |
-
# On Android Bionic's C library comes with its own pthread implementation bundled in
|
| 501 |
-
ifneq ($(OS),Android)
|
| 502 |
-
# Haiku has pthreads in its libroot, so only link it in on other platforms
|
| 503 |
-
ifneq ($(KERNEL),Haiku)
|
| 504 |
-
ifneq ($(COMP),ndk)
|
| 505 |
-
LDFLAGS += -lpthread
|
| 506 |
-
endif
|
| 507 |
-
endif
|
| 508 |
-
endif
|
| 509 |
-
endif
|
| 510 |
-
|
| 511 |
-
### 3.2.1 Debugging
|
| 512 |
-
ifeq ($(debug),no)
|
| 513 |
-
CXXFLAGS += -DNDEBUG
|
| 514 |
-
else
|
| 515 |
-
CXXFLAGS += -g
|
| 516 |
-
endif
|
| 517 |
-
|
| 518 |
-
### 3.2.2 Debugging with undefined behavior sanitizers
|
| 519 |
-
ifneq ($(sanitize),none)
|
| 520 |
-
CXXFLAGS += -g3 $(addprefix -fsanitize=,$(sanitize))
|
| 521 |
-
LDFLAGS += $(addprefix -fsanitize=,$(sanitize))
|
| 522 |
-
endif
|
| 523 |
-
|
| 524 |
-
### 3.3 Optimization
|
| 525 |
-
ifeq ($(optimize),yes)
|
| 526 |
-
|
| 527 |
-
CXXFLAGS += -O3 -fno-strict-aliasing
|
| 528 |
-
|
| 529 |
-
ifeq ($(comp),gcc)
|
| 530 |
-
ifeq ($(OS), Android)
|
| 531 |
-
CXXFLAGS += -fno-gcse -mthumb -march=armv7-a -mfloat-abi=softfp
|
| 532 |
-
endif
|
| 533 |
-
endif
|
| 534 |
-
|
| 535 |
-
ifeq ($(comp),$(filter $(comp),gcc clang icc))
|
| 536 |
-
ifeq ($(KERNEL),Darwin)
|
| 537 |
-
CXXFLAGS += -mdynamic-no-pic
|
| 538 |
-
endif
|
| 539 |
-
endif
|
| 540 |
-
|
| 541 |
-
ifeq ($(comp),clang)
|
| 542 |
-
clangmajorversion = $(shell $(CXX) -dumpversion 2>/dev/null | cut -f1 -d.)
|
| 543 |
-
ifeq ($(shell expr $(clangmajorversion) \< 16),1)
|
| 544 |
-
CXXFLAGS += -fexperimental-new-pass-manager
|
| 545 |
-
endif
|
| 546 |
-
endif
|
| 547 |
-
endif
|
| 548 |
-
|
| 549 |
-
### 3.4 Bits
|
| 550 |
-
ifeq ($(bits),64)
|
| 551 |
-
CXXFLAGS += -DIS_64BIT
|
| 552 |
-
endif
|
| 553 |
-
|
| 554 |
-
### 3.5 prefetch
|
| 555 |
-
ifeq ($(prefetch),yes)
|
| 556 |
-
ifeq ($(sse),yes)
|
| 557 |
-
CXXFLAGS += -msse
|
| 558 |
-
endif
|
| 559 |
-
else
|
| 560 |
-
CXXFLAGS += -DNO_PREFETCH
|
| 561 |
-
endif
|
| 562 |
-
|
| 563 |
-
### 3.6 popcnt
|
| 564 |
-
ifeq ($(popcnt),yes)
|
| 565 |
-
ifeq ($(arch),$(filter $(arch),ppc64 armv7 armv8 arm64))
|
| 566 |
-
CXXFLAGS += -DUSE_POPCNT
|
| 567 |
-
else ifeq ($(comp),icc)
|
| 568 |
-
CXXFLAGS += -msse3 -DUSE_POPCNT
|
| 569 |
-
else
|
| 570 |
-
CXXFLAGS += -msse3 -mpopcnt -DUSE_POPCNT
|
| 571 |
-
endif
|
| 572 |
-
endif
|
| 573 |
-
|
| 574 |
-
ifeq ($(avx2),yes)
|
| 575 |
-
CXXFLAGS += -DUSE_AVX2
|
| 576 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 577 |
-
CXXFLAGS += -mavx2 -mbmi
|
| 578 |
-
endif
|
| 579 |
-
endif
|
| 580 |
-
|
| 581 |
-
ifeq ($(avx512),yes)
|
| 582 |
-
CXXFLAGS += -DUSE_AVX512
|
| 583 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 584 |
-
CXXFLAGS += -mavx512f -mavx512bw
|
| 585 |
-
endif
|
| 586 |
-
endif
|
| 587 |
-
|
| 588 |
-
ifeq ($(vnni256),yes)
|
| 589 |
-
CXXFLAGS += -DUSE_VNNI
|
| 590 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 591 |
-
CXXFLAGS += -mavx512f -mavx512bw -mavx512vnni -mavx512dq -mavx512vl -mprefer-vector-width=256
|
| 592 |
-
endif
|
| 593 |
-
endif
|
| 594 |
-
|
| 595 |
-
ifeq ($(vnni512),yes)
|
| 596 |
-
CXXFLAGS += -DUSE_VNNI
|
| 597 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 598 |
-
CXXFLAGS += -mavx512vnni -mavx512dq -mavx512vl
|
| 599 |
-
endif
|
| 600 |
-
endif
|
| 601 |
-
|
| 602 |
-
ifeq ($(sse41),yes)
|
| 603 |
-
CXXFLAGS += -DUSE_SSE41
|
| 604 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 605 |
-
CXXFLAGS += -msse4.1
|
| 606 |
-
endif
|
| 607 |
-
endif
|
| 608 |
-
|
| 609 |
-
ifeq ($(ssse3),yes)
|
| 610 |
-
CXXFLAGS += -DUSE_SSSE3
|
| 611 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 612 |
-
CXXFLAGS += -mssse3
|
| 613 |
-
endif
|
| 614 |
-
endif
|
| 615 |
-
|
| 616 |
-
ifeq ($(sse2),yes)
|
| 617 |
-
CXXFLAGS += -DUSE_SSE2
|
| 618 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 619 |
-
CXXFLAGS += -msse2
|
| 620 |
-
endif
|
| 621 |
-
endif
|
| 622 |
-
|
| 623 |
-
ifeq ($(mmx),yes)
|
| 624 |
-
CXXFLAGS += -DUSE_MMX
|
| 625 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 626 |
-
CXXFLAGS += -mmmx
|
| 627 |
-
endif
|
| 628 |
-
endif
|
| 629 |
-
|
| 630 |
-
ifeq ($(neon),yes)
|
| 631 |
-
CXXFLAGS += -DUSE_NEON
|
| 632 |
-
ifeq ($(KERNEL),Linux)
|
| 633 |
-
ifneq ($(COMP),ndk)
|
| 634 |
-
ifneq ($(arch),armv8)
|
| 635 |
-
CXXFLAGS += -mfpu=neon
|
| 636 |
-
endif
|
| 637 |
-
endif
|
| 638 |
-
endif
|
| 639 |
-
endif
|
| 640 |
-
|
| 641 |
-
### 3.7 pext
|
| 642 |
-
ifeq ($(pext),yes)
|
| 643 |
-
CXXFLAGS += -DUSE_PEXT
|
| 644 |
-
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
| 645 |
-
CXXFLAGS += -mbmi2
|
| 646 |
-
endif
|
| 647 |
-
endif
|
| 648 |
-
|
| 649 |
-
### 3.8 Link Time Optimization
|
| 650 |
-
### This is a mix of compile and link time options because the lto link phase
|
| 651 |
-
### needs access to the optimization flags.
|
| 652 |
-
ifeq ($(optimize),yes)
|
| 653 |
-
ifeq ($(debug), no)
|
| 654 |
-
ifeq ($(comp),clang)
|
| 655 |
-
CXXFLAGS += -flto
|
| 656 |
-
ifneq ($(findstring MINGW,$(KERNEL)),)
|
| 657 |
-
CXXFLAGS += -fuse-ld=lld
|
| 658 |
-
else ifneq ($(findstring MSYS,$(KERNEL)),)
|
| 659 |
-
CXXFLAGS += -fuse-ld=lld
|
| 660 |
-
endif
|
| 661 |
-
LDFLAGS += $(CXXFLAGS)
|
| 662 |
-
|
| 663 |
-
# GCC and CLANG use different methods for parallelizing LTO and CLANG pretends to be
|
| 664 |
-
# GCC on some systems.
|
| 665 |
-
else ifeq ($(comp),gcc)
|
| 666 |
-
ifeq ($(gccisclang),)
|
| 667 |
-
CXXFLAGS += -flto
|
| 668 |
-
LDFLAGS += $(CXXFLAGS) -flto=jobserver
|
| 669 |
-
ifneq ($(findstring MINGW,$(KERNEL)),)
|
| 670 |
-
LDFLAGS += -save-temps
|
| 671 |
-
else ifneq ($(findstring MSYS,$(KERNEL)),)
|
| 672 |
-
LDFLAGS += -save-temps
|
| 673 |
-
endif
|
| 674 |
-
else
|
| 675 |
-
CXXFLAGS += -flto
|
| 676 |
-
LDFLAGS += $(CXXFLAGS)
|
| 677 |
-
endif
|
| 678 |
-
|
| 679 |
-
# To use LTO and static linking on windows, the tool chain requires a recent gcc:
|
| 680 |
-
# gcc version 10.1 in msys2 or TDM-GCC version 9.2 are known to work, older might not.
|
| 681 |
-
# So, only enable it for a cross from Linux by default.
|
| 682 |
-
else ifeq ($(comp),mingw)
|
| 683 |
-
ifeq ($(KERNEL),Linux)
|
| 684 |
-
ifneq ($(arch),i386)
|
| 685 |
-
CXXFLAGS += -flto
|
| 686 |
-
LDFLAGS += $(CXXFLAGS) -flto=jobserver
|
| 687 |
-
endif
|
| 688 |
-
endif
|
| 689 |
-
endif
|
| 690 |
-
endif
|
| 691 |
-
endif
|
| 692 |
-
|
| 693 |
-
### 3.9 Android 5 can only run position independent executables. Note that this
|
| 694 |
-
### breaks Android 4.0 and earlier.
|
| 695 |
-
ifeq ($(OS), Android)
|
| 696 |
-
CXXFLAGS += -fPIE
|
| 697 |
-
LDFLAGS += -fPIE -pie
|
| 698 |
-
endif
|
| 699 |
-
|
| 700 |
-
### ==========================================================================
|
| 701 |
-
### Section 4. Public Targets
|
| 702 |
-
### ==========================================================================
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
help:
|
| 706 |
-
@echo ""
|
| 707 |
-
@echo "To compile stockfish, type: "
|
| 708 |
-
@echo ""
|
| 709 |
-
@echo "make target ARCH=arch [COMP=compiler] [COMPCXX=cxx]"
|
| 710 |
-
@echo ""
|
| 711 |
-
@echo "Supported targets:"
|
| 712 |
-
@echo ""
|
| 713 |
-
@echo "help > Display architecture details"
|
| 714 |
-
@echo "build > Standard build"
|
| 715 |
-
@echo "net > Download the default nnue net"
|
| 716 |
-
@echo "profile-build > Faster build (with profile-guided optimization)"
|
| 717 |
-
@echo "strip > Strip executable"
|
| 718 |
-
@echo "install > Install executable"
|
| 719 |
-
@echo "clean > Clean up"
|
| 720 |
-
@echo ""
|
| 721 |
-
@echo "Supported archs:"
|
| 722 |
-
@echo ""
|
| 723 |
-
@echo "x86-64-vnni512 > x86 64-bit with vnni support 512bit wide"
|
| 724 |
-
@echo "x86-64-vnni256 > x86 64-bit with vnni support 256bit wide"
|
| 725 |
-
@echo "x86-64-avx512 > x86 64-bit with avx512 support"
|
| 726 |
-
@echo "x86-64-bmi2 > x86 64-bit with bmi2 support"
|
| 727 |
-
@echo "x86-64-avx2 > x86 64-bit with avx2 support"
|
| 728 |
-
@echo "x86-64-sse41-popcnt > x86 64-bit with sse41 and popcnt support"
|
| 729 |
-
@echo "x86-64-modern > common modern CPU, currently x86-64-sse41-popcnt"
|
| 730 |
-
@echo "x86-64-ssse3 > x86 64-bit with ssse3 support"
|
| 731 |
-
@echo "x86-64-sse3-popcnt > x86 64-bit with sse3 and popcnt support"
|
| 732 |
-
@echo "x86-64 > x86 64-bit generic (with sse2 support)"
|
| 733 |
-
@echo "x86-32-sse41-popcnt > x86 32-bit with sse41 and popcnt support"
|
| 734 |
-
@echo "x86-32-sse2 > x86 32-bit with sse2 support"
|
| 735 |
-
@echo "x86-32 > x86 32-bit generic (with mmx and sse support)"
|
| 736 |
-
@echo "ppc-64 > PPC 64-bit"
|
| 737 |
-
@echo "ppc-32 > PPC 32-bit"
|
| 738 |
-
@echo "armv7 > ARMv7 32-bit"
|
| 739 |
-
@echo "armv7-neon > ARMv7 32-bit with popcnt and neon"
|
| 740 |
-
@echo "armv8 > ARMv8 64-bit with popcnt and neon"
|
| 741 |
-
@echo "e2k > Elbrus 2000"
|
| 742 |
-
@echo "apple-silicon > Apple silicon ARM64"
|
| 743 |
-
@echo "general-64 > unspecified 64-bit"
|
| 744 |
-
@echo "general-32 > unspecified 32-bit"
|
| 745 |
-
@echo ""
|
| 746 |
-
@echo "Supported compilers:"
|
| 747 |
-
@echo ""
|
| 748 |
-
@echo "gcc > Gnu compiler (default)"
|
| 749 |
-
@echo "mingw > Gnu compiler with MinGW under Windows"
|
| 750 |
-
@echo "clang > LLVM Clang compiler"
|
| 751 |
-
@echo "icc > Intel compiler"
|
| 752 |
-
@echo "ndk > Google NDK to cross-compile for Android"
|
| 753 |
-
@echo ""
|
| 754 |
-
@echo "Simple examples. If you don't know what to do, you likely want to run: "
|
| 755 |
-
@echo ""
|
| 756 |
-
@echo "make -j build ARCH=x86-64 (A portable, slow compile for 64-bit systems)"
|
| 757 |
-
@echo "make -j build ARCH=x86-32 (A portable, slow compile for 32-bit systems)"
|
| 758 |
-
@echo ""
|
| 759 |
-
@echo "Advanced examples, for experienced users looking for performance: "
|
| 760 |
-
@echo ""
|
| 761 |
-
@echo "make help ARCH=x86-64-bmi2"
|
| 762 |
-
@echo "make -j profile-build ARCH=x86-64-bmi2 COMP=gcc COMPCXX=g++-9.0"
|
| 763 |
-
@echo "make -j build ARCH=x86-64-ssse3 COMP=clang"
|
| 764 |
-
@echo ""
|
| 765 |
-
@echo "-------------------------------"
|
| 766 |
-
ifeq ($(SUPPORTED_ARCH)$(help_skip_sanity), true)
|
| 767 |
-
@echo "The selected architecture $(ARCH) will enable the following configuration: "
|
| 768 |
-
@$(MAKE) ARCH=$(ARCH) COMP=$(COMP) config-sanity
|
| 769 |
-
else
|
| 770 |
-
@echo "Specify a supported architecture with the ARCH option for more details"
|
| 771 |
-
@echo ""
|
| 772 |
-
@echo "-------------------------------"
|
| 773 |
-
@echo "Embed and enable NNUE by default: "
|
| 774 |
-
@echo ""
|
| 775 |
-
@echo "make build ARCH=x86-64 nnue=yes"
|
| 776 |
-
@echo ""
|
| 777 |
-
@echo "-------------------------------"
|
| 778 |
-
@echo "Version for large boards: "
|
| 779 |
-
@echo ""
|
| 780 |
-
@echo "make build ARCH=x86-64 COMP=gcc largeboards=yes"
|
| 781 |
-
@echo ""
|
| 782 |
-
@echo "Include all variants (adds Game of the Amazons): "
|
| 783 |
-
@echo ""
|
| 784 |
-
@echo "make build ARCH=x86-64 largeboards=yes all=yes"
|
| 785 |
-
@echo ""
|
| 786 |
-
endif
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
.PHONY: help build profile-build strip install clean net objclean profileclean \
|
| 790 |
-
config-sanity icc-profile-use icc-profile-make gcc-profile-use gcc-profile-make \
|
| 791 |
-
clang-profile-use clang-profile-make
|
| 792 |
-
|
| 793 |
-
build: $(load_net) config-sanity
|
| 794 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) all
|
| 795 |
-
|
| 796 |
-
profile-build: $(load_net) config-sanity objclean profileclean
|
| 797 |
-
@echo ""
|
| 798 |
-
@echo "Step 1/4. Building instrumented executable ..."
|
| 799 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) $(profile_make)
|
| 800 |
-
@echo ""
|
| 801 |
-
@echo "Step 2/4. Running benchmark for pgo-build ..."
|
| 802 |
-
$(PGOBENCH) > /dev/null
|
| 803 |
-
@echo ""
|
| 804 |
-
@echo "Step 3/4. Building optimized executable ..."
|
| 805 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) objclean
|
| 806 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) $(profile_use)
|
| 807 |
-
@echo ""
|
| 808 |
-
@echo "Step 4/4. Deleting profile data ..."
|
| 809 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) profileclean
|
| 810 |
-
|
| 811 |
-
strip:
|
| 812 |
-
$(STRIP) $(EXE)
|
| 813 |
-
|
| 814 |
-
install:
|
| 815 |
-
-mkdir -p -m 755 $(BINDIR)
|
| 816 |
-
-cp $(EXE) $(BINDIR)
|
| 817 |
-
-strip $(BINDIR)/$(EXE)
|
| 818 |
-
|
| 819 |
-
# clean all
|
| 820 |
-
clean: objclean profileclean
|
| 821 |
-
@rm -f .depend *~ core
|
| 822 |
-
|
| 823 |
-
# evaluation network (nnue)
|
| 824 |
-
net:
|
| 825 |
-
$(eval nnuenet := $(shell grep EvalFileDefaultName evaluate.h | grep define | sed 's/.*\(nn-[a-z0-9]\{12\}.nnue\).*/\1/'))
|
| 826 |
-
@echo "Default net: $(nnuenet)"
|
| 827 |
-
$(eval nnuedownloadurl1 := https://tests.stockfishchess.org/api/nn/$(nnuenet))
|
| 828 |
-
$(eval nnuedownloadurl2 := https://github.com/official-stockfish/networks/raw/master/$(nnuenet))
|
| 829 |
-
$(eval curl_or_wget := $(shell if hash curl 2>/dev/null; then echo "curl -skL"; elif hash wget 2>/dev/null; then echo "wget -qO-"; fi))
|
| 830 |
-
@if [ "x$(curl_or_wget)" = "x" ]; then \
|
| 831 |
-
echo "Automatic download failed: neither curl nor wget is installed. Install one of these tools or download the net manually"; exit 1; \
|
| 832 |
-
fi
|
| 833 |
-
$(eval shasum_command := $(shell if hash shasum 2>/dev/null; then echo "shasum -a 256 "; elif hash sha256sum 2>/dev/null; then echo "sha256sum "; fi))
|
| 834 |
-
@if [ "x$(shasum_command)" = "x" ]; then \
|
| 835 |
-
echo "shasum / sha256sum not found, skipping net validation"; \
|
| 836 |
-
fi
|
| 837 |
-
@for nnuedownloadurl in "$(nnuedownloadurl1)" "$(nnuedownloadurl2)"; do \
|
| 838 |
-
if test -f "$(nnuenet)"; then \
|
| 839 |
-
echo "$(nnuenet) available."; \
|
| 840 |
-
else \
|
| 841 |
-
if [ "x$(curl_or_wget)" != "x" ]; then \
|
| 842 |
-
echo "Downloading $${nnuedownloadurl}"; $(curl_or_wget) $${nnuedownloadurl} > $(nnuenet);\
|
| 843 |
-
fi; \
|
| 844 |
-
fi; \
|
| 845 |
-
if [ "x$(shasum_command)" != "x" ]; then \
|
| 846 |
-
if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
|
| 847 |
-
echo "Removing failed download"; rm -f $(nnuenet); \
|
| 848 |
-
else \
|
| 849 |
-
echo "Network validated"; break; \
|
| 850 |
-
fi; \
|
| 851 |
-
fi; \
|
| 852 |
-
done
|
| 853 |
-
@if ! test -f "$(nnuenet)"; then \
|
| 854 |
-
echo "Failed to download $(nnuenet)."; \
|
| 855 |
-
fi
|
| 856 |
-
|
| 857 |
-
# clean binaries and objects
|
| 858 |
-
objclean:
|
| 859 |
-
@rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o
|
| 860 |
-
|
| 861 |
-
# clean auxiliary profiling files
|
| 862 |
-
profileclean:
|
| 863 |
-
@rm -rf profdir
|
| 864 |
-
@rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s
|
| 865 |
-
@rm -f stockfish.profdata *.profraw
|
| 866 |
-
@rm -f stockfish.exe.lto_wrapper_args
|
| 867 |
-
@rm -f stockfish.exe.ltrans.out
|
| 868 |
-
@rm -f ./-lstdc++.res
|
| 869 |
-
|
| 870 |
-
default:
|
| 871 |
-
help
|
| 872 |
-
|
| 873 |
-
### ==========================================================================
|
| 874 |
-
### Section 5. Private Targets
|
| 875 |
-
### ==========================================================================
|
| 876 |
-
|
| 877 |
-
all: $(EXE) .depend
|
| 878 |
-
|
| 879 |
-
config-sanity: $(load_net)
|
| 880 |
-
@echo ""
|
| 881 |
-
@echo "Config:"
|
| 882 |
-
@echo "debug: '$(debug)'"
|
| 883 |
-
@echo "sanitize: '$(sanitize)'"
|
| 884 |
-
@echo "optimize: '$(optimize)'"
|
| 885 |
-
@echo "arch: '$(arch)'"
|
| 886 |
-
@echo "bits: '$(bits)'"
|
| 887 |
-
@echo "kernel: '$(KERNEL)'"
|
| 888 |
-
@echo "os: '$(OS)'"
|
| 889 |
-
@echo "prefetch: '$(prefetch)'"
|
| 890 |
-
@echo "popcnt: '$(popcnt)'"
|
| 891 |
-
@echo "pext: '$(pext)'"
|
| 892 |
-
@echo "sse: '$(sse)'"
|
| 893 |
-
@echo "mmx: '$(mmx)'"
|
| 894 |
-
@echo "sse2: '$(sse2)'"
|
| 895 |
-
@echo "ssse3: '$(ssse3)'"
|
| 896 |
-
@echo "sse41: '$(sse41)'"
|
| 897 |
-
@echo "avx2: '$(avx2)'"
|
| 898 |
-
@echo "avx512: '$(avx512)'"
|
| 899 |
-
@echo "vnni256: '$(vnni256)'"
|
| 900 |
-
@echo "vnni512: '$(vnni512)'"
|
| 901 |
-
@echo "neon: '$(neon)'"
|
| 902 |
-
@echo ""
|
| 903 |
-
@echo "Fairy-Stockfish specific:"
|
| 904 |
-
@echo "largeboards: '$(largeboards)'"
|
| 905 |
-
@echo "all: '$(all)'"
|
| 906 |
-
@echo "precomputedmagics: '$(precomputedmagics)'"
|
| 907 |
-
@echo "nnue: '$(nnue)'"
|
| 908 |
-
@echo ""
|
| 909 |
-
@echo "Flags:"
|
| 910 |
-
@echo "CXX: $(CXX)"
|
| 911 |
-
@echo "CXXFLAGS: $(CXXFLAGS)"
|
| 912 |
-
@echo "LDFLAGS: $(LDFLAGS)"
|
| 913 |
-
@echo ""
|
| 914 |
-
@echo "Testing config sanity. If this fails, try 'make help' ..."
|
| 915 |
-
@echo ""
|
| 916 |
-
@test "$(debug)" = "yes" || test "$(debug)" = "no"
|
| 917 |
-
@test "$(optimize)" = "yes" || test "$(optimize)" = "no"
|
| 918 |
-
@test "$(SUPPORTED_ARCH)" = "true"
|
| 919 |
-
@test "$(arch)" = "any" || test "$(arch)" = "x86_64" || test "$(arch)" = "i386" || \
|
| 920 |
-
test "$(arch)" = "ppc64" || test "$(arch)" = "ppc" || test "$(arch)" = "e2k" || \
|
| 921 |
-
test "$(arch)" = "armv7" || test "$(arch)" = "armv8" || test "$(arch)" = "arm64"
|
| 922 |
-
@test "$(bits)" = "32" || test "$(bits)" = "64"
|
| 923 |
-
@test "$(prefetch)" = "yes" || test "$(prefetch)" = "no"
|
| 924 |
-
@test "$(popcnt)" = "yes" || test "$(popcnt)" = "no"
|
| 925 |
-
@test "$(pext)" = "yes" || test "$(pext)" = "no"
|
| 926 |
-
@test "$(sse)" = "yes" || test "$(sse)" = "no"
|
| 927 |
-
@test "$(mmx)" = "yes" || test "$(mmx)" = "no"
|
| 928 |
-
@test "$(sse2)" = "yes" || test "$(sse2)" = "no"
|
| 929 |
-
@test "$(ssse3)" = "yes" || test "$(ssse3)" = "no"
|
| 930 |
-
@test "$(sse41)" = "yes" || test "$(sse41)" = "no"
|
| 931 |
-
@test "$(avx2)" = "yes" || test "$(avx2)" = "no"
|
| 932 |
-
@test "$(avx512)" = "yes" || test "$(avx512)" = "no"
|
| 933 |
-
@test "$(vnni256)" = "yes" || test "$(vnni256)" = "no"
|
| 934 |
-
@test "$(vnni512)" = "yes" || test "$(vnni512)" = "no"
|
| 935 |
-
@test "$(neon)" = "yes" || test "$(neon)" = "no"
|
| 936 |
-
@test "$(comp)" = "gcc" || test "$(comp)" = "icc" || test "$(comp)" = "mingw" || test "$(comp)" = "clang" \
|
| 937 |
-
|| test "$(comp)" = "armv7a-linux-androideabi16-clang" || test "$(comp)" = "aarch64-linux-android21-clang"
|
| 938 |
-
|
| 939 |
-
$(EXE): $(OBJS)
|
| 940 |
-
+$(CXX) -o $@ $(OBJS) $(LDFLAGS)
|
| 941 |
-
|
| 942 |
-
clang-profile-make:
|
| 943 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 944 |
-
EXTRACXXFLAGS='-fprofile-instr-generate ' \
|
| 945 |
-
EXTRALDFLAGS=' -fprofile-instr-generate' \
|
| 946 |
-
all
|
| 947 |
-
|
| 948 |
-
clang-profile-use:
|
| 949 |
-
$(XCRUN) llvm-profdata merge -output=stockfish.profdata *.profraw
|
| 950 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 951 |
-
EXTRACXXFLAGS='-fprofile-instr-use=stockfish.profdata' \
|
| 952 |
-
EXTRALDFLAGS='-fprofile-use ' \
|
| 953 |
-
all
|
| 954 |
-
|
| 955 |
-
gcc-profile-make:
|
| 956 |
-
@mkdir -p profdir
|
| 957 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 958 |
-
EXTRACXXFLAGS='-fprofile-generate=profdir' \
|
| 959 |
-
EXTRALDFLAGS='-lgcov' \
|
| 960 |
-
all
|
| 961 |
-
|
| 962 |
-
gcc-profile-use:
|
| 963 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 964 |
-
EXTRACXXFLAGS='-fprofile-use=profdir -fno-peel-loops -fno-tracer' \
|
| 965 |
-
EXTRALDFLAGS='-lgcov' \
|
| 966 |
-
all
|
| 967 |
-
|
| 968 |
-
icc-profile-make:
|
| 969 |
-
@mkdir -p profdir
|
| 970 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 971 |
-
EXTRACXXFLAGS='-prof-gen=srcpos -prof_dir ./profdir' \
|
| 972 |
-
all
|
| 973 |
-
|
| 974 |
-
icc-profile-use:
|
| 975 |
-
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
| 976 |
-
EXTRACXXFLAGS='-prof_use -prof_dir ./profdir' \
|
| 977 |
-
all
|
| 978 |
-
|
| 979 |
-
.depend:
|
| 980 |
-
-@$(CXX) $(DEPENDFLAGS) -MM $(SRCS) > $@ 2> /dev/null
|
| 981 |
-
|
| 982 |
-
-include .depend
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/Makefile_js
DELETED
|
@@ -1,95 +0,0 @@
|
|
| 1 |
-
# ffish.js, a JavaScript chess variant library derived from Fairy-Stockfish
|
| 2 |
-
# Copyright (C) 2022 Fabian Fichter, Johannes Czech
|
| 3 |
-
#
|
| 4 |
-
# ffish.js is free software: you can redistribute it and/or modify
|
| 5 |
-
# it under the terms of the GNU General Public License as published by
|
| 6 |
-
# the Free Software Foundation, either version 3 of the License, or
|
| 7 |
-
# (at your option) any later version.
|
| 8 |
-
#
|
| 9 |
-
# ffish.js is distributed in the hope that it will be useful,
|
| 10 |
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
-
# GNU General Public License for more details.
|
| 13 |
-
#
|
| 14 |
-
# You should have received a copy of the GNU General Public License
|
| 15 |
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 16 |
-
|
| 17 |
-
EXE = ../tests/js/ffish.js
|
| 18 |
-
|
| 19 |
-
SRCS = ffishjs.cpp benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp \
|
| 20 |
-
material.cpp misc.cpp movegen.cpp movepick.cpp pawns.cpp position.cpp psqt.cpp \
|
| 21 |
-
search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \
|
| 22 |
-
nnue/evaluate_nnue.cpp nnue/features/half_ka_v2.cpp \
|
| 23 |
-
partner.cpp parser.cpp piece.cpp variant.cpp xboard.cpp \
|
| 24 |
-
nnue/features/half_ka_v2_variants.cpp
|
| 25 |
-
|
| 26 |
-
CXX=emcc
|
| 27 |
-
CXXFLAGS += --bind -DNNUE_EMBEDDING_OFF -DNO_THREADS -std=c++17 -Wall
|
| 28 |
-
|
| 29 |
-
largeboards = yes
|
| 30 |
-
all = yes
|
| 31 |
-
optimize = yes
|
| 32 |
-
debug = no
|
| 33 |
-
|
| 34 |
-
### Debugging
|
| 35 |
-
ifeq ($(debug),no)
|
| 36 |
-
CXXFLAGS += -DNDEBUG -s ASSERTIONS=0 -s SAFE_HEAP=0
|
| 37 |
-
else
|
| 38 |
-
CXXFLAGS += -g -s ASSERTIONS=1 -s SAFE_HEAP=1
|
| 39 |
-
endif
|
| 40 |
-
|
| 41 |
-
### Optimization
|
| 42 |
-
ifeq ($(optimize),yes)
|
| 43 |
-
CXXFLAGS += -O3
|
| 44 |
-
endif
|
| 45 |
-
|
| 46 |
-
# Compile version with support for large board variants
|
| 47 |
-
# Use precomputed magics by default
|
| 48 |
-
ifneq ($(largeboards),no)
|
| 49 |
-
CXXFLAGS += -DLARGEBOARDS -DPRECOMPUTED_MAGICS -s TOTAL_MEMORY=32MB -s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=1GB
|
| 50 |
-
endif
|
| 51 |
-
|
| 52 |
-
# Enable all variants, even heavyweight ones like duck and amazons
|
| 53 |
-
ifneq ($(all),no)
|
| 54 |
-
CXXFLAGS += -DALLVARS
|
| 55 |
-
endif
|
| 56 |
-
|
| 57 |
-
### Compile as ES6/ES2015 module
|
| 58 |
-
ifeq ($(es6),yes)
|
| 59 |
-
CXXFLAGS += -s ENVIRONMENT='web,worker' -s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=0
|
| 60 |
-
endif
|
| 61 |
-
|
| 62 |
-
.PHONY: help objclean clean build deps test serve
|
| 63 |
-
|
| 64 |
-
help:
|
| 65 |
-
@echo ""
|
| 66 |
-
@echo "To compile ffishjs, type: "
|
| 67 |
-
@echo ""
|
| 68 |
-
@echo "make -f Makefile_js build"
|
| 69 |
-
@echo ""
|
| 70 |
-
@echo "Supported targets:"
|
| 71 |
-
@echo ""
|
| 72 |
-
@echo "help > Display this help"
|
| 73 |
-
@echo "build > Standard build"
|
| 74 |
-
@echo "clean > Clean up"
|
| 75 |
-
@echo "deps > Install runtime dependencies using npm"
|
| 76 |
-
@echo "test > Run tests"
|
| 77 |
-
@echo "serve > Run example server"
|
| 78 |
-
@echo ""
|
| 79 |
-
|
| 80 |
-
objclean:
|
| 81 |
-
@rm -f $(EXE)
|
| 82 |
-
|
| 83 |
-
clean: objclean
|
| 84 |
-
|
| 85 |
-
build:
|
| 86 |
-
$(CXX) $(CXXFLAGS) $(SRCS) -o $(EXE)
|
| 87 |
-
|
| 88 |
-
deps:
|
| 89 |
-
cd ../tests/js && npm install
|
| 90 |
-
|
| 91 |
-
test: deps
|
| 92 |
-
cd ../tests/js && npm test
|
| 93 |
-
|
| 94 |
-
serve: deps
|
| 95 |
-
cd ../tests/js && node index.js
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/apiutil.h
DELETED
|
@@ -1,1165 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Fairy-Stockfish, a UCI chess variant playing engine derived from Stockfish
|
| 3 |
-
Copyright (C) 2018-2022 Fabian Fichter
|
| 4 |
-
|
| 5 |
-
Fairy-Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Fairy-Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef APIUTIL_H_INCLUDED
|
| 20 |
-
#define APIUTIL_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <array>
|
| 23 |
-
#include <vector>
|
| 24 |
-
#include <string>
|
| 25 |
-
#include <sstream>
|
| 26 |
-
#include <cctype>
|
| 27 |
-
#include <iostream>
|
| 28 |
-
#include <math.h>
|
| 29 |
-
|
| 30 |
-
#include "types.h"
|
| 31 |
-
#include "position.h"
|
| 32 |
-
#include "variant.h"
|
| 33 |
-
|
| 34 |
-
namespace Stockfish {
|
| 35 |
-
|
| 36 |
-
enum Notation {
|
| 37 |
-
NOTATION_DEFAULT,
|
| 38 |
-
// https://en.wikipedia.org/wiki/Algebraic_notation_(chess)
|
| 39 |
-
NOTATION_SAN,
|
| 40 |
-
NOTATION_LAN,
|
| 41 |
-
// https://en.wikipedia.org/wiki/Shogi_notation#Western_notation
|
| 42 |
-
NOTATION_SHOGI_HOSKING, // Examples: P76, S’34
|
| 43 |
-
NOTATION_SHOGI_HODGES, // Examples: P-7f, S*3d
|
| 44 |
-
NOTATION_SHOGI_HODGES_NUMBER, // Examples: P-76, S*34
|
| 45 |
-
// http://www.janggi.pl/janggi-notation/
|
| 46 |
-
NOTATION_JANGGI,
|
| 47 |
-
// https://en.wikipedia.org/wiki/Xiangqi#Notation
|
| 48 |
-
NOTATION_XIANGQI_WXF,
|
| 49 |
-
// https://web.archive.org/web/20180817205956/http://bgsthai.com/2018/05/07/lawofthaichessc/
|
| 50 |
-
NOTATION_THAI_SAN,
|
| 51 |
-
NOTATION_THAI_LAN,
|
| 52 |
-
};
|
| 53 |
-
|
| 54 |
-
inline Notation default_notation(const Variant* v) {
|
| 55 |
-
if (v->variantTemplate == "shogi")
|
| 56 |
-
return NOTATION_SHOGI_HODGES_NUMBER;
|
| 57 |
-
return NOTATION_SAN;
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
enum Termination {
|
| 61 |
-
ONGOING,
|
| 62 |
-
CHECKMATE,
|
| 63 |
-
STALEMATE,
|
| 64 |
-
INSUFFICIENT_MATERIAL,
|
| 65 |
-
N_MOVE_RULE,
|
| 66 |
-
N_FOLD_REPETITION,
|
| 67 |
-
VARIANT_END,
|
| 68 |
-
};
|
| 69 |
-
|
| 70 |
-
const std::array<std::string, 12> THAI_FILES = {"ก", "ข", "ค", "ง", "จ", "ฉ", "ช", "ญ", "ต", "ถ", "ธ", "น"};
|
| 71 |
-
const std::array<std::string, 12> THAI_RANKS = {"๑", "๒", "๓", "๔", "๕", "๖", "๗", "๘", "๙", "๑๐", "๑๑", "๑๒"};
|
| 72 |
-
|
| 73 |
-
namespace SAN {
|
| 74 |
-
|
| 75 |
-
enum Disambiguation {
|
| 76 |
-
NO_DISAMBIGUATION,
|
| 77 |
-
FILE_DISAMBIGUATION,
|
| 78 |
-
RANK_DISAMBIGUATION,
|
| 79 |
-
SQUARE_DISAMBIGUATION,
|
| 80 |
-
};
|
| 81 |
-
|
| 82 |
-
inline bool is_shogi(Notation n) {
|
| 83 |
-
return n == NOTATION_SHOGI_HOSKING || n == NOTATION_SHOGI_HODGES || n == NOTATION_SHOGI_HODGES_NUMBER;
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
inline bool is_thai(Notation n) {
|
| 87 |
-
return n == NOTATION_THAI_SAN || n == NOTATION_THAI_LAN;
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
-
// is there more than one file with a pair of pieces?
|
| 91 |
-
inline bool multi_tandem(Bitboard b) {
|
| 92 |
-
int tandems = 0;
|
| 93 |
-
for (File f = FILE_A; f <= FILE_MAX; ++f)
|
| 94 |
-
if (more_than_one(b & file_bb(f)))
|
| 95 |
-
tandems++;
|
| 96 |
-
return tandems >= 2;
|
| 97 |
-
}
|
| 98 |
-
|
| 99 |
-
inline std::string piece_to_thai_char(Piece pc, bool promoted) {
|
| 100 |
-
switch(type_of(pc)) {
|
| 101 |
-
case KING:
|
| 102 |
-
return "ข";
|
| 103 |
-
case KHON:
|
| 104 |
-
return "ค";
|
| 105 |
-
case FERS:
|
| 106 |
-
return promoted ? "ง" : "ม็";
|
| 107 |
-
case KNIGHT:
|
| 108 |
-
return "ม";
|
| 109 |
-
case ROOK:
|
| 110 |
-
return "ร";
|
| 111 |
-
case PAWN:
|
| 112 |
-
return "บ";
|
| 113 |
-
case AIWOK:
|
| 114 |
-
return "ว";
|
| 115 |
-
default:
|
| 116 |
-
return "X";
|
| 117 |
-
}
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
inline std::string piece(const Position& pos, Move m, Notation n) {
|
| 121 |
-
Color us = pos.side_to_move();
|
| 122 |
-
Square from = from_sq(m);
|
| 123 |
-
Piece pc = pos.moved_piece(m);
|
| 124 |
-
PieceType pt = type_of(pc);
|
| 125 |
-
// Quiet pawn moves
|
| 126 |
-
if ((n == NOTATION_SAN || n == NOTATION_LAN || n == NOTATION_THAI_SAN) && type_of(pc) == PAWN && type_of(m) != DROP)
|
| 127 |
-
return "";
|
| 128 |
-
// Tandem pawns
|
| 129 |
-
else if (n == NOTATION_XIANGQI_WXF && popcount(pos.pieces(us, pt) & file_bb(from)) >= 3 - multi_tandem(pos.pieces(us, pt)))
|
| 130 |
-
return std::to_string(popcount(forward_file_bb(us, from) & pos.pieces(us, pt)) + 1);
|
| 131 |
-
// Moves of promoted pieces
|
| 132 |
-
else if (is_shogi(n) && type_of(m) != DROP && pos.unpromoted_piece_on(from))
|
| 133 |
-
return "+" + std::string(1, toupper(pos.piece_to_char()[pos.unpromoted_piece_on(from)]));
|
| 134 |
-
// Promoted drops
|
| 135 |
-
else if (is_shogi(n) && type_of(m) == DROP && dropped_piece_type(m) != in_hand_piece_type(m))
|
| 136 |
-
return "+" + std::string(1, toupper(pos.piece_to_char()[in_hand_piece_type(m)]));
|
| 137 |
-
else if (is_thai(n))
|
| 138 |
-
return piece_to_thai_char(pc, pos.is_promoted(from));
|
| 139 |
-
else if (pos.piece_to_char_synonyms()[pc] != ' ')
|
| 140 |
-
return std::string(1, toupper(pos.piece_to_char_synonyms()[pc]));
|
| 141 |
-
else
|
| 142 |
-
return std::string(1, toupper(pos.piece_to_char()[pc]));
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
inline std::string file(const Position& pos, Square s, Notation n) {
|
| 146 |
-
switch (n)
|
| 147 |
-
{
|
| 148 |
-
case NOTATION_SHOGI_HOSKING:
|
| 149 |
-
case NOTATION_SHOGI_HODGES:
|
| 150 |
-
case NOTATION_SHOGI_HODGES_NUMBER:
|
| 151 |
-
return std::to_string(pos.max_file() - file_of(s) + 1);
|
| 152 |
-
case NOTATION_JANGGI:
|
| 153 |
-
return std::to_string(file_of(s) + 1);
|
| 154 |
-
case NOTATION_XIANGQI_WXF:
|
| 155 |
-
return std::to_string((pos.side_to_move() == WHITE ? pos.max_file() - file_of(s) : file_of(s)) + 1);
|
| 156 |
-
case NOTATION_THAI_SAN:
|
| 157 |
-
case NOTATION_THAI_LAN:
|
| 158 |
-
return THAI_FILES[file_of(s)];
|
| 159 |
-
default:
|
| 160 |
-
return std::string(1, char('a' + file_of(s)));
|
| 161 |
-
}
|
| 162 |
-
}
|
| 163 |
-
|
| 164 |
-
inline std::string rank(const Position& pos, Square s, Notation n) {
|
| 165 |
-
switch (n)
|
| 166 |
-
{
|
| 167 |
-
case NOTATION_SHOGI_HOSKING:
|
| 168 |
-
case NOTATION_SHOGI_HODGES_NUMBER:
|
| 169 |
-
return std::to_string(pos.max_rank() - rank_of(s) + 1);
|
| 170 |
-
case NOTATION_SHOGI_HODGES:
|
| 171 |
-
return std::string(1, char('a' + pos.max_rank() - rank_of(s)));
|
| 172 |
-
case NOTATION_JANGGI:
|
| 173 |
-
return std::to_string((pos.max_rank() - rank_of(s) + 1) % 10);
|
| 174 |
-
case NOTATION_XIANGQI_WXF:
|
| 175 |
-
{
|
| 176 |
-
if (pos.empty(s))
|
| 177 |
-
// Handle piece drops
|
| 178 |
-
return std::to_string(relative_rank(pos.side_to_move(), s, pos.max_rank()) + 1);
|
| 179 |
-
else if (pos.pieces(pos.side_to_move(), type_of(pos.piece_on(s))) & forward_file_bb(pos.side_to_move(), s))
|
| 180 |
-
return "-";
|
| 181 |
-
else
|
| 182 |
-
return "+";
|
| 183 |
-
}
|
| 184 |
-
case NOTATION_THAI_SAN:
|
| 185 |
-
case NOTATION_THAI_LAN:
|
| 186 |
-
return THAI_RANKS[rank_of(s)];
|
| 187 |
-
default:
|
| 188 |
-
return std::to_string(rank_of(s) + 1);
|
| 189 |
-
}
|
| 190 |
-
}
|
| 191 |
-
|
| 192 |
-
inline std::string square(const Position& pos, Square s, Notation n) {
|
| 193 |
-
switch (n)
|
| 194 |
-
{
|
| 195 |
-
case NOTATION_JANGGI:
|
| 196 |
-
return rank(pos, s, n) + file(pos, s, n);
|
| 197 |
-
default:
|
| 198 |
-
return file(pos, s, n) + rank(pos, s, n);
|
| 199 |
-
}
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
-
inline Disambiguation disambiguation_level(const Position& pos, Move m, Notation n) {
|
| 203 |
-
// Drops never need disambiguation
|
| 204 |
-
if (type_of(m) == DROP)
|
| 205 |
-
return NO_DISAMBIGUATION;
|
| 206 |
-
|
| 207 |
-
// NOTATION_LAN and Janggi always use disambiguation
|
| 208 |
-
if (n == NOTATION_LAN || n == NOTATION_THAI_LAN || n == NOTATION_JANGGI)
|
| 209 |
-
return SQUARE_DISAMBIGUATION;
|
| 210 |
-
|
| 211 |
-
Color us = pos.side_to_move();
|
| 212 |
-
Square from = from_sq(m);
|
| 213 |
-
Square to = to_sq(m);
|
| 214 |
-
Piece pc = pos.moved_piece(m);
|
| 215 |
-
PieceType pt = type_of(pc);
|
| 216 |
-
|
| 217 |
-
// Xiangqi uses either file disambiguation or +/- if two pieces on file
|
| 218 |
-
if (n == NOTATION_XIANGQI_WXF)
|
| 219 |
-
{
|
| 220 |
-
// Disambiguate by rank (+/-) if target square of other piece is valid
|
| 221 |
-
if (popcount(pos.pieces(us, pt) & file_bb(from)) == 2 && !multi_tandem(pos.pieces(us, pt)))
|
| 222 |
-
{
|
| 223 |
-
Square otherFrom = lsb((pos.pieces(us, pt) & file_bb(from)) ^ from);
|
| 224 |
-
Square otherTo = otherFrom + Direction(to) - Direction(from);
|
| 225 |
-
if (is_ok(otherTo) && (pos.board_bb(us, pt) & otherTo))
|
| 226 |
-
return RANK_DISAMBIGUATION;
|
| 227 |
-
}
|
| 228 |
-
return FILE_DISAMBIGUATION;
|
| 229 |
-
}
|
| 230 |
-
|
| 231 |
-
// Pawn captures always use disambiguation
|
| 232 |
-
if ((n == NOTATION_SAN || n == NOTATION_THAI_SAN) && pt == PAWN)
|
| 233 |
-
{
|
| 234 |
-
if (pos.capture(m))
|
| 235 |
-
return FILE_DISAMBIGUATION;
|
| 236 |
-
if (type_of(m) == PROMOTION && from != to && pos.sittuyin_promotion())
|
| 237 |
-
return SQUARE_DISAMBIGUATION;
|
| 238 |
-
}
|
| 239 |
-
|
| 240 |
-
// A disambiguation occurs if we have more than one piece of type 'pt'
|
| 241 |
-
// that can reach 'to' with a legal move.
|
| 242 |
-
Bitboard b = pos.pieces(us, pt) ^ from;
|
| 243 |
-
Bitboard others = 0;
|
| 244 |
-
|
| 245 |
-
while (b)
|
| 246 |
-
{
|
| 247 |
-
Square s = pop_lsb(b);
|
| 248 |
-
// Construct a potential move with identical special move flags
|
| 249 |
-
// and only a different "from" square.
|
| 250 |
-
Move testMove = Move(m ^ make_move(from, to) ^ make_move(s, to));
|
| 251 |
-
if ( pos.pseudo_legal(testMove)
|
| 252 |
-
&& pos.legal(testMove)
|
| 253 |
-
&& !(is_shogi(n) && pos.unpromoted_piece_on(s) != pos.unpromoted_piece_on(from)))
|
| 254 |
-
others |= s;
|
| 255 |
-
}
|
| 256 |
-
|
| 257 |
-
if (!others)
|
| 258 |
-
return NO_DISAMBIGUATION;
|
| 259 |
-
else if (is_shogi(n))
|
| 260 |
-
return SQUARE_DISAMBIGUATION;
|
| 261 |
-
else if (!(others & file_bb(from)))
|
| 262 |
-
return FILE_DISAMBIGUATION;
|
| 263 |
-
else if (!(others & rank_bb(from)))
|
| 264 |
-
return RANK_DISAMBIGUATION;
|
| 265 |
-
else
|
| 266 |
-
return SQUARE_DISAMBIGUATION;
|
| 267 |
-
}
|
| 268 |
-
|
| 269 |
-
inline std::string disambiguation(const Position& pos, Square s, Notation n, Disambiguation d) {
|
| 270 |
-
switch (d)
|
| 271 |
-
{
|
| 272 |
-
case FILE_DISAMBIGUATION:
|
| 273 |
-
return file(pos, s, n);
|
| 274 |
-
case RANK_DISAMBIGUATION:
|
| 275 |
-
return rank(pos, s, n);
|
| 276 |
-
case SQUARE_DISAMBIGUATION:
|
| 277 |
-
return square(pos, s, n);
|
| 278 |
-
default:
|
| 279 |
-
assert(d == NO_DISAMBIGUATION);
|
| 280 |
-
return "";
|
| 281 |
-
}
|
| 282 |
-
}
|
| 283 |
-
|
| 284 |
-
inline const std::string move_to_san(Position& pos, Move m, Notation n) {
|
| 285 |
-
std::string san = "";
|
| 286 |
-
Color us = pos.side_to_move();
|
| 287 |
-
Square from = from_sq(m);
|
| 288 |
-
Square to = to_sq(m);
|
| 289 |
-
|
| 290 |
-
if (type_of(m) == CASTLING)
|
| 291 |
-
{
|
| 292 |
-
san = to > from ? "O-O" : "O-O-O";
|
| 293 |
-
|
| 294 |
-
if (is_gating(m))
|
| 295 |
-
{
|
| 296 |
-
san += std::string("/") + (char)toupper(pos.piece_to_char()[make_piece(us, gating_type(m))]);
|
| 297 |
-
san += square(pos, gating_square(m), n);
|
| 298 |
-
}
|
| 299 |
-
}
|
| 300 |
-
else
|
| 301 |
-
{
|
| 302 |
-
// Piece
|
| 303 |
-
san += piece(pos, m, n);
|
| 304 |
-
|
| 305 |
-
if (n == NOTATION_THAI_LAN)
|
| 306 |
-
san += " ";
|
| 307 |
-
|
| 308 |
-
// Origin square, disambiguation
|
| 309 |
-
Disambiguation d = disambiguation_level(pos, m, n);
|
| 310 |
-
san += disambiguation(pos, from, n, d);
|
| 311 |
-
|
| 312 |
-
// Separator/Operator
|
| 313 |
-
if (type_of(m) == DROP)
|
| 314 |
-
san += n == NOTATION_SHOGI_HOSKING ? '\'' : is_shogi(n) ? '*' : '@';
|
| 315 |
-
else if (n == NOTATION_XIANGQI_WXF)
|
| 316 |
-
{
|
| 317 |
-
if (rank_of(from) == rank_of(to))
|
| 318 |
-
san += '=';
|
| 319 |
-
else if (relative_rank(us, to, pos.max_rank()) > relative_rank(us, from, pos.max_rank()))
|
| 320 |
-
san += '+';
|
| 321 |
-
else
|
| 322 |
-
san += '-';
|
| 323 |
-
}
|
| 324 |
-
else if (pos.capture(m))
|
| 325 |
-
san += 'x';
|
| 326 |
-
else if (n == NOTATION_LAN || n == NOTATION_THAI_LAN || (is_shogi(n) && (n != NOTATION_SHOGI_HOSKING || d == SQUARE_DISAMBIGUATION)) || n == NOTATION_JANGGI || (n == NOTATION_THAI_SAN && type_of(pos.moved_piece(m)) != PAWN))
|
| 327 |
-
san += '-';
|
| 328 |
-
|
| 329 |
-
// Destination square
|
| 330 |
-
if (n == NOTATION_XIANGQI_WXF && type_of(m) != DROP)
|
| 331 |
-
san += file_of(to) == file_of(from) ? std::to_string(std::abs(rank_of(to) - rank_of(from))) : file(pos, to, n);
|
| 332 |
-
else
|
| 333 |
-
san += square(pos, to, n);
|
| 334 |
-
|
| 335 |
-
// Suffix
|
| 336 |
-
if (type_of(m) == PROMOTION)
|
| 337 |
-
san += std::string("=") + (char)toupper(pos.piece_to_char()[make_piece(us, promotion_type(m))]);
|
| 338 |
-
else if (type_of(m) == PIECE_PROMOTION)
|
| 339 |
-
san += is_shogi(n) ? std::string("+") : std::string("=") + (char)toupper(pos.piece_to_char()[make_piece(us, pos.promoted_piece_type(type_of(pos.moved_piece(m))))]);
|
| 340 |
-
else if (type_of(m) == PIECE_DEMOTION)
|
| 341 |
-
san += is_shogi(n) ? std::string("-") : std::string("=") + std::string(1, toupper(pos.piece_to_char()[pos.unpromoted_piece_on(from)]));
|
| 342 |
-
else if (type_of(m) == NORMAL && is_shogi(n) && pos.pseudo_legal(make<PIECE_PROMOTION>(from, to)))
|
| 343 |
-
san += std::string("=");
|
| 344 |
-
if (is_gating(m))
|
| 345 |
-
san += std::string("/") + (char)toupper(pos.piece_to_char()[make_piece(us, gating_type(m))]);
|
| 346 |
-
}
|
| 347 |
-
|
| 348 |
-
// Wall square
|
| 349 |
-
if (pos.walling())
|
| 350 |
-
san += "," + square(pos, gating_square(m), n);
|
| 351 |
-
|
| 352 |
-
// Check and checkmate
|
| 353 |
-
if (pos.gives_check(m) && !is_shogi(n) && n != NOTATION_XIANGQI_WXF)
|
| 354 |
-
{
|
| 355 |
-
StateInfo st;
|
| 356 |
-
pos.do_move(m, st);
|
| 357 |
-
san += MoveList<LEGAL>(pos).size() ? "+" : "#";
|
| 358 |
-
pos.undo_move(m);
|
| 359 |
-
}
|
| 360 |
-
|
| 361 |
-
return san;
|
| 362 |
-
}
|
| 363 |
-
|
| 364 |
-
} // namespace SAN
|
| 365 |
-
|
| 366 |
-
inline bool has_insufficient_material(Color c, const Position& pos) {
|
| 367 |
-
|
| 368 |
-
// Other win rules
|
| 369 |
-
if ( pos.captures_to_hand()
|
| 370 |
-
|| pos.count_in_hand(c, ALL_PIECES)
|
| 371 |
-
|| (pos.extinction_value() != VALUE_NONE && !pos.extinction_pseudo_royal())
|
| 372 |
-
|| (pos.variant()->nFoldRule && pos.variant()->nFoldValue != VALUE_DRAW)
|
| 373 |
-
|| (pos.flag_region(c) && pos.count(c, pos.flag_piece(c))))
|
| 374 |
-
return false;
|
| 375 |
-
|
| 376 |
-
// Precalculate if any promotion pawn types have pieces
|
| 377 |
-
bool hasPromotingPawn = false;
|
| 378 |
-
for (PieceSet pawnTypes = pos.promotion_pawn_types(c); pawnTypes; )
|
| 379 |
-
{
|
| 380 |
-
PieceType pawnType = pop_lsb(pawnTypes);
|
| 381 |
-
if (pos.count(c, pawnType) > 0)
|
| 382 |
-
{
|
| 383 |
-
hasPromotingPawn = true;
|
| 384 |
-
break;
|
| 385 |
-
}
|
| 386 |
-
}
|
| 387 |
-
|
| 388 |
-
// Determine checkmating potential of present pieces
|
| 389 |
-
constexpr PieceSet MAJOR_PIECES = piece_set(ROOK) | QUEEN | ARCHBISHOP | CHANCELLOR
|
| 390 |
-
| SILVER | GOLD | COMMONER | CENTAUR | AMAZON | BERS;
|
| 391 |
-
constexpr PieceSet COLORBOUND_PIECES = piece_set(BISHOP) | FERS | FERS_ALFIL | ALFIL | ELEPHANT;
|
| 392 |
-
Bitboard restricted = pos.pieces(KING);
|
| 393 |
-
Bitboard colorbound = 0;
|
| 394 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 395 |
-
{
|
| 396 |
-
PieceType pt = pop_lsb(ps);
|
| 397 |
-
|
| 398 |
-
// Constrained pieces
|
| 399 |
-
if (pt == KING || !(pos.board_bb(c, pt) & pos.board_bb(~c, KING)) || (pos.extinction_pseudo_royal() && pos.blast_on_capture() && (pos.extinction_piece_types() & pt)))
|
| 400 |
-
restricted |= pos.pieces(c, pt);
|
| 401 |
-
|
| 402 |
-
// If piece is a major piece or a custom piece we consider it sufficient for mate.
|
| 403 |
-
// To avoid false positives, we assume any custom piece has mating potential.
|
| 404 |
-
else if ((MAJOR_PIECES & pt) || is_custom(pt))
|
| 405 |
-
{
|
| 406 |
-
// Check if piece is already on the board
|
| 407 |
-
if (pos.count(c, pt) > 0)
|
| 408 |
-
return false;
|
| 409 |
-
|
| 410 |
-
// Check if any pawn can promote to this piece type
|
| 411 |
-
if (hasPromotingPawn && (pos.promotion_piece_types(c) & pt))
|
| 412 |
-
return false;
|
| 413 |
-
}
|
| 414 |
-
|
| 415 |
-
// Collect color-bound pieces
|
| 416 |
-
else if (COLORBOUND_PIECES & pt)
|
| 417 |
-
colorbound |= pos.pieces(pt);
|
| 418 |
-
}
|
| 419 |
-
|
| 420 |
-
Bitboard unbound = pos.pieces() ^ restricted ^ colorbound;
|
| 421 |
-
|
| 422 |
-
// Color-bound pieces
|
| 423 |
-
if ((colorbound & pos.pieces(c)) && (((DarkSquares & colorbound) && (~DarkSquares & colorbound)) || unbound || pos.stalemate_value() != VALUE_DRAW || pos.check_counting() || pos.makpong()))
|
| 424 |
-
return false;
|
| 425 |
-
|
| 426 |
-
// Unbound pieces require one helper piece of either color
|
| 427 |
-
if ((pos.pieces(c) & unbound) && (popcount(pos.pieces() ^ restricted) >= 2 || pos.stalemate_value() != VALUE_DRAW || pos.check_counting() || pos.makpong()))
|
| 428 |
-
return false;
|
| 429 |
-
|
| 430 |
-
// Non-draw stalemate with lone custom king
|
| 431 |
-
if ( pos.stalemate_value() != VALUE_DRAW && pos.king_type() != KING
|
| 432 |
-
&& pos.pieces(c, KING) && (pos.board_bb(c, KING) & pos.board_bb(~c, KING)))
|
| 433 |
-
return false;
|
| 434 |
-
|
| 435 |
-
return true;
|
| 436 |
-
}
|
| 437 |
-
|
| 438 |
-
inline Bitboard checked(const Position& pos) {
|
| 439 |
-
return (pos.checkers() ? square_bb(pos.square<KING>(pos.side_to_move())) : Bitboard(0))
|
| 440 |
-
| (pos.extinction_pseudo_royal() ? pos.checked_pseudo_royals(pos.side_to_move()) : Bitboard(0));
|
| 441 |
-
}
|
| 442 |
-
|
| 443 |
-
namespace FEN {
|
| 444 |
-
|
| 445 |
-
enum FenValidation : int {
|
| 446 |
-
FEN_INVALID_COUNTING_RULE = -14,
|
| 447 |
-
FEN_INVALID_CHECK_COUNT = -13,
|
| 448 |
-
FEN_INVALID_PROMOTED_PIECE = -12,
|
| 449 |
-
FEN_INVALID_NB_PARTS = -11,
|
| 450 |
-
FEN_INVALID_CHAR = -10,
|
| 451 |
-
FEN_TOUCHING_KINGS = -9,
|
| 452 |
-
FEN_INVALID_BOARD_GEOMETRY = -8,
|
| 453 |
-
FEN_INVALID_POCKET_INFO = -7,
|
| 454 |
-
FEN_INVALID_SIDE_TO_MOVE = -6,
|
| 455 |
-
FEN_INVALID_CASTLING_INFO = -5,
|
| 456 |
-
FEN_INVALID_EN_PASSANT_SQ = -4,
|
| 457 |
-
FEN_INVALID_NUMBER_OF_KINGS = -3,
|
| 458 |
-
FEN_INVALID_HALF_MOVE_COUNTER = -2,
|
| 459 |
-
FEN_INVALID_MOVE_COUNTER = -1,
|
| 460 |
-
FEN_EMPTY = 0,
|
| 461 |
-
FEN_OK = 1
|
| 462 |
-
};
|
| 463 |
-
enum Validation : int {
|
| 464 |
-
NOK,
|
| 465 |
-
OK
|
| 466 |
-
};
|
| 467 |
-
|
| 468 |
-
struct CharSquare {
|
| 469 |
-
int rowIdx;
|
| 470 |
-
int fileIdx;
|
| 471 |
-
CharSquare() : rowIdx(-1), fileIdx(-1) {}
|
| 472 |
-
CharSquare(int row, int file) : rowIdx(row), fileIdx(file) {}
|
| 473 |
-
};
|
| 474 |
-
|
| 475 |
-
inline bool operator==(const CharSquare& s1, const CharSquare& s2) {
|
| 476 |
-
return s1.rowIdx == s2.rowIdx && s1.fileIdx == s2.fileIdx;
|
| 477 |
-
}
|
| 478 |
-
|
| 479 |
-
inline bool operator!=(const CharSquare& s1, const CharSquare& s2) {
|
| 480 |
-
return !(s1 == s2);
|
| 481 |
-
}
|
| 482 |
-
|
| 483 |
-
inline int non_root_euclidian_distance(const CharSquare& s1, const CharSquare& s2) {
|
| 484 |
-
return pow(s1.rowIdx - s2.rowIdx, 2) + pow(s1.fileIdx - s2.fileIdx, 2);
|
| 485 |
-
}
|
| 486 |
-
|
| 487 |
-
class CharBoard {
|
| 488 |
-
private:
|
| 489 |
-
int nbRanks;
|
| 490 |
-
int nbFiles;
|
| 491 |
-
std::vector<char> board; // fill an array where the pieces are for later geometry checks
|
| 492 |
-
public:
|
| 493 |
-
CharBoard(int ranks, int files) : nbRanks(ranks), nbFiles(files) {
|
| 494 |
-
assert(nbFiles > 0 && nbRanks > 0);
|
| 495 |
-
board = std::vector<char>(nbRanks * nbFiles, ' ');
|
| 496 |
-
}
|
| 497 |
-
void set_piece(int rankIdx, int fileIdx, char c) {
|
| 498 |
-
board[rankIdx * nbFiles + fileIdx] = c;
|
| 499 |
-
}
|
| 500 |
-
char get_piece(int rowIdx, int fileIdx) const {
|
| 501 |
-
return board[rowIdx * nbFiles + fileIdx];
|
| 502 |
-
}
|
| 503 |
-
int get_nb_ranks() const {
|
| 504 |
-
return nbRanks;
|
| 505 |
-
}
|
| 506 |
-
int get_nb_files() const {
|
| 507 |
-
return nbFiles;
|
| 508 |
-
}
|
| 509 |
-
/// Returns the square of a given character
|
| 510 |
-
CharSquare get_square_for_piece(char piece) const {
|
| 511 |
-
CharSquare s;
|
| 512 |
-
for (int r = 0; r < nbRanks; ++r)
|
| 513 |
-
{
|
| 514 |
-
for (int c = 0; c < nbFiles; ++c)
|
| 515 |
-
{
|
| 516 |
-
if (get_piece(r, c) == piece)
|
| 517 |
-
{
|
| 518 |
-
s.rowIdx = r;
|
| 519 |
-
s.fileIdx = c;
|
| 520 |
-
return s;
|
| 521 |
-
}
|
| 522 |
-
}
|
| 523 |
-
}
|
| 524 |
-
return s;
|
| 525 |
-
}
|
| 526 |
-
/// Returns all square positions for a given piece
|
| 527 |
-
std::vector<CharSquare> get_squares_for_pieces(Color color, PieceSet ps, const std::string& pieceChars) const {
|
| 528 |
-
std::vector<CharSquare> squares;
|
| 529 |
-
size_t pcIdx;
|
| 530 |
-
for (int r = 0; r < nbRanks; ++r)
|
| 531 |
-
for (int c = 0; c < nbFiles; ++c)
|
| 532 |
-
if ((pcIdx = pieceChars.find(get_piece(r, c))) != std::string::npos && (ps & type_of(Piece(pcIdx))) && color_of(Piece(pcIdx)) == color)
|
| 533 |
-
squares.emplace_back(CharSquare(r, c));
|
| 534 |
-
return squares;
|
| 535 |
-
}
|
| 536 |
-
friend std::ostream& operator<<(std::ostream& os, const CharBoard& board);
|
| 537 |
-
};
|
| 538 |
-
|
| 539 |
-
inline std::ostream& operator<<(std::ostream& os, const CharBoard& board) {
|
| 540 |
-
for (int r = 0; r < board.nbRanks; ++r)
|
| 541 |
-
{
|
| 542 |
-
for (int c = 0; c < board.nbFiles; ++c)
|
| 543 |
-
os << "[" << board.get_piece(r, c) << "] ";
|
| 544 |
-
os << std::endl;
|
| 545 |
-
}
|
| 546 |
-
return os;
|
| 547 |
-
}
|
| 548 |
-
|
| 549 |
-
inline bool contains(const std::string& str, char c) {
|
| 550 |
-
return str.find(c) != std::string::npos;
|
| 551 |
-
}
|
| 552 |
-
|
| 553 |
-
inline bool in_any(const std::vector<std::string>& vec, char c) {
|
| 554 |
-
for (std::string str : vec)
|
| 555 |
-
if (contains(str, c))
|
| 556 |
-
return true;
|
| 557 |
-
return false;
|
| 558 |
-
}
|
| 559 |
-
|
| 560 |
-
inline Validation check_for_valid_characters(const std::string& firstFenPart, const std::string& validSpecialCharactersFirstField, const Variant* v) {
|
| 561 |
-
for (char c : firstFenPart)
|
| 562 |
-
{
|
| 563 |
-
if (!isdigit(c) && !in_any({v->pieceToChar, v->pieceToCharSynonyms, validSpecialCharactersFirstField}, c))
|
| 564 |
-
{
|
| 565 |
-
std::cerr << "Invalid piece character: '" << c << "'." << std::endl;
|
| 566 |
-
return NOK;
|
| 567 |
-
}
|
| 568 |
-
}
|
| 569 |
-
return OK;
|
| 570 |
-
}
|
| 571 |
-
|
| 572 |
-
inline Validation check_promoted_pieces(const std::string& firstFenPart, const Variant* v) {
|
| 573 |
-
// Only check promoted pieces if the variant supports shogi-style promotions
|
| 574 |
-
if (!v || !v->shogiStylePromotions)
|
| 575 |
-
return OK;
|
| 576 |
-
|
| 577 |
-
for (size_t i = 0; i < firstFenPart.length() - 1; ++i) {
|
| 578 |
-
// Look for promoted pieces ('+' followed by piece character)
|
| 579 |
-
if (firstFenPart[i] == '+') {
|
| 580 |
-
char pieceChar = firstFenPart[i + 1];
|
| 581 |
-
|
| 582 |
-
// Skip if next character is not a piece character or is a special character
|
| 583 |
-
if (isdigit(pieceChar) || pieceChar == '/' || pieceChar == ' ' || pieceChar == '[')
|
| 584 |
-
continue;
|
| 585 |
-
|
| 586 |
-
// Find the piece type corresponding to this character
|
| 587 |
-
size_t idx = v->pieceToChar.find(pieceChar);
|
| 588 |
-
if (idx == std::string::npos) {
|
| 589 |
-
// Try synonyms
|
| 590 |
-
idx = v->pieceToCharSynonyms.find(pieceChar);
|
| 591 |
-
if (idx == std::string::npos)
|
| 592 |
-
continue; // Character validation will catch this
|
| 593 |
-
}
|
| 594 |
-
|
| 595 |
-
// Ensure idx is within valid range for piece types
|
| 596 |
-
if (idx >= PIECE_TYPE_NB)
|
| 597 |
-
continue;
|
| 598 |
-
|
| 599 |
-
// Get the piece type directly from the index
|
| 600 |
-
PieceType pt = PieceType(idx);
|
| 601 |
-
|
| 602 |
-
// Check if this piece type has a promoted form
|
| 603 |
-
if (pt != NO_PIECE_TYPE && pt < PIECE_TYPE_NB && v->promotedPieceType[pt] == NO_PIECE_TYPE) {
|
| 604 |
-
std::cerr << "Invalid promoted piece: '+' followed by '" << pieceChar
|
| 605 |
-
<< "'. This piece cannot be promoted in variant." << std::endl;
|
| 606 |
-
return NOK;
|
| 607 |
-
}
|
| 608 |
-
}
|
| 609 |
-
}
|
| 610 |
-
return OK;
|
| 611 |
-
}
|
| 612 |
-
|
| 613 |
-
inline std::vector<std::string> get_fen_parts(const std::string& fullFen, char delim) {
|
| 614 |
-
std::vector<std::string> fenParts;
|
| 615 |
-
std::string curPart;
|
| 616 |
-
std::stringstream ss(fullFen);
|
| 617 |
-
while (std::getline(ss, curPart, delim))
|
| 618 |
-
fenParts.emplace_back(curPart);
|
| 619 |
-
return fenParts;
|
| 620 |
-
}
|
| 621 |
-
|
| 622 |
-
/// fills the character board according to a given FEN string
|
| 623 |
-
inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, const std::string& validSpecialCharactersFirstField, const Variant* v) {
|
| 624 |
-
int rankIdx = 0;
|
| 625 |
-
int fileIdx = 0;
|
| 626 |
-
|
| 627 |
-
char prevChar = '?';
|
| 628 |
-
for (char c : fenBoard)
|
| 629 |
-
{
|
| 630 |
-
if (c == ' ' || c == '[')
|
| 631 |
-
break;
|
| 632 |
-
if (c == '*')
|
| 633 |
-
++fileIdx;
|
| 634 |
-
else if (isdigit(c))
|
| 635 |
-
{
|
| 636 |
-
fileIdx += c - '0';
|
| 637 |
-
// if we have multiple digits attached we can add multiples of 9 to compute the resulting number (e.g. -> 21 = 2 + 2 * 9 + 1)
|
| 638 |
-
if (isdigit(prevChar))
|
| 639 |
-
fileIdx += 9 * (prevChar - '0');
|
| 640 |
-
}
|
| 641 |
-
else if (c == '/')
|
| 642 |
-
{
|
| 643 |
-
++rankIdx;
|
| 644 |
-
if (fileIdx != board.get_nb_files())
|
| 645 |
-
{
|
| 646 |
-
std::cerr << "curRankWidth != nbFiles: " << fileIdx << " != " << board.get_nb_files() << std::endl;
|
| 647 |
-
return NOK;
|
| 648 |
-
}
|
| 649 |
-
if (rankIdx == board.get_nb_ranks())
|
| 650 |
-
break;
|
| 651 |
-
fileIdx = 0;
|
| 652 |
-
}
|
| 653 |
-
else if (!contains(validSpecialCharactersFirstField, c))
|
| 654 |
-
{ // normal piece
|
| 655 |
-
if (fileIdx == board.get_nb_files())
|
| 656 |
-
{
|
| 657 |
-
std::cerr << "File index: " << fileIdx << " for piece '" << c << "' exceeds maximum of allowed number of files: " << board.get_nb_files() << "." << std::endl;
|
| 658 |
-
return NOK;
|
| 659 |
-
}
|
| 660 |
-
board.set_piece(v->maxRank-rankIdx, fileIdx, c); // we mirror the rank index because the black pieces are given first in the FEN
|
| 661 |
-
++fileIdx;
|
| 662 |
-
}
|
| 663 |
-
prevChar = c;
|
| 664 |
-
}
|
| 665 |
-
|
| 666 |
-
if (v->pieceDrops)
|
| 667 |
-
{ // pockets can either be defined by [] or /
|
| 668 |
-
if (rankIdx+1 != board.get_nb_ranks() && rankIdx != board.get_nb_ranks())
|
| 669 |
-
{
|
| 670 |
-
std::cerr << "Invalid number of ranks. Expected: " << board.get_nb_ranks() << " Actual: " << rankIdx+1 << std::endl;
|
| 671 |
-
return NOK;
|
| 672 |
-
}
|
| 673 |
-
}
|
| 674 |
-
else
|
| 675 |
-
{
|
| 676 |
-
if (rankIdx+1 != board.get_nb_ranks())
|
| 677 |
-
{
|
| 678 |
-
std::cerr << "Invalid number of ranks. Expected: " << board.get_nb_ranks() << " Actual: " << rankIdx+1 << std::endl;
|
| 679 |
-
return NOK;
|
| 680 |
-
}
|
| 681 |
-
}
|
| 682 |
-
return OK;
|
| 683 |
-
}
|
| 684 |
-
|
| 685 |
-
inline Validation check_touching_kings(const CharBoard& board, const std::array<CharSquare, 2>& kingPositions) {
|
| 686 |
-
if (non_root_euclidian_distance(kingPositions[WHITE], kingPositions[BLACK]) <= 2)
|
| 687 |
-
{
|
| 688 |
-
std::cerr << "King pieces are next to each other." << std::endl;
|
| 689 |
-
std::cerr << board << std::endl;
|
| 690 |
-
return NOK;
|
| 691 |
-
}
|
| 692 |
-
return OK;
|
| 693 |
-
}
|
| 694 |
-
|
| 695 |
-
inline Validation fill_castling_info_splitted(const std::string& castlingInfo, std::array<std::string, 2>& castlingInfoSplitted) {
|
| 696 |
-
for (char c : castlingInfo)
|
| 697 |
-
{
|
| 698 |
-
if (c != '-')
|
| 699 |
-
{
|
| 700 |
-
if (!isalpha(c))
|
| 701 |
-
{
|
| 702 |
-
std::cerr << "Invalid castling specification: '" << c << "'." << std::endl;
|
| 703 |
-
return NOK;
|
| 704 |
-
}
|
| 705 |
-
else if (isupper(c))
|
| 706 |
-
castlingInfoSplitted[WHITE] += tolower(c);
|
| 707 |
-
else
|
| 708 |
-
castlingInfoSplitted[BLACK] += c;
|
| 709 |
-
}
|
| 710 |
-
}
|
| 711 |
-
return OK;
|
| 712 |
-
}
|
| 713 |
-
|
| 714 |
-
inline std::string color_to_string(Color c) {
|
| 715 |
-
switch (c)
|
| 716 |
-
{
|
| 717 |
-
case WHITE:
|
| 718 |
-
return "WHITE";
|
| 719 |
-
case BLACK:
|
| 720 |
-
return "BLACK";
|
| 721 |
-
case COLOR_NB:
|
| 722 |
-
return "COLOR_NB";
|
| 723 |
-
default:
|
| 724 |
-
return "INVALID_COLOR";
|
| 725 |
-
}
|
| 726 |
-
}
|
| 727 |
-
|
| 728 |
-
inline std::string castling_rights_to_string(CastlingRights castlingRights) {
|
| 729 |
-
switch (castlingRights)
|
| 730 |
-
{
|
| 731 |
-
case KING_SIDE:
|
| 732 |
-
return "KING_SIDE";
|
| 733 |
-
case QUEEN_SIDE:
|
| 734 |
-
return "QUEENS_SIDE";
|
| 735 |
-
case WHITE_OO:
|
| 736 |
-
return "WHITE_OO";
|
| 737 |
-
case WHITE_OOO:
|
| 738 |
-
return "WHITE_OOO";
|
| 739 |
-
case BLACK_OO:
|
| 740 |
-
return "BLACK_OO";
|
| 741 |
-
case BLACK_OOO:
|
| 742 |
-
return "BLACK_OOO";
|
| 743 |
-
case WHITE_CASTLING:
|
| 744 |
-
return "WHITE_CASTLING";
|
| 745 |
-
case BLACK_CASTLING:
|
| 746 |
-
return "BLACK_CASTLING";
|
| 747 |
-
case ANY_CASTLING:
|
| 748 |
-
return "ANY_CASTLING";
|
| 749 |
-
case CASTLING_RIGHT_NB:
|
| 750 |
-
return "CASTLING_RIGHT_NB";
|
| 751 |
-
default:
|
| 752 |
-
return "INVALID_CASTLING_RIGHTS";
|
| 753 |
-
}
|
| 754 |
-
}
|
| 755 |
-
|
| 756 |
-
inline Validation check_castling_rank(const std::array<std::string, 2>& castlingInfoSplitted, const CharBoard& board,
|
| 757 |
-
const std::array<CharSquare, 2>& kingPositions, const Variant* v) {
|
| 758 |
-
|
| 759 |
-
for (Color c : {WHITE, BLACK})
|
| 760 |
-
{
|
| 761 |
-
const Rank castlingRank = relative_rank(c, v->castlingRank, v->maxRank);
|
| 762 |
-
for (char castlingFlag : castlingInfoSplitted[c])
|
| 763 |
-
{
|
| 764 |
-
if (tolower(castlingFlag) == 'k' || tolower(castlingFlag) == 'q')
|
| 765 |
-
{
|
| 766 |
-
if (kingPositions[c].rowIdx != castlingRank)
|
| 767 |
-
{
|
| 768 |
-
std::cerr << "The " << color_to_string(c) << " king must be on rank " << castlingRank << " if castling is enabled for " << color_to_string(c) << "." << std::endl;
|
| 769 |
-
return NOK;
|
| 770 |
-
}
|
| 771 |
-
bool kingside = tolower(castlingFlag) == 'k';
|
| 772 |
-
bool castlingRook = false;
|
| 773 |
-
size_t pcIdx;
|
| 774 |
-
for (int f = kingside ? board.get_nb_files() - 1 : 0; f != kingPositions[c].fileIdx; kingside ? f-- : f++)
|
| 775 |
-
if ( (pcIdx = v->pieceToChar.find(board.get_piece(castlingRank, f))) != std::string::npos
|
| 776 |
-
&& (v->castlingRookPieces[c] & type_of(Piece(pcIdx)))
|
| 777 |
-
&& color_of(Piece(pcIdx)) == c)
|
| 778 |
-
{
|
| 779 |
-
castlingRook = true;
|
| 780 |
-
break;
|
| 781 |
-
}
|
| 782 |
-
if (!castlingRook)
|
| 783 |
-
{
|
| 784 |
-
std::cerr << "No castling rook for flag " << castlingFlag << std::endl;
|
| 785 |
-
return NOK;
|
| 786 |
-
}
|
| 787 |
-
}
|
| 788 |
-
else if (board.get_piece(castlingRank, tolower(castlingFlag) - 'a') == ' ')
|
| 789 |
-
{
|
| 790 |
-
std::cerr << "No gating piece for flag " << castlingFlag << std::endl;
|
| 791 |
-
return NOK;
|
| 792 |
-
}
|
| 793 |
-
}
|
| 794 |
-
}
|
| 795 |
-
return OK;
|
| 796 |
-
}
|
| 797 |
-
|
| 798 |
-
inline Validation check_standard_castling(std::array<std::string, 2>& castlingInfoSplitted, const CharBoard& board,
|
| 799 |
-
const std::array<CharSquare, 2>& kingPositions, const std::array<CharSquare, 2>& kingPositionsStart,
|
| 800 |
-
const std::array<std::vector<CharSquare>, 2>& rookPositionsStart, const Variant* v) {
|
| 801 |
-
|
| 802 |
-
for (Color c : {WHITE, BLACK})
|
| 803 |
-
{
|
| 804 |
-
if (castlingInfoSplitted[c].size() == 0)
|
| 805 |
-
continue;
|
| 806 |
-
if (kingPositions[c] != kingPositionsStart[c])
|
| 807 |
-
{
|
| 808 |
-
std::cerr << "The " << color_to_string(c) << " KING has moved. Castling is no longer valid for " << color_to_string(c) << "." << std::endl;
|
| 809 |
-
return NOK;
|
| 810 |
-
}
|
| 811 |
-
|
| 812 |
-
for (CastlingRights castling: {KING_SIDE, QUEEN_SIDE})
|
| 813 |
-
{
|
| 814 |
-
CharSquare rookStartingSquare = castling == QUEEN_SIDE ? rookPositionsStart[c][0] : rookPositionsStart[c][1];
|
| 815 |
-
char targetChar = castling == QUEEN_SIDE ? 'q' : 'k';
|
| 816 |
-
size_t pcIdx;
|
| 817 |
-
if (castlingInfoSplitted[c].find(targetChar) != std::string::npos)
|
| 818 |
-
{
|
| 819 |
-
if ( (pcIdx = v->pieceToChar.find(board.get_piece(rookStartingSquare.rowIdx, rookStartingSquare.fileIdx))) == std::string::npos
|
| 820 |
-
|| !(v->castlingRookPieces[c] & type_of(Piece(pcIdx)))
|
| 821 |
-
|| color_of(Piece(pcIdx)) != c)
|
| 822 |
-
{
|
| 823 |
-
std::cerr << "The " << color_to_string(c) << " ROOK on the "<< castling_rights_to_string(castling) << " has moved. "
|
| 824 |
-
<< castling_rights_to_string(castling) << " castling is no longer valid for " << color_to_string(c) << "." << std::endl;
|
| 825 |
-
return NOK;
|
| 826 |
-
}
|
| 827 |
-
}
|
| 828 |
-
|
| 829 |
-
}
|
| 830 |
-
}
|
| 831 |
-
return OK;
|
| 832 |
-
}
|
| 833 |
-
|
| 834 |
-
inline Validation check_pocket_info(const std::string& fenBoard, int nbRanks, const Variant* v, std::string& pocket) {
|
| 835 |
-
|
| 836 |
-
char stopChar;
|
| 837 |
-
int offset = 0;
|
| 838 |
-
if (std::count(fenBoard.begin(), fenBoard.end(), '/') == nbRanks)
|
| 839 |
-
{
|
| 840 |
-
// look for last '/'
|
| 841 |
-
stopChar = '/';
|
| 842 |
-
}
|
| 843 |
-
else if (std::count(fenBoard.begin(), fenBoard.end(), '[') == 1)
|
| 844 |
-
{
|
| 845 |
-
// pocket is defined as [ and ]
|
| 846 |
-
stopChar = '[';
|
| 847 |
-
offset = 1;
|
| 848 |
-
if (*(fenBoard.end()-1) != ']')
|
| 849 |
-
{
|
| 850 |
-
std::cerr << "Pocket specification does not end with ']'." << std::endl;
|
| 851 |
-
return NOK;
|
| 852 |
-
}
|
| 853 |
-
}
|
| 854 |
-
else
|
| 855 |
-
// allow to skip pocket
|
| 856 |
-
return OK;
|
| 857 |
-
|
| 858 |
-
// look for last '/'
|
| 859 |
-
for (auto it = fenBoard.rbegin()+offset; it != fenBoard.rend(); ++it)
|
| 860 |
-
{
|
| 861 |
-
const char c = *it;
|
| 862 |
-
if (c == stopChar)
|
| 863 |
-
return OK;
|
| 864 |
-
if (c != '-')
|
| 865 |
-
{
|
| 866 |
-
if (!in_any({v->pieceToChar, v->pieceToCharSynonyms}, c))
|
| 867 |
-
{
|
| 868 |
-
std::cerr << "Invalid pocket piece: '" << c << "'." << std::endl;
|
| 869 |
-
return NOK;
|
| 870 |
-
}
|
| 871 |
-
else
|
| 872 |
-
pocket += c;
|
| 873 |
-
}
|
| 874 |
-
}
|
| 875 |
-
std::cerr << "Pocket piece closing character '" << stopChar << "' was not found." << std::endl;
|
| 876 |
-
return NOK;
|
| 877 |
-
}
|
| 878 |
-
|
| 879 |
-
inline int piece_count(const std::string& fenBoard, Color c, PieceType pt, const Variant* v) {
|
| 880 |
-
return std::count(fenBoard.begin(), fenBoard.end(), v->pieceToChar[make_piece(c, pt)]);
|
| 881 |
-
}
|
| 882 |
-
|
| 883 |
-
inline Validation check_number_of_kings(const std::string& fenBoard, const std::string& startFenBoard, const Variant* v) {
|
| 884 |
-
int nbWhiteKings = piece_count(fenBoard, WHITE, KING, v);
|
| 885 |
-
int nbBlackKings = piece_count(fenBoard, BLACK, KING, v);
|
| 886 |
-
int nbWhiteKingsStart = piece_count(startFenBoard, WHITE, KING, v);
|
| 887 |
-
int nbBlackKingsStart = piece_count(startFenBoard, BLACK, KING, v);
|
| 888 |
-
|
| 889 |
-
if (nbWhiteKings > 1)
|
| 890 |
-
{
|
| 891 |
-
std::cerr << "Invalid number of white kings. Maximum: 1. Given: " << nbWhiteKings << std::endl;
|
| 892 |
-
return NOK;
|
| 893 |
-
}
|
| 894 |
-
if (nbBlackKings > 1)
|
| 895 |
-
{
|
| 896 |
-
std::cerr << "Invalid number of black kings. Maximum: 1. Given: " << nbBlackKings << std::endl;
|
| 897 |
-
return NOK;
|
| 898 |
-
}
|
| 899 |
-
if (nbWhiteKings != nbWhiteKingsStart)
|
| 900 |
-
{
|
| 901 |
-
std::cerr << "Invalid number of white kings. Expected: " << nbWhiteKingsStart << ". Given: " << nbWhiteKings << std::endl;
|
| 902 |
-
return NOK;
|
| 903 |
-
}
|
| 904 |
-
if (nbBlackKings != nbBlackKingsStart)
|
| 905 |
-
{
|
| 906 |
-
std::cerr << "Invalid number of black kings. Expected: " << nbBlackKingsStart << ". Given: " << nbBlackKings << std::endl;
|
| 907 |
-
return NOK;
|
| 908 |
-
}
|
| 909 |
-
return OK;
|
| 910 |
-
}
|
| 911 |
-
|
| 912 |
-
|
| 913 |
-
inline Validation check_en_passant_square(const std::string& enPassantInfo) {
|
| 914 |
-
if (enPassantInfo.size() != 1 || enPassantInfo[0] != '-')
|
| 915 |
-
{
|
| 916 |
-
if (enPassantInfo.size() != 2)
|
| 917 |
-
{
|
| 918 |
-
std::cerr << "Invalid en-passant square '" << enPassantInfo << "'. Expects 2 characters. Actual: " << enPassantInfo.size() << " character(s)." << std::endl;
|
| 919 |
-
return NOK;
|
| 920 |
-
}
|
| 921 |
-
if (!isalpha(enPassantInfo[0]))
|
| 922 |
-
{
|
| 923 |
-
std::cerr << "Invalid en-passant square '" << enPassantInfo << "'. Expects 1st character to be a letter." << std::endl;
|
| 924 |
-
return NOK;
|
| 925 |
-
}
|
| 926 |
-
if (!isdigit(enPassantInfo[1]))
|
| 927 |
-
{
|
| 928 |
-
std::cerr << "Invalid en-passant square '" << enPassantInfo << "'. Expects 2nd character to be a digit." << std::endl;
|
| 929 |
-
return NOK;
|
| 930 |
-
}
|
| 931 |
-
}
|
| 932 |
-
return OK;
|
| 933 |
-
}
|
| 934 |
-
|
| 935 |
-
|
| 936 |
-
inline Validation check_check_count(const std::string& checkCountInfo) {
|
| 937 |
-
if (checkCountInfo.size() != 3)
|
| 938 |
-
{
|
| 939 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 3 characters. Actual: " << checkCountInfo.size() << " character(s)." << std::endl;
|
| 940 |
-
return NOK;
|
| 941 |
-
}
|
| 942 |
-
if (!isdigit(checkCountInfo[0]))
|
| 943 |
-
{
|
| 944 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 1st character to be a digit." << std::endl;
|
| 945 |
-
return NOK;
|
| 946 |
-
}
|
| 947 |
-
if (!isdigit(checkCountInfo[2])) {
|
| 948 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 3rd character to be a digit." << std::endl;
|
| 949 |
-
return NOK;
|
| 950 |
-
}
|
| 951 |
-
return OK;
|
| 952 |
-
}
|
| 953 |
-
|
| 954 |
-
inline Validation check_lichess_check_count(const std::string& checkCountInfo) {
|
| 955 |
-
if (checkCountInfo.size() != 4)
|
| 956 |
-
{
|
| 957 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 4 characters. Actual: " << checkCountInfo.size() << " character(s)." << std::endl;
|
| 958 |
-
return NOK;
|
| 959 |
-
}
|
| 960 |
-
if (!isdigit(checkCountInfo[1]) || checkCountInfo[1] - '0' > 3)
|
| 961 |
-
{
|
| 962 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 2nd character to be a digit up to 3." << std::endl;
|
| 963 |
-
return NOK;
|
| 964 |
-
}
|
| 965 |
-
if (!isdigit(checkCountInfo[3]) || checkCountInfo[3] - '0' > 3) {
|
| 966 |
-
std::cerr << "Invalid check count '" << checkCountInfo << "'. Expects 4th character to be a digit up to 3." << std::endl;
|
| 967 |
-
return NOK;
|
| 968 |
-
}
|
| 969 |
-
return OK;
|
| 970 |
-
}
|
| 971 |
-
|
| 972 |
-
inline Validation check_digit_field(const std::string& field) {
|
| 973 |
-
if (field.size() == 1 && field[0] == '-')
|
| 974 |
-
return OK;
|
| 975 |
-
for (char c : field)
|
| 976 |
-
if (!isdigit(c))
|
| 977 |
-
return NOK;
|
| 978 |
-
return OK;
|
| 979 |
-
}
|
| 980 |
-
|
| 981 |
-
inline std::string get_valid_special_chars(const Variant* v) {
|
| 982 |
-
std::string validSpecialCharactersFirstField = "/*";
|
| 983 |
-
// Whether or not '-', '+', '~', '[', ']' are valid depends on the variant being played.
|
| 984 |
-
if (v->shogiStylePromotions)
|
| 985 |
-
validSpecialCharactersFirstField += '+';
|
| 986 |
-
if (v->promotionPieceTypes[WHITE] || v->promotionPieceTypes[BLACK])
|
| 987 |
-
validSpecialCharactersFirstField += '~';
|
| 988 |
-
if (!v->freeDrops && (v->pieceDrops || v->seirawanGating))
|
| 989 |
-
validSpecialCharactersFirstField += "[-]";
|
| 990 |
-
return validSpecialCharactersFirstField;
|
| 991 |
-
}
|
| 992 |
-
|
| 993 |
-
inline FenValidation validate_fen(const std::string& fen, const Variant* v, bool chess960 = false) {
|
| 994 |
-
|
| 995 |
-
const std::string validSpecialCharactersFirstField = get_valid_special_chars(v);
|
| 996 |
-
// 0) Layout
|
| 997 |
-
// check for empty fen
|
| 998 |
-
if (fen.empty())
|
| 999 |
-
{
|
| 1000 |
-
std::cerr << "Fen is empty." << std::endl;
|
| 1001 |
-
return FEN_EMPTY;
|
| 1002 |
-
}
|
| 1003 |
-
|
| 1004 |
-
std::vector<std::string> fenParts = get_fen_parts(fen, ' ');
|
| 1005 |
-
std::vector<std::string> startFenParts = get_fen_parts(v->startFen, ' ');
|
| 1006 |
-
|
| 1007 |
-
// check for number of parts
|
| 1008 |
-
const unsigned int maxNumberFenParts = 6 + v->checkCounting;
|
| 1009 |
-
if (fenParts.size() < 1 || fenParts.size() > maxNumberFenParts)
|
| 1010 |
-
{
|
| 1011 |
-
std::cerr << "Invalid number of fen parts. Expected: >= 1 and <= " << maxNumberFenParts
|
| 1012 |
-
<< " Actual: " << fenParts.size() << std::endl;
|
| 1013 |
-
return FEN_INVALID_NB_PARTS;
|
| 1014 |
-
}
|
| 1015 |
-
|
| 1016 |
-
// 1) Part
|
| 1017 |
-
// check for valid characters
|
| 1018 |
-
if (check_for_valid_characters(fenParts[0], validSpecialCharactersFirstField, v) == NOK)
|
| 1019 |
-
return FEN_INVALID_CHAR;
|
| 1020 |
-
|
| 1021 |
-
// check for valid promoted pieces
|
| 1022 |
-
if (check_promoted_pieces(fenParts[0], v) == NOK)
|
| 1023 |
-
return FEN_INVALID_PROMOTED_PIECE;
|
| 1024 |
-
|
| 1025 |
-
// check for number of ranks
|
| 1026 |
-
const int nbRanks = v->maxRank + 1;
|
| 1027 |
-
// check for number of files
|
| 1028 |
-
const int nbFiles = v->maxFile + 1;
|
| 1029 |
-
CharBoard board(nbRanks, nbFiles); // create a 2D character board for later geometry checks
|
| 1030 |
-
|
| 1031 |
-
if (fill_char_board(board, fenParts[0], validSpecialCharactersFirstField, v) == NOK)
|
| 1032 |
-
return FEN_INVALID_BOARD_GEOMETRY;
|
| 1033 |
-
|
| 1034 |
-
// check for pocket
|
| 1035 |
-
std::string pocket = "";
|
| 1036 |
-
if (v->pieceDrops || v->seirawanGating)
|
| 1037 |
-
{
|
| 1038 |
-
if (check_pocket_info(fenParts[0], nbRanks, v, pocket) == NOK)
|
| 1039 |
-
return FEN_INVALID_POCKET_INFO;
|
| 1040 |
-
}
|
| 1041 |
-
|
| 1042 |
-
// check for number of kings
|
| 1043 |
-
if (v->pieceTypes & KING)
|
| 1044 |
-
{
|
| 1045 |
-
// we have a royal king in this variant,
|
| 1046 |
-
// ensure that each side has exactly as many kings as in the starting position
|
| 1047 |
-
// (variants like giveaway use the COMMONER piece type instead)
|
| 1048 |
-
if (check_number_of_kings(fenParts[0], startFenParts[0], v) == NOK)
|
| 1049 |
-
return FEN_INVALID_NUMBER_OF_KINGS;
|
| 1050 |
-
|
| 1051 |
-
// check for touching kings if there are exactly two royal kings on the board (excluding pocket)
|
| 1052 |
-
if ( v->kingType == KING
|
| 1053 |
-
&& piece_count(fenParts[0], WHITE, KING, v) - piece_count(pocket, WHITE, KING, v) == 1
|
| 1054 |
-
&& piece_count(fenParts[0], BLACK, KING, v) - piece_count(pocket, BLACK, KING, v) == 1)
|
| 1055 |
-
{
|
| 1056 |
-
std::array<CharSquare, 2> kingPositions;
|
| 1057 |
-
kingPositions[WHITE] = board.get_square_for_piece(v->pieceToChar[make_piece(WHITE, KING)]);
|
| 1058 |
-
kingPositions[BLACK] = board.get_square_for_piece(v->pieceToChar[make_piece(BLACK, KING)]);
|
| 1059 |
-
if (check_touching_kings(board, kingPositions) == NOK)
|
| 1060 |
-
return FEN_TOUCHING_KINGS;
|
| 1061 |
-
}
|
| 1062 |
-
}
|
| 1063 |
-
|
| 1064 |
-
// 2) Part
|
| 1065 |
-
// check side to move char
|
| 1066 |
-
if (fenParts.size() >= 2 && fenParts[1][0] != 'w' && fenParts[1][0] != 'b')
|
| 1067 |
-
{
|
| 1068 |
-
std::cerr << "Invalid side to move specification: '" << fenParts[1][0] << "'." << std::endl;
|
| 1069 |
-
return FEN_INVALID_SIDE_TO_MOVE;
|
| 1070 |
-
}
|
| 1071 |
-
|
| 1072 |
-
// Castling and en passant can be skipped
|
| 1073 |
-
bool skipCastlingAndEp = fenParts.size() >= 4 && fenParts.size() <= 5 && isdigit(fenParts[2][0]);
|
| 1074 |
-
|
| 1075 |
-
// 3) Part
|
| 1076 |
-
// check castling rights
|
| 1077 |
-
if (fenParts.size() >= 3 && !skipCastlingAndEp && v->castling)
|
| 1078 |
-
{
|
| 1079 |
-
std::array<std::string, 2> castlingInfoSplitted;
|
| 1080 |
-
if (fill_castling_info_splitted(fenParts[2], castlingInfoSplitted) == NOK)
|
| 1081 |
-
return FEN_INVALID_CASTLING_INFO;
|
| 1082 |
-
|
| 1083 |
-
if (castlingInfoSplitted[WHITE].size() != 0 || castlingInfoSplitted[BLACK].size() != 0)
|
| 1084 |
-
{
|
| 1085 |
-
std::array<CharSquare, 2> kingPositions;
|
| 1086 |
-
kingPositions[WHITE] = board.get_square_for_piece(toupper(v->pieceToChar[v->castlingKingPiece[WHITE]]));
|
| 1087 |
-
kingPositions[BLACK] = board.get_square_for_piece(tolower(v->pieceToChar[v->castlingKingPiece[BLACK]]));
|
| 1088 |
-
|
| 1089 |
-
CharBoard startBoard(board.get_nb_ranks(), board.get_nb_files());
|
| 1090 |
-
fill_char_board(startBoard, v->startFen, validSpecialCharactersFirstField, v);
|
| 1091 |
-
|
| 1092 |
-
// Check pieces present on castling rank against castling/gating rights
|
| 1093 |
-
if (check_castling_rank(castlingInfoSplitted, board, kingPositions, v) == NOK)
|
| 1094 |
-
return FEN_INVALID_CASTLING_INFO;
|
| 1095 |
-
|
| 1096 |
-
// only check exact squares if starting position of castling pieces is known
|
| 1097 |
-
if (!v->chess960 && !v->castlingDroppedPiece && !chess960)
|
| 1098 |
-
{
|
| 1099 |
-
std::array<CharSquare, 2> kingPositionsStart;
|
| 1100 |
-
kingPositionsStart[WHITE] = startBoard.get_square_for_piece(v->pieceToChar[make_piece(WHITE, v->castlingKingPiece[WHITE])]);
|
| 1101 |
-
kingPositionsStart[BLACK] = startBoard.get_square_for_piece(v->pieceToChar[make_piece(BLACK, v->castlingKingPiece[BLACK])]);
|
| 1102 |
-
std::array<std::vector<CharSquare>, 2> rookPositionsStart;
|
| 1103 |
-
rookPositionsStart[WHITE] = startBoard.get_squares_for_pieces(WHITE, v->castlingRookPieces[WHITE], v->pieceToChar);
|
| 1104 |
-
rookPositionsStart[BLACK] = startBoard.get_squares_for_pieces(BLACK, v->castlingRookPieces[BLACK], v->pieceToChar);
|
| 1105 |
-
|
| 1106 |
-
if (check_standard_castling(castlingInfoSplitted, board, kingPositions, kingPositionsStart, rookPositionsStart, v) == NOK)
|
| 1107 |
-
return FEN_INVALID_CASTLING_INFO;
|
| 1108 |
-
}
|
| 1109 |
-
}
|
| 1110 |
-
}
|
| 1111 |
-
|
| 1112 |
-
// 4) Part
|
| 1113 |
-
// check en-passant square
|
| 1114 |
-
if (fenParts.size() >= 4 && !skipCastlingAndEp)
|
| 1115 |
-
{
|
| 1116 |
-
if (v->doubleStep && (v->pieceTypes & PAWN))
|
| 1117 |
-
{
|
| 1118 |
-
if (check_en_passant_square(fenParts[3]) == NOK)
|
| 1119 |
-
return FEN_INVALID_EN_PASSANT_SQ;
|
| 1120 |
-
}
|
| 1121 |
-
else if (v->countingRule && !check_digit_field(fenParts[3]))
|
| 1122 |
-
return FEN_INVALID_COUNTING_RULE;
|
| 1123 |
-
}
|
| 1124 |
-
|
| 1125 |
-
// 5) Part
|
| 1126 |
-
// check check count
|
| 1127 |
-
unsigned int optionalInbetweenFields = 2 * !skipCastlingAndEp;
|
| 1128 |
-
unsigned int optionalTrailingFields = 0;
|
| 1129 |
-
if (fenParts.size() >= 3 + optionalInbetweenFields && v->checkCounting && fenParts.size() % 2)
|
| 1130 |
-
{
|
| 1131 |
-
if (check_check_count(fenParts[2 + optionalInbetweenFields]) == NOK)
|
| 1132 |
-
{
|
| 1133 |
-
// allow valid lichess style check as alternative
|
| 1134 |
-
if (fenParts.size() < 5 + optionalInbetweenFields || check_lichess_check_count(fenParts[fenParts.size() - 1]) == NOK)
|
| 1135 |
-
return FEN_INVALID_CHECK_COUNT;
|
| 1136 |
-
else
|
| 1137 |
-
optionalTrailingFields++;
|
| 1138 |
-
}
|
| 1139 |
-
else
|
| 1140 |
-
optionalInbetweenFields++;
|
| 1141 |
-
}
|
| 1142 |
-
|
| 1143 |
-
// 6) Part
|
| 1144 |
-
// check half move counter
|
| 1145 |
-
if (fenParts.size() >= 3 + optionalInbetweenFields && !check_digit_field(fenParts[fenParts.size() - 2 - optionalTrailingFields]))
|
| 1146 |
-
{
|
| 1147 |
-
std::cerr << "Invalid half move counter: '" << fenParts[fenParts.size()-2] << "'." << std::endl;
|
| 1148 |
-
return FEN_INVALID_HALF_MOVE_COUNTER;
|
| 1149 |
-
}
|
| 1150 |
-
|
| 1151 |
-
// 7) Part
|
| 1152 |
-
// check move counter
|
| 1153 |
-
if (fenParts.size() >= 4 + optionalInbetweenFields && !check_digit_field(fenParts[fenParts.size() - 1 - optionalTrailingFields]))
|
| 1154 |
-
{
|
| 1155 |
-
std::cerr << "Invalid move counter: '" << fenParts[fenParts.size()-1] << "'." << std::endl;
|
| 1156 |
-
return FEN_INVALID_MOVE_COUNTER;
|
| 1157 |
-
}
|
| 1158 |
-
|
| 1159 |
-
return FEN_OK;
|
| 1160 |
-
}
|
| 1161 |
-
} // namespace FEN
|
| 1162 |
-
|
| 1163 |
-
} // namespace Stockfish
|
| 1164 |
-
|
| 1165 |
-
#endif // #ifndef APIUTIL_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/benchmark.cpp
DELETED
|
@@ -1,195 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <fstream>
|
| 20 |
-
#include <iostream>
|
| 21 |
-
#include <istream>
|
| 22 |
-
#include <vector>
|
| 23 |
-
|
| 24 |
-
#include "position.h"
|
| 25 |
-
#include "uci.h"
|
| 26 |
-
|
| 27 |
-
using namespace std;
|
| 28 |
-
|
| 29 |
-
namespace {
|
| 30 |
-
|
| 31 |
-
const vector<string> Defaults = {
|
| 32 |
-
"setoption name UCI_Chess960 value false",
|
| 33 |
-
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
| 34 |
-
"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 10",
|
| 35 |
-
"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 11",
|
| 36 |
-
"4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19",
|
| 37 |
-
"rq3rk1/ppp2ppp/1bnpb3/3N2B1/3NP3/7P/PPPQ1PP1/2KR3R w - - 7 14 moves d4e6",
|
| 38 |
-
"r1bq1r1k/1pp1n1pp/1p1p4/4p2Q/4Pp2/1BNP4/PPP2PPP/3R1RK1 w - - 2 14 moves g2g4",
|
| 39 |
-
"r3r1k1/2p2ppp/p1p1bn2/8/1q2P3/2NPQN2/PPP3PP/R4RK1 b - - 2 15",
|
| 40 |
-
"r1bbk1nr/pp3p1p/2n5/1N4p1/2Np1B2/8/PPP2PPP/2KR1B1R w kq - 0 13",
|
| 41 |
-
"r1bq1rk1/ppp1nppp/4n3/3p3Q/3P4/1BP1B3/PP1N2PP/R4RK1 w - - 1 16",
|
| 42 |
-
"4r1k1/r1q2ppp/ppp2n2/4P3/5Rb1/1N1BQ3/PPP3PP/R5K1 w - - 1 17",
|
| 43 |
-
"2rqkb1r/ppp2p2/2npb1p1/1N1Nn2p/2P1PP2/8/PP2B1PP/R1BQK2R b KQ - 0 11",
|
| 44 |
-
"r1bq1r1k/b1p1npp1/p2p3p/1p6/3PP3/1B2NN2/PP3PPP/R2Q1RK1 w - - 1 16",
|
| 45 |
-
"3r1rk1/p5pp/bpp1pp2/8/q1PP1P2/b3P3/P2NQRPP/1R2B1K1 b - - 6 22",
|
| 46 |
-
"r1q2rk1/2p1bppp/2Pp4/p6b/Q1PNp3/4B3/PP1R1PPP/2K4R w - - 2 18",
|
| 47 |
-
"4k2r/1pb2ppp/1p2p3/1R1p4/3P4/2r1PN2/P4PPP/1R4K1 b - - 3 22",
|
| 48 |
-
"3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - 4 26",
|
| 49 |
-
"6k1/6p1/6Pp/ppp5/3pn2P/1P3K2/1PP2P2/3N4 b - - 0 1",
|
| 50 |
-
"3b4/5kp1/1p1p1p1p/pP1PpP1P/P1P1P3/3KN3/8/8 w - - 0 1",
|
| 51 |
-
"2K5/p7/7P/5pR1/8/5k2/r7/8 w - - 0 1 moves g5g6 f3e3 g6g5 e3f3",
|
| 52 |
-
"8/6pk/1p6/8/PP3p1p/5P2/4KP1q/3Q4 w - - 0 1",
|
| 53 |
-
"7k/3p2pp/4q3/8/4Q3/5Kp1/P6b/8 w - - 0 1",
|
| 54 |
-
"8/2p5/8/2kPKp1p/2p4P/2P5/3P4/8 w - - 0 1",
|
| 55 |
-
"8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - 0 1",
|
| 56 |
-
"8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - 0 1",
|
| 57 |
-
"8/3p4/p1bk3p/Pp6/1Kp1PpPp/2P2P1P/2P5/5B2 b - - 0 1",
|
| 58 |
-
"5k2/7R/4P2p/5K2/p1r2P1p/8/8/8 b - - 0 1",
|
| 59 |
-
"6k1/6p1/P6p/r1N5/5p2/7P/1b3PP1/4R1K1 w - - 0 1",
|
| 60 |
-
"1r3k2/4q3/2Pp3b/3Bp3/2Q2p2/1p1P2P1/1P2KP2/3N4 w - - 0 1",
|
| 61 |
-
"6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - 0 1",
|
| 62 |
-
"8/3p3B/5p2/5P2/p7/PP5b/k7/6K1 w - - 0 1",
|
| 63 |
-
"5rk1/q6p/2p3bR/1pPp1rP1/1P1Pp3/P3B1Q1/1K3P2/R7 w - - 93 90",
|
| 64 |
-
"4rrk1/1p1nq3/p7/2p1P1pp/3P2bp/3Q1Bn1/PPPB4/1K2R1NR w - - 40 21",
|
| 65 |
-
"r3k2r/3nnpbp/q2pp1p1/p7/Pp1PPPP1/4BNN1/1P5P/R2Q1RK1 w kq - 0 16",
|
| 66 |
-
"3Qb1k1/1r2ppb1/pN1n2q1/Pp1Pp1Pr/4P2p/4BP2/4B1R1/1R5K b - - 11 40",
|
| 67 |
-
"4k3/3q1r2/1N2r1b1/3ppN2/2nPP3/1B1R2n1/2R1Q3/3K4 w - - 5 1",
|
| 68 |
-
|
| 69 |
-
// 5-man positions
|
| 70 |
-
"8/8/8/8/5kp1/P7/8/1K1N4 w - - 0 1", // Kc2 - mate
|
| 71 |
-
"8/8/8/5N2/8/p7/8/2NK3k w - - 0 1", // Na2 - mate
|
| 72 |
-
"8/3k4/8/8/8/4B3/4KB2/2B5 w - - 0 1", // draw
|
| 73 |
-
|
| 74 |
-
// 6-man positions
|
| 75 |
-
"8/8/1P6/5pr1/8/4R3/7k/2K5 w - - 0 1", // Re5 - mate
|
| 76 |
-
"8/2p4P/8/kr6/6R1/8/8/1K6 w - - 0 1", // Ka2 - mate
|
| 77 |
-
"8/8/3P3k/8/1p6/8/1P6/1K3n2 b - - 0 1", // Nd2 - draw
|
| 78 |
-
|
| 79 |
-
// 7-man positions
|
| 80 |
-
"8/R7/2q5/8/6k1/8/1P5p/K6R w - - 0 124", // Draw
|
| 81 |
-
|
| 82 |
-
// Mate and stalemate positions
|
| 83 |
-
"6k1/3b3r/1p1p4/p1n2p2/1PPNpP1q/P3Q1p1/1R1RB1P1/5K2 b - - 0 1",
|
| 84 |
-
"r2r1n2/pp2bk2/2p1p2p/3q4/3PN1QP/2P3R1/P4PP1/5RK1 w - - 0 1",
|
| 85 |
-
"8/8/8/8/8/6k1/6p1/6K1 w - -",
|
| 86 |
-
"7k/7P/6K1/8/3B4/8/8/8 b - -",
|
| 87 |
-
|
| 88 |
-
// Chess 960
|
| 89 |
-
"setoption name UCI_Chess960 value true",
|
| 90 |
-
"bbqnnrkr/pppppppp/8/8/8/8/PPPPPPPP/BBQNNRKR w HFhf - 0 1 moves g2g3 d7d5 d2d4 c8h3 c1g5 e8d6 g5e7 f7f6",
|
| 91 |
-
"setoption name UCI_Chess960 value false"
|
| 92 |
-
};
|
| 93 |
-
|
| 94 |
-
} // namespace
|
| 95 |
-
|
| 96 |
-
namespace Stockfish {
|
| 97 |
-
|
| 98 |
-
/// setup_bench() builds a list of UCI commands to be run by bench. There
|
| 99 |
-
/// are five parameters: TT size in MB, number of search threads that
|
| 100 |
-
/// should be used, the limit value spent for each position, a file name
|
| 101 |
-
/// where to look for positions in FEN format, the type of the limit:
|
| 102 |
-
/// depth, perft, nodes and movetime (in millisecs), and evaluation type
|
| 103 |
-
/// mixed (default), classical, NNUE.
|
| 104 |
-
///
|
| 105 |
-
/// bench -> search default positions up to depth 13
|
| 106 |
-
/// bench 64 1 15 -> search default positions up to depth 15 (TT = 64MB)
|
| 107 |
-
/// bench 64 4 5000 current movetime -> search current position with 4 threads for 5 sec
|
| 108 |
-
/// bench 64 1 100000 default nodes -> search default positions for 100K nodes each
|
| 109 |
-
/// bench 16 1 5 default perft -> run a perft 5 on default positions
|
| 110 |
-
|
| 111 |
-
vector<string> setup_bench(const Position& current, istream& is) {
|
| 112 |
-
|
| 113 |
-
vector<string> fens, list;
|
| 114 |
-
string go, token, varname;
|
| 115 |
-
|
| 116 |
-
streampos args = is.tellg();
|
| 117 |
-
// Check whether the next token is a variant name
|
| 118 |
-
if ((is >> token) && variants.find(token) != variants.end())
|
| 119 |
-
{
|
| 120 |
-
args = is.tellg();
|
| 121 |
-
varname = token;
|
| 122 |
-
}
|
| 123 |
-
else
|
| 124 |
-
{
|
| 125 |
-
is.seekg(args);
|
| 126 |
-
varname = string(Options["UCI_Variant"]);
|
| 127 |
-
}
|
| 128 |
-
const Variant* variant = variants.find(varname)->second;
|
| 129 |
-
|
| 130 |
-
// Assign default values to missing arguments
|
| 131 |
-
string ttSize = (is >> token) ? token : "16";
|
| 132 |
-
string threads = (is >> token) ? token : "1";
|
| 133 |
-
string limit = (is >> token) ? token : "13";
|
| 134 |
-
string fenFile = (is >> token) ? token : "default";
|
| 135 |
-
string limitType = (is >> token) ? token : "depth";
|
| 136 |
-
string evalType = (is >> token) ? token : "mixed";
|
| 137 |
-
|
| 138 |
-
go = limitType == "eval" ? "eval" : "go " + limitType + " " + limit;
|
| 139 |
-
|
| 140 |
-
if (fenFile == "default")
|
| 141 |
-
{
|
| 142 |
-
if (varname != "chess")
|
| 143 |
-
fens.push_back(variant->startFen);
|
| 144 |
-
else
|
| 145 |
-
fens = Defaults;
|
| 146 |
-
}
|
| 147 |
-
|
| 148 |
-
else if (fenFile == "current")
|
| 149 |
-
fens.push_back(current.fen());
|
| 150 |
-
|
| 151 |
-
else
|
| 152 |
-
{
|
| 153 |
-
string fen;
|
| 154 |
-
ifstream file(fenFile);
|
| 155 |
-
|
| 156 |
-
if (!file.is_open())
|
| 157 |
-
{
|
| 158 |
-
cerr << "Unable to open file " << fenFile << endl;
|
| 159 |
-
exit(EXIT_FAILURE);
|
| 160 |
-
}
|
| 161 |
-
|
| 162 |
-
while (getline(file, fen))
|
| 163 |
-
if (!fen.empty())
|
| 164 |
-
fens.push_back(fen);
|
| 165 |
-
|
| 166 |
-
file.close();
|
| 167 |
-
}
|
| 168 |
-
|
| 169 |
-
list.emplace_back("setoption name Threads value " + threads);
|
| 170 |
-
list.emplace_back("setoption name Hash value " + ttSize);
|
| 171 |
-
list.emplace_back("setoption name UCI_Variant value " + varname);
|
| 172 |
-
list.emplace_back("ucinewgame");
|
| 173 |
-
|
| 174 |
-
size_t posCounter = 0;
|
| 175 |
-
|
| 176 |
-
for (const string& fen : fens)
|
| 177 |
-
if (fen.find("setoption") != string::npos)
|
| 178 |
-
list.emplace_back(fen);
|
| 179 |
-
else
|
| 180 |
-
{
|
| 181 |
-
if (evalType == "classical" || (evalType == "mixed" && posCounter % 2 == 0))
|
| 182 |
-
list.emplace_back("setoption name Use NNUE value false");
|
| 183 |
-
else if (evalType == "NNUE" || (evalType == "mixed" && posCounter % 2 != 0))
|
| 184 |
-
list.emplace_back("setoption name Use NNUE value true");
|
| 185 |
-
list.emplace_back("position fen " + fen);
|
| 186 |
-
list.emplace_back(go);
|
| 187 |
-
++posCounter;
|
| 188 |
-
}
|
| 189 |
-
|
| 190 |
-
list.emplace_back("setoption name Use NNUE value true");
|
| 191 |
-
|
| 192 |
-
return list;
|
| 193 |
-
}
|
| 194 |
-
|
| 195 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/bitbase.cpp
DELETED
|
@@ -1,177 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <cassert>
|
| 20 |
-
#include <vector>
|
| 21 |
-
#include <bitset>
|
| 22 |
-
|
| 23 |
-
#include "bitboard.h"
|
| 24 |
-
#include "types.h"
|
| 25 |
-
|
| 26 |
-
namespace Stockfish {
|
| 27 |
-
|
| 28 |
-
namespace {
|
| 29 |
-
|
| 30 |
-
// There are 24 possible pawn squares: files A to D and ranks from 2 to 7.
|
| 31 |
-
// Positions with the pawn on files E to H will be mirrored before probing.
|
| 32 |
-
constexpr unsigned MAX_INDEX = 2*24*64*64; // stm * psq * wksq * bksq = 196608
|
| 33 |
-
|
| 34 |
-
std::bitset<MAX_INDEX> KPKBitbase;
|
| 35 |
-
|
| 36 |
-
// A KPK bitbase index is an integer in [0, IndexMax] range
|
| 37 |
-
//
|
| 38 |
-
// Information is mapped in a way that minimizes the number of iterations:
|
| 39 |
-
//
|
| 40 |
-
// bit 0- 5: white king square (from SQ_A1 to SQ_H8)
|
| 41 |
-
// bit 6-11: black king square (from SQ_A1 to SQ_H8)
|
| 42 |
-
// bit 12: side to move (WHITE or BLACK)
|
| 43 |
-
// bit 13-14: white pawn file (from FILE_A to FILE_D)
|
| 44 |
-
// bit 15-17: white pawn RANK_7 - rank (from RANK_7 - RANK_7 to RANK_7 - RANK_2)
|
| 45 |
-
unsigned index(Color stm, Square bksq, Square wksq, Square psq) {
|
| 46 |
-
return int(wksq) | (bksq << 6) | (stm << 12) | (file_of(psq) << 13) | ((RANK_7 - rank_of(psq)) << 15);
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
enum Result {
|
| 50 |
-
INVALID = 0,
|
| 51 |
-
UNKNOWN = 1,
|
| 52 |
-
DRAW = 2,
|
| 53 |
-
WIN = 4
|
| 54 |
-
};
|
| 55 |
-
|
| 56 |
-
Result& operator|=(Result& r, Result v) { return r = Result(r | v); }
|
| 57 |
-
|
| 58 |
-
struct KPKPosition {
|
| 59 |
-
KPKPosition() = default;
|
| 60 |
-
explicit KPKPosition(unsigned idx);
|
| 61 |
-
operator Result() const { return result; }
|
| 62 |
-
Result classify(const std::vector<KPKPosition>& db);
|
| 63 |
-
|
| 64 |
-
Color stm;
|
| 65 |
-
Square ksq[COLOR_NB], psq;
|
| 66 |
-
Result result;
|
| 67 |
-
};
|
| 68 |
-
|
| 69 |
-
} // namespace
|
| 70 |
-
|
| 71 |
-
bool Bitbases::probe(Square wksq, Square wpsq, Square bksq, Color stm) {
|
| 72 |
-
|
| 73 |
-
assert(file_of(wpsq) <= FILE_D);
|
| 74 |
-
|
| 75 |
-
return KPKBitbase[index(stm, bksq, wksq, wpsq)];
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
void Bitbases::init() {
|
| 80 |
-
|
| 81 |
-
#ifdef LARGEBOARDS
|
| 82 |
-
// Bitbases are not working for large-board version
|
| 83 |
-
return;
|
| 84 |
-
#endif
|
| 85 |
-
|
| 86 |
-
std::vector<KPKPosition> db(MAX_INDEX);
|
| 87 |
-
unsigned idx, repeat = 1;
|
| 88 |
-
|
| 89 |
-
// Initialize db with known win / draw positions
|
| 90 |
-
for (idx = 0; idx < MAX_INDEX; ++idx)
|
| 91 |
-
db[idx] = KPKPosition(idx);
|
| 92 |
-
|
| 93 |
-
// Iterate through the positions until none of the unknown positions can be
|
| 94 |
-
// changed to either wins or draws (15 cycles needed).
|
| 95 |
-
while (repeat)
|
| 96 |
-
for (repeat = idx = 0; idx < MAX_INDEX; ++idx)
|
| 97 |
-
repeat |= (db[idx] == UNKNOWN && db[idx].classify(db) != UNKNOWN);
|
| 98 |
-
|
| 99 |
-
// Fill the bitbase with the decisive results
|
| 100 |
-
for (idx = 0; idx < MAX_INDEX; ++idx)
|
| 101 |
-
if (db[idx] == WIN)
|
| 102 |
-
KPKBitbase.set(idx);
|
| 103 |
-
}
|
| 104 |
-
|
| 105 |
-
namespace {
|
| 106 |
-
|
| 107 |
-
KPKPosition::KPKPosition(unsigned idx) {
|
| 108 |
-
|
| 109 |
-
ksq[WHITE] = Square((idx >> 0) & 0x3F);
|
| 110 |
-
ksq[BLACK] = Square((idx >> 6) & 0x3F);
|
| 111 |
-
stm = Color ((idx >> 12) & 0x01);
|
| 112 |
-
psq = make_square(File((idx >> 13) & 0x3), Rank(RANK_7 - ((idx >> 15) & 0x7)));
|
| 113 |
-
|
| 114 |
-
// Invalid if two pieces are on the same square or if a king can be captured
|
| 115 |
-
if ( distance(ksq[WHITE], ksq[BLACK]) <= 1
|
| 116 |
-
|| ksq[WHITE] == psq
|
| 117 |
-
|| ksq[BLACK] == psq
|
| 118 |
-
|| (stm == WHITE && (pawn_attacks_bb(WHITE, psq) & ksq[BLACK])))
|
| 119 |
-
result = INVALID;
|
| 120 |
-
|
| 121 |
-
// Win if the pawn can be promoted without getting captured
|
| 122 |
-
else if ( stm == WHITE
|
| 123 |
-
&& rank_of(psq) == RANK_7
|
| 124 |
-
&& ksq[WHITE] != psq + NORTH
|
| 125 |
-
&& ( distance(ksq[BLACK], psq + NORTH) > 1
|
| 126 |
-
|| (distance(ksq[WHITE], psq + NORTH) == 1)))
|
| 127 |
-
result = WIN;
|
| 128 |
-
|
| 129 |
-
// Draw if it is stalemate or the black king can capture the pawn
|
| 130 |
-
else if ( stm == BLACK
|
| 131 |
-
&& ( !(attacks_bb<KING>(ksq[BLACK]) & ~(attacks_bb<KING>(ksq[WHITE]) | pawn_attacks_bb(WHITE, psq)))
|
| 132 |
-
|| (attacks_bb<KING>(ksq[BLACK]) & ~attacks_bb<KING>(ksq[WHITE]) & psq)))
|
| 133 |
-
result = DRAW;
|
| 134 |
-
|
| 135 |
-
// Position will be classified later
|
| 136 |
-
else
|
| 137 |
-
result = UNKNOWN;
|
| 138 |
-
}
|
| 139 |
-
|
| 140 |
-
Result KPKPosition::classify(const std::vector<KPKPosition>& db) {
|
| 141 |
-
|
| 142 |
-
// White to move: If one move leads to a position classified as WIN, the result
|
| 143 |
-
// of the current position is WIN. If all moves lead to positions classified
|
| 144 |
-
// as DRAW, the current position is classified as DRAW, otherwise the current
|
| 145 |
-
// position is classified as UNKNOWN.
|
| 146 |
-
//
|
| 147 |
-
// Black to move: If one move leads to a position classified as DRAW, the result
|
| 148 |
-
// of the current position is DRAW. If all moves lead to positions classified
|
| 149 |
-
// as WIN, the position is classified as WIN, otherwise the current position is
|
| 150 |
-
// classified as UNKNOWN.
|
| 151 |
-
const Result Good = (stm == WHITE ? WIN : DRAW);
|
| 152 |
-
const Result Bad = (stm == WHITE ? DRAW : WIN);
|
| 153 |
-
|
| 154 |
-
Result r = INVALID;
|
| 155 |
-
Bitboard b = attacks_bb<KING>(ksq[stm]);
|
| 156 |
-
|
| 157 |
-
while (b)
|
| 158 |
-
r |= stm == WHITE ? db[index(BLACK, ksq[BLACK], pop_lsb(b), psq)]
|
| 159 |
-
: db[index(WHITE, pop_lsb(b), ksq[WHITE], psq)];
|
| 160 |
-
|
| 161 |
-
if (stm == WHITE)
|
| 162 |
-
{
|
| 163 |
-
if (rank_of(psq) < RANK_7) // Single push
|
| 164 |
-
r |= db[index(BLACK, ksq[BLACK], ksq[WHITE], psq + NORTH)];
|
| 165 |
-
|
| 166 |
-
if ( rank_of(psq) == RANK_2 // Double push
|
| 167 |
-
&& psq + NORTH != ksq[WHITE]
|
| 168 |
-
&& psq + NORTH != ksq[BLACK])
|
| 169 |
-
r |= db[index(BLACK, ksq[BLACK], ksq[WHITE], psq + NORTH + NORTH)];
|
| 170 |
-
}
|
| 171 |
-
|
| 172 |
-
return result = r & Good ? Good : r & UNKNOWN ? UNKNOWN : Bad;
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
} // namespace
|
| 176 |
-
|
| 177 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/bitboard.cpp
DELETED
|
@@ -1,501 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <algorithm>
|
| 20 |
-
#include <bitset>
|
| 21 |
-
|
| 22 |
-
#include "bitboard.h"
|
| 23 |
-
#include "magic.h"
|
| 24 |
-
#include "misc.h"
|
| 25 |
-
#include "piece.h"
|
| 26 |
-
|
| 27 |
-
namespace Stockfish {
|
| 28 |
-
|
| 29 |
-
uint8_t PopCnt16[1 << 16];
|
| 30 |
-
uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
|
| 31 |
-
|
| 32 |
-
Bitboard SquareBB[SQUARE_NB];
|
| 33 |
-
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
|
| 34 |
-
Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
|
| 35 |
-
Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 36 |
-
Bitboard PseudoMoves[2][COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 37 |
-
Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 38 |
-
Bitboard LeaperMoves[2][COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 39 |
-
Bitboard BoardSizeBB[FILE_NB][RANK_NB];
|
| 40 |
-
RiderType AttackRiderTypes[PIECE_TYPE_NB];
|
| 41 |
-
RiderType MoveRiderTypes[2][PIECE_TYPE_NB];
|
| 42 |
-
|
| 43 |
-
Magic RookMagicsH[SQUARE_NB];
|
| 44 |
-
Magic RookMagicsV[SQUARE_NB];
|
| 45 |
-
Magic BishopMagics[SQUARE_NB];
|
| 46 |
-
Magic CannonMagicsH[SQUARE_NB];
|
| 47 |
-
Magic CannonMagicsV[SQUARE_NB];
|
| 48 |
-
Magic LameDabbabaMagics[SQUARE_NB];
|
| 49 |
-
Magic HorseMagics[SQUARE_NB];
|
| 50 |
-
Magic ElephantMagics[SQUARE_NB];
|
| 51 |
-
Magic JanggiElephantMagics[SQUARE_NB];
|
| 52 |
-
Magic CannonDiagMagics[SQUARE_NB];
|
| 53 |
-
Magic NightriderMagics[SQUARE_NB];
|
| 54 |
-
Magic GrasshopperMagicsH[SQUARE_NB];
|
| 55 |
-
Magic GrasshopperMagicsV[SQUARE_NB];
|
| 56 |
-
Magic GrasshopperMagicsD[SQUARE_NB];
|
| 57 |
-
|
| 58 |
-
Magic* magics[] = {BishopMagics, RookMagicsH, RookMagicsV, CannonMagicsH, CannonMagicsV,
|
| 59 |
-
LameDabbabaMagics, HorseMagics, ElephantMagics, JanggiElephantMagics, CannonDiagMagics, NightriderMagics,
|
| 60 |
-
GrasshopperMagicsH, GrasshopperMagicsV, GrasshopperMagicsD};
|
| 61 |
-
|
| 62 |
-
namespace {
|
| 63 |
-
|
| 64 |
-
// Some magics need to be split in order to reduce memory consumption.
|
| 65 |
-
// Otherwise on a 12x10 board they can be >100 MB.
|
| 66 |
-
#ifdef LARGEBOARDS
|
| 67 |
-
Bitboard RookTableH[0x11800]; // To store horizontal rook attacks
|
| 68 |
-
Bitboard RookTableV[0x4800]; // To store vertical rook attacks
|
| 69 |
-
Bitboard BishopTable[0x33C00]; // To store bishop attacks
|
| 70 |
-
Bitboard CannonTableH[0x11800]; // To store horizontal cannon attacks
|
| 71 |
-
Bitboard CannonTableV[0x4800]; // To store vertical cannon attacks
|
| 72 |
-
Bitboard LameDabbabaTable[0x500]; // To store lame dabbaba attacks
|
| 73 |
-
Bitboard HorseTable[0x500]; // To store horse attacks
|
| 74 |
-
Bitboard ElephantTable[0x400]; // To store elephant attacks
|
| 75 |
-
Bitboard JanggiElephantTable[0x1C000]; // To store janggi elephant attacks
|
| 76 |
-
Bitboard CannonDiagTable[0x33C00]; // To store diagonal cannon attacks
|
| 77 |
-
Bitboard NightriderTable[0x70200]; // To store nightrider attacks
|
| 78 |
-
Bitboard GrasshopperTableH[0x11800]; // To store horizontal grasshopper attacks
|
| 79 |
-
Bitboard GrasshopperTableV[0x4800]; // To store vertical grasshopper attacks
|
| 80 |
-
Bitboard GrasshopperTableD[0x33C00]; // To store diagonal grasshopper attacks
|
| 81 |
-
#else
|
| 82 |
-
Bitboard RookTableH[0xA00]; // To store horizontal rook attacks
|
| 83 |
-
Bitboard RookTableV[0xA00]; // To store vertical rook attacks
|
| 84 |
-
Bitboard BishopTable[0x1480]; // To store bishop attacks
|
| 85 |
-
Bitboard CannonTableH[0xA00]; // To store horizontal cannon attacks
|
| 86 |
-
Bitboard CannonTableV[0xA00]; // To store vertical cannon attacks
|
| 87 |
-
Bitboard LameDabbabaTable[0x240]; // To store lame dabbaba attacks
|
| 88 |
-
Bitboard HorseTable[0x240]; // To store horse attacks
|
| 89 |
-
Bitboard ElephantTable[0x1A0]; // To store elephant attacks
|
| 90 |
-
Bitboard JanggiElephantTable[0x5C00]; // To store janggi elephant attacks
|
| 91 |
-
Bitboard CannonDiagTable[0x1480]; // To store diagonal cannon attacks
|
| 92 |
-
Bitboard NightriderTable[0x1840]; // To store nightrider attacks
|
| 93 |
-
Bitboard GrasshopperTableH[0xA00]; // To store horizontal grasshopper attacks
|
| 94 |
-
Bitboard GrasshopperTableV[0xA00]; // To store vertical grasshopper attacks
|
| 95 |
-
Bitboard GrasshopperTableD[0x1480]; // To store diagonal grasshopper attacks
|
| 96 |
-
#endif
|
| 97 |
-
|
| 98 |
-
// Rider directions
|
| 99 |
-
const std::map<Direction, int> RookDirectionsV { {NORTH, 0}, {SOUTH, 0}};
|
| 100 |
-
const std::map<Direction, int> RookDirectionsH { {EAST, 0}, {WEST, 0} };
|
| 101 |
-
const std::map<Direction, int> BishopDirections { {NORTH_EAST, 0}, {SOUTH_EAST, 0}, {SOUTH_WEST, 0}, {NORTH_WEST, 0} };
|
| 102 |
-
const std::map<Direction, int> LameDabbabaDirections { {2 * NORTH, 0}, {2 * EAST, 0}, {2 * SOUTH, 0}, {2 * WEST, 0} };
|
| 103 |
-
const std::map<Direction, int> HorseDirections { {2 * SOUTH + WEST, 0}, {2 * SOUTH + EAST, 0}, {SOUTH + 2 * WEST, 0}, {SOUTH + 2 * EAST, 0},
|
| 104 |
-
{NORTH + 2 * WEST, 0}, {NORTH + 2 * EAST, 0}, {2 * NORTH + WEST, 0}, {2 * NORTH + EAST, 0} };
|
| 105 |
-
const std::map<Direction, int> ElephantDirections { {2 * NORTH_EAST, 0}, {2 * SOUTH_EAST, 0}, {2 * SOUTH_WEST, 0}, {2 * NORTH_WEST, 0} };
|
| 106 |
-
const std::map<Direction, int> JanggiElephantDirections { {NORTH + 2 * NORTH_EAST, 0}, {EAST + 2 * NORTH_EAST, 0},
|
| 107 |
-
{EAST + 2 * SOUTH_EAST, 0}, {SOUTH + 2 * SOUTH_EAST, 0},
|
| 108 |
-
{SOUTH + 2 * SOUTH_WEST, 0}, {WEST + 2 * SOUTH_WEST, 0},
|
| 109 |
-
{WEST + 2 * NORTH_WEST, 0}, {NORTH + 2 * NORTH_WEST, 0} };
|
| 110 |
-
const std::map<Direction, int> GrasshopperDirectionsV { {NORTH, 1}, {SOUTH, 1}};
|
| 111 |
-
const std::map<Direction, int> GrasshopperDirectionsH { {EAST, 1}, {WEST, 1} };
|
| 112 |
-
const std::map<Direction, int> GrasshopperDirectionsD { {NORTH_EAST, 1}, {SOUTH_EAST, 1}, {SOUTH_WEST, 1}, {NORTH_WEST, 1} };
|
| 113 |
-
|
| 114 |
-
enum MovementType { RIDER, HOPPER, LAME_LEAPER, HOPPER_RANGE };
|
| 115 |
-
|
| 116 |
-
template <MovementType MT>
|
| 117 |
-
#ifdef PRECOMPUTED_MAGICS
|
| 118 |
-
void init_magics(Bitboard table[], Magic magics[], std::map<Direction, int> directions, const Bitboard magicsInit[]);
|
| 119 |
-
#else
|
| 120 |
-
void init_magics(Bitboard table[], Magic magics[], std::map<Direction, int> directions);
|
| 121 |
-
#endif
|
| 122 |
-
|
| 123 |
-
template <MovementType MT>
|
| 124 |
-
Bitboard sliding_attack(std::map<Direction, int> directions, Square sq, Bitboard occupied, Color c = WHITE) {
|
| 125 |
-
assert(MT != LAME_LEAPER);
|
| 126 |
-
|
| 127 |
-
Bitboard attack = 0;
|
| 128 |
-
|
| 129 |
-
for (auto const& [d, limit] : directions)
|
| 130 |
-
{
|
| 131 |
-
int count = 0;
|
| 132 |
-
bool hurdle = false;
|
| 133 |
-
for (Square s = sq + (c == WHITE ? d : -d);
|
| 134 |
-
is_ok(s) && distance(s, s - (c == WHITE ? d : -d)) <= 2;
|
| 135 |
-
s += (c == WHITE ? d : -d))
|
| 136 |
-
{
|
| 137 |
-
if (MT != HOPPER || hurdle)
|
| 138 |
-
{
|
| 139 |
-
attack |= s;
|
| 140 |
-
// For hoppers we consider limit == 1 as a grasshopper,
|
| 141 |
-
// but limit > 1 as a limited distance hopper
|
| 142 |
-
if (limit && !(MT == HOPPER_RANGE && limit == 1) && ++count >= limit)
|
| 143 |
-
break;
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
if (occupied & s)
|
| 147 |
-
{
|
| 148 |
-
if (MT == HOPPER && !hurdle)
|
| 149 |
-
hurdle = true;
|
| 150 |
-
else
|
| 151 |
-
break;
|
| 152 |
-
}
|
| 153 |
-
}
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
return attack;
|
| 157 |
-
}
|
| 158 |
-
|
| 159 |
-
Bitboard lame_leaper_path(Direction d, Square s) {
|
| 160 |
-
Direction dr = d > 0 ? NORTH : SOUTH;
|
| 161 |
-
Direction df = (std::abs(d % NORTH) < NORTH / 2 ? d % NORTH : -(d % NORTH)) < 0 ? WEST : EAST;
|
| 162 |
-
Square to = s + d;
|
| 163 |
-
Bitboard b = 0;
|
| 164 |
-
if (!is_ok(to) || distance(s, to) >= 4)
|
| 165 |
-
return b;
|
| 166 |
-
while (s != to)
|
| 167 |
-
{
|
| 168 |
-
int diff = std::abs(file_of(to) - file_of(s)) - std::abs(rank_of(to) - rank_of(s));
|
| 169 |
-
if (diff > 0)
|
| 170 |
-
s += df;
|
| 171 |
-
else if (diff < 0)
|
| 172 |
-
s += dr;
|
| 173 |
-
else
|
| 174 |
-
s += df + dr;
|
| 175 |
-
|
| 176 |
-
if (s != to)
|
| 177 |
-
b |= s;
|
| 178 |
-
}
|
| 179 |
-
return b;
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
Bitboard lame_leaper_path(std::map<Direction, int> directions, Square s) {
|
| 183 |
-
Bitboard b = 0;
|
| 184 |
-
for (const auto& i : directions)
|
| 185 |
-
b |= lame_leaper_path(i.first, s);
|
| 186 |
-
return b;
|
| 187 |
-
}
|
| 188 |
-
|
| 189 |
-
Bitboard lame_leaper_attack(std::map<Direction, int> directions, Square s, Bitboard occupied) {
|
| 190 |
-
Bitboard b = 0;
|
| 191 |
-
for (const auto& i : directions)
|
| 192 |
-
{
|
| 193 |
-
Square to = s + i.first;
|
| 194 |
-
if (is_ok(to) && distance(s, to) < 4 && !(lame_leaper_path(i.first, s) & occupied))
|
| 195 |
-
b |= to;
|
| 196 |
-
}
|
| 197 |
-
return b;
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
-
/// safe_destination() returns the bitboard of target square for the given step
|
| 203 |
-
/// from the given square. If the step is off the board, returns empty bitboard.
|
| 204 |
-
|
| 205 |
-
inline Bitboard safe_destination(Square s, int step) {
|
| 206 |
-
Square to = Square(s + step);
|
| 207 |
-
return is_ok(to) && distance(s, to) <= 3 ? square_bb(to) : Bitboard(0);
|
| 208 |
-
}
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
/// Bitboards::pretty() returns an ASCII representation of a bitboard suitable
|
| 212 |
-
/// to be printed to standard output. Useful for debugging.
|
| 213 |
-
|
| 214 |
-
std::string Bitboards::pretty(Bitboard b) {
|
| 215 |
-
|
| 216 |
-
std::string s = "+---+---+---+---+---+---+---+---+---+---+---+---+\n";
|
| 217 |
-
|
| 218 |
-
for (Rank r = RANK_MAX; r >= RANK_1; --r)
|
| 219 |
-
{
|
| 220 |
-
for (File f = FILE_A; f <= FILE_MAX; ++f)
|
| 221 |
-
s += b & make_square(f, r) ? "| X " : "| ";
|
| 222 |
-
|
| 223 |
-
s += "| " + std::to_string(1 + r) + "\n+---+---+---+---+---+---+---+---+---+---+---+---+\n";
|
| 224 |
-
}
|
| 225 |
-
s += " a b c d e f g h i j k l\n";
|
| 226 |
-
|
| 227 |
-
return s;
|
| 228 |
-
}
|
| 229 |
-
|
| 230 |
-
/// Bitboards::init_pieces() initializes piece move/attack bitboards and rider types
|
| 231 |
-
|
| 232 |
-
void Bitboards::init_pieces() {
|
| 233 |
-
|
| 234 |
-
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
| 235 |
-
{
|
| 236 |
-
const PieceInfo* pi = pieceMap.find(pt)->second;
|
| 237 |
-
|
| 238 |
-
// Detect rider types
|
| 239 |
-
for (auto modality : {MODALITY_QUIET, MODALITY_CAPTURE})
|
| 240 |
-
{
|
| 241 |
-
for (bool initial : {false, true})
|
| 242 |
-
{
|
| 243 |
-
// We do not support initial captures
|
| 244 |
-
if (modality == MODALITY_CAPTURE && initial)
|
| 245 |
-
continue;
|
| 246 |
-
auto& riderTypes = modality == MODALITY_CAPTURE ? AttackRiderTypes[pt] : MoveRiderTypes[initial][pt];
|
| 247 |
-
riderTypes = NO_RIDER;
|
| 248 |
-
for (auto const& [d, limit] : pi->steps[initial][modality])
|
| 249 |
-
{
|
| 250 |
-
if (limit && LameDabbabaDirections.find(d) != LameDabbabaDirections.end())
|
| 251 |
-
riderTypes |= RIDER_LAME_DABBABA;
|
| 252 |
-
if (limit && HorseDirections.find(d) != HorseDirections.end())
|
| 253 |
-
riderTypes |= RIDER_HORSE;
|
| 254 |
-
if (limit && ElephantDirections.find(d) != ElephantDirections.end())
|
| 255 |
-
riderTypes |= RIDER_ELEPHANT;
|
| 256 |
-
if (limit && JanggiElephantDirections.find(d) != JanggiElephantDirections.end())
|
| 257 |
-
riderTypes |= RIDER_JANGGI_ELEPHANT;
|
| 258 |
-
}
|
| 259 |
-
for (auto const& [d, limit] : pi->slider[initial][modality])
|
| 260 |
-
{
|
| 261 |
-
if (BishopDirections.find(d) != BishopDirections.end())
|
| 262 |
-
riderTypes |= RIDER_BISHOP;
|
| 263 |
-
if (RookDirectionsH.find(d) != RookDirectionsH.end())
|
| 264 |
-
riderTypes |= RIDER_ROOK_H;
|
| 265 |
-
if (RookDirectionsV.find(d) != RookDirectionsV.end())
|
| 266 |
-
riderTypes |= RIDER_ROOK_V;
|
| 267 |
-
if (HorseDirections.find(d) != HorseDirections.end())
|
| 268 |
-
riderTypes |= RIDER_NIGHTRIDER;
|
| 269 |
-
}
|
| 270 |
-
for (auto const& [d, limit] : pi->hopper[initial][modality])
|
| 271 |
-
{
|
| 272 |
-
if (RookDirectionsH.find(d) != RookDirectionsH.end())
|
| 273 |
-
riderTypes |= limit == 1 ? RIDER_GRASSHOPPER_H : RIDER_CANNON_H;
|
| 274 |
-
if (RookDirectionsV.find(d) != RookDirectionsV.end())
|
| 275 |
-
riderTypes |= limit == 1 ? RIDER_GRASSHOPPER_V : RIDER_CANNON_V;
|
| 276 |
-
if (BishopDirections.find(d) != BishopDirections.end())
|
| 277 |
-
riderTypes |= limit == 1 ? RIDER_GRASSHOPPER_D : RIDER_CANNON_DIAG;
|
| 278 |
-
}
|
| 279 |
-
}
|
| 280 |
-
}
|
| 281 |
-
|
| 282 |
-
// Initialize move/attack bitboards
|
| 283 |
-
for (Color c : { WHITE, BLACK })
|
| 284 |
-
{
|
| 285 |
-
for (Square s = SQ_A1; s <= SQ_MAX; ++s)
|
| 286 |
-
{
|
| 287 |
-
for (auto modality : {MODALITY_QUIET, MODALITY_CAPTURE})
|
| 288 |
-
{
|
| 289 |
-
for (bool initial : {false, true})
|
| 290 |
-
{
|
| 291 |
-
// We do not support initial captures
|
| 292 |
-
if (modality == MODALITY_CAPTURE && initial)
|
| 293 |
-
continue;
|
| 294 |
-
auto& pseudo = modality == MODALITY_CAPTURE ? PseudoAttacks[c][pt][s] : PseudoMoves[initial][c][pt][s];
|
| 295 |
-
auto& leaper = modality == MODALITY_CAPTURE ? LeaperAttacks[c][pt][s] : LeaperMoves[initial][c][pt][s];
|
| 296 |
-
pseudo = 0;
|
| 297 |
-
leaper = 0;
|
| 298 |
-
for (auto const& [d, limit] : pi->steps[initial][modality])
|
| 299 |
-
{
|
| 300 |
-
pseudo |= safe_destination(s, c == WHITE ? d : -d);
|
| 301 |
-
if (!limit)
|
| 302 |
-
leaper |= safe_destination(s, c == WHITE ? d : -d);
|
| 303 |
-
}
|
| 304 |
-
pseudo |= sliding_attack<RIDER>(pi->slider[initial][modality], s, 0, c);
|
| 305 |
-
pseudo |= sliding_attack<HOPPER_RANGE>(pi->hopper[initial][modality], s, 0, c);
|
| 306 |
-
}
|
| 307 |
-
}
|
| 308 |
-
}
|
| 309 |
-
}
|
| 310 |
-
}
|
| 311 |
-
}
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
/// Bitboards::init() initializes various bitboard tables. It is called at
|
| 315 |
-
/// startup and relies on global objects to be already zero-initialized.
|
| 316 |
-
|
| 317 |
-
void Bitboards::init() {
|
| 318 |
-
|
| 319 |
-
for (unsigned i = 0; i < (1 << 16); ++i)
|
| 320 |
-
PopCnt16[i] = uint8_t(std::bitset<16>(i).count());
|
| 321 |
-
|
| 322 |
-
for (Square s = SQ_A1; s <= SQ_MAX; ++s)
|
| 323 |
-
SquareBB[s] = make_bitboard(s);
|
| 324 |
-
|
| 325 |
-
for (File f = FILE_A; f <= FILE_MAX; ++f)
|
| 326 |
-
for (Rank r = RANK_1; r <= RANK_MAX; ++r)
|
| 327 |
-
BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : Bitboard(0));
|
| 328 |
-
|
| 329 |
-
for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
|
| 330 |
-
for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
|
| 331 |
-
SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
|
| 332 |
-
|
| 333 |
-
#ifdef PRECOMPUTED_MAGICS
|
| 334 |
-
init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH, RookMagicHInit);
|
| 335 |
-
init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV, RookMagicVInit);
|
| 336 |
-
init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
|
| 337 |
-
init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH, CannonMagicHInit);
|
| 338 |
-
init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV, CannonMagicVInit);
|
| 339 |
-
init_magics<LAME_LEAPER>(LameDabbabaTable, LameDabbabaMagics, LameDabbabaDirections, LameDabbabaMagicInit);
|
| 340 |
-
init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections, HorseMagicInit);
|
| 341 |
-
init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit);
|
| 342 |
-
init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit);
|
| 343 |
-
init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections, CannonDiagMagicInit);
|
| 344 |
-
init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections, NightriderMagicInit);
|
| 345 |
-
init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH, GrasshopperMagicHInit);
|
| 346 |
-
init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV, GrasshopperMagicVInit);
|
| 347 |
-
init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD, GrasshopperMagicDInit);
|
| 348 |
-
#else
|
| 349 |
-
init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH);
|
| 350 |
-
init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV);
|
| 351 |
-
init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections);
|
| 352 |
-
init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH);
|
| 353 |
-
init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV);
|
| 354 |
-
init_magics<LAME_LEAPER>(LameDabbabaTable, LameDabbabaMagics, LameDabbabaDirections);
|
| 355 |
-
init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections);
|
| 356 |
-
init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections);
|
| 357 |
-
init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections);
|
| 358 |
-
init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections);
|
| 359 |
-
init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections);
|
| 360 |
-
init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH);
|
| 361 |
-
init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV);
|
| 362 |
-
init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD);
|
| 363 |
-
#endif
|
| 364 |
-
|
| 365 |
-
init_pieces();
|
| 366 |
-
|
| 367 |
-
for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
|
| 368 |
-
{
|
| 369 |
-
for (PieceType pt : { BISHOP, ROOK })
|
| 370 |
-
for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
|
| 371 |
-
{
|
| 372 |
-
if (PseudoAttacks[WHITE][pt][s1] & s2)
|
| 373 |
-
{
|
| 374 |
-
LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
|
| 375 |
-
BetweenBB[s1][s2] = (attacks_bb(WHITE, pt, s1, square_bb(s2)) & attacks_bb(WHITE, pt, s2, square_bb(s1)));
|
| 376 |
-
}
|
| 377 |
-
BetweenBB[s1][s2] |= s2;
|
| 378 |
-
}
|
| 379 |
-
}
|
| 380 |
-
}
|
| 381 |
-
|
| 382 |
-
namespace {
|
| 383 |
-
|
| 384 |
-
// init_magics() computes all rook and bishop attacks at startup. Magic
|
| 385 |
-
// bitboards are used to look up attacks of sliding pieces. As a reference see
|
| 386 |
-
// www.chessprogramming.org/Magic_Bitboards. In particular, here we use the so
|
| 387 |
-
// called "fancy" approach.
|
| 388 |
-
|
| 389 |
-
template <MovementType MT>
|
| 390 |
-
#ifdef PRECOMPUTED_MAGICS
|
| 391 |
-
void init_magics(Bitboard table[], Magic magics[], std::map<Direction, int> directions, const Bitboard magicsInit[]) {
|
| 392 |
-
#else
|
| 393 |
-
void init_magics(Bitboard table[], Magic magics[], std::map<Direction, int> directions) {
|
| 394 |
-
#endif
|
| 395 |
-
|
| 396 |
-
// Optimal PRNG seeds to pick the correct magics in the shortest time
|
| 397 |
-
#ifndef PRECOMPUTED_MAGICS
|
| 398 |
-
#ifdef LARGEBOARDS
|
| 399 |
-
int seeds[][RANK_NB] = { { 734, 10316, 55013, 32803, 12281, 15100, 16645, 255, 346, 89123 },
|
| 400 |
-
{ 734, 10316, 55013, 32803, 12281, 15100, 16645, 255, 346, 89123 } };
|
| 401 |
-
#else
|
| 402 |
-
int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998, 5731, 95205, 104912, 17020 },
|
| 403 |
-
{ 728, 10316, 55013, 32803, 12281, 15100, 16645, 255 } };
|
| 404 |
-
#endif
|
| 405 |
-
#endif
|
| 406 |
-
|
| 407 |
-
Bitboard* occupancy = new Bitboard[1 << (FILE_NB + RANK_NB - 4)];
|
| 408 |
-
Bitboard* reference = new Bitboard[1 << (FILE_NB + RANK_NB - 4)];
|
| 409 |
-
Bitboard edges, b;
|
| 410 |
-
int* epoch = new int[1 << (FILE_NB + RANK_NB - 4)]();
|
| 411 |
-
int cnt = 0, size = 0;
|
| 412 |
-
|
| 413 |
-
for (Square s = SQ_A1; s <= SQ_MAX; ++s)
|
| 414 |
-
{
|
| 415 |
-
// Board edges are not considered in the relevant occupancies
|
| 416 |
-
edges = ((Rank1BB | rank_bb(RANK_MAX)) & ~rank_bb(s)) | ((FileABB | file_bb(FILE_MAX)) & ~file_bb(s));
|
| 417 |
-
|
| 418 |
-
// Given a square 's', the mask is the bitboard of sliding attacks from
|
| 419 |
-
// 's' computed on an empty board. The index must be big enough to contain
|
| 420 |
-
// all the attacks for each possible subset of the mask and so is 2 power
|
| 421 |
-
// the number of 1s of the mask. Hence we deduce the size of the shift to
|
| 422 |
-
// apply to the 64 or 32 bits word to get the index.
|
| 423 |
-
Magic& m = magics[s];
|
| 424 |
-
// The mask for hoppers is unlimited distance, even if the hopper is limited distance (e.g., grasshopper)
|
| 425 |
-
m.mask = (MT == LAME_LEAPER ? lame_leaper_path(directions, s) : sliding_attack<MT == HOPPER ? HOPPER_RANGE : MT>(directions, s, 0)) & ~edges;
|
| 426 |
-
#ifdef LARGEBOARDS
|
| 427 |
-
m.shift = 128 - popcount(m.mask);
|
| 428 |
-
#else
|
| 429 |
-
m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask);
|
| 430 |
-
#endif
|
| 431 |
-
|
| 432 |
-
// Set the offset for the attacks table of the square. We have individual
|
| 433 |
-
// table sizes for each square with "Fancy Magic Bitboards".
|
| 434 |
-
m.attacks = s == SQ_A1 ? table : magics[s - 1].attacks + size;
|
| 435 |
-
|
| 436 |
-
// Use Carry-Rippler trick to enumerate all subsets of masks[s] and
|
| 437 |
-
// store the corresponding sliding attack bitboard in reference[].
|
| 438 |
-
b = size = 0;
|
| 439 |
-
do {
|
| 440 |
-
occupancy[size] = b;
|
| 441 |
-
reference[size] = MT == LAME_LEAPER ? lame_leaper_attack(directions, s, b) : sliding_attack<MT>(directions, s, b);
|
| 442 |
-
|
| 443 |
-
if (HasPext)
|
| 444 |
-
m.attacks[pext(b, m.mask)] = reference[size];
|
| 445 |
-
|
| 446 |
-
size++;
|
| 447 |
-
b = (b - m.mask) & m.mask;
|
| 448 |
-
} while (b);
|
| 449 |
-
|
| 450 |
-
if (HasPext)
|
| 451 |
-
continue;
|
| 452 |
-
|
| 453 |
-
#ifndef PRECOMPUTED_MAGICS
|
| 454 |
-
PRNG rng(seeds[Is64Bit][rank_of(s)]);
|
| 455 |
-
#endif
|
| 456 |
-
|
| 457 |
-
// Find a magic for square 's' picking up an (almost) random number
|
| 458 |
-
// until we find the one that passes the verification test.
|
| 459 |
-
for (int i = 0; i < size; )
|
| 460 |
-
{
|
| 461 |
-
for (m.magic = 0; popcount((m.magic * m.mask) >> (SQUARE_NB - FILE_NB)) < FILE_NB - 2; )
|
| 462 |
-
{
|
| 463 |
-
#ifdef LARGEBOARDS
|
| 464 |
-
#ifdef PRECOMPUTED_MAGICS
|
| 465 |
-
m.magic = magicsInit[s];
|
| 466 |
-
#else
|
| 467 |
-
m.magic = (rng.sparse_rand<Bitboard>() << 64) ^ rng.sparse_rand<Bitboard>();
|
| 468 |
-
#endif
|
| 469 |
-
#else
|
| 470 |
-
m.magic = rng.sparse_rand<Bitboard>();
|
| 471 |
-
#endif
|
| 472 |
-
}
|
| 473 |
-
|
| 474 |
-
// A good magic must map every possible occupancy to an index that
|
| 475 |
-
// looks up the correct sliding attack in the attacks[s] database.
|
| 476 |
-
// Note that we build up the database for square 's' as a side
|
| 477 |
-
// effect of verifying the magic. Keep track of the attempt count
|
| 478 |
-
// and save it in epoch[], little speed-up trick to avoid resetting
|
| 479 |
-
// m.attacks[] after every failed attempt.
|
| 480 |
-
for (++cnt, i = 0; i < size; ++i)
|
| 481 |
-
{
|
| 482 |
-
unsigned idx = m.index(occupancy[i]);
|
| 483 |
-
|
| 484 |
-
if (epoch[idx] < cnt)
|
| 485 |
-
{
|
| 486 |
-
epoch[idx] = cnt;
|
| 487 |
-
m.attacks[idx] = reference[i];
|
| 488 |
-
}
|
| 489 |
-
else if (m.attacks[idx] != reference[i])
|
| 490 |
-
break;
|
| 491 |
-
}
|
| 492 |
-
}
|
| 493 |
-
}
|
| 494 |
-
|
| 495 |
-
delete[] occupancy;
|
| 496 |
-
delete[] reference;
|
| 497 |
-
delete[] epoch;
|
| 498 |
-
}
|
| 499 |
-
}
|
| 500 |
-
|
| 501 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/bitboard.h
DELETED
|
@@ -1,787 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef BITBOARD_H_INCLUDED
|
| 20 |
-
#define BITBOARD_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <string>
|
| 23 |
-
|
| 24 |
-
#include "types.h"
|
| 25 |
-
|
| 26 |
-
namespace Stockfish {
|
| 27 |
-
|
| 28 |
-
namespace Bitbases {
|
| 29 |
-
|
| 30 |
-
void init();
|
| 31 |
-
bool probe(Square wksq, Square wpsq, Square bksq, Color us);
|
| 32 |
-
|
| 33 |
-
} // namespace Stockfish::Bitbases
|
| 34 |
-
|
| 35 |
-
namespace Bitboards {
|
| 36 |
-
|
| 37 |
-
void init_pieces();
|
| 38 |
-
void init();
|
| 39 |
-
std::string pretty(Bitboard b);
|
| 40 |
-
|
| 41 |
-
} // namespace Stockfish::Bitboards
|
| 42 |
-
|
| 43 |
-
#ifdef LARGEBOARDS
|
| 44 |
-
constexpr Bitboard AllSquares = ((~Bitboard(0)) >> 8);
|
| 45 |
-
#else
|
| 46 |
-
constexpr Bitboard AllSquares = ~Bitboard(0);
|
| 47 |
-
#endif
|
| 48 |
-
#ifdef LARGEBOARDS
|
| 49 |
-
constexpr Bitboard DarkSquares = (Bitboard(0xAAA555AAA555AAULL) << 64) ^ Bitboard(0xA555AAA555AAA555ULL);
|
| 50 |
-
#else
|
| 51 |
-
constexpr Bitboard DarkSquares = 0xAA55AA55AA55AA55ULL;
|
| 52 |
-
#endif
|
| 53 |
-
|
| 54 |
-
#ifdef LARGEBOARDS
|
| 55 |
-
constexpr Bitboard FileABB = (Bitboard(0x00100100100100ULL) << 64) ^ Bitboard(0x1001001001001001ULL);
|
| 56 |
-
#else
|
| 57 |
-
constexpr Bitboard FileABB = 0x0101010101010101ULL;
|
| 58 |
-
#endif
|
| 59 |
-
constexpr Bitboard FileBBB = FileABB << 1;
|
| 60 |
-
constexpr Bitboard FileCBB = FileABB << 2;
|
| 61 |
-
constexpr Bitboard FileDBB = FileABB << 3;
|
| 62 |
-
constexpr Bitboard FileEBB = FileABB << 4;
|
| 63 |
-
constexpr Bitboard FileFBB = FileABB << 5;
|
| 64 |
-
constexpr Bitboard FileGBB = FileABB << 6;
|
| 65 |
-
constexpr Bitboard FileHBB = FileABB << 7;
|
| 66 |
-
#ifdef LARGEBOARDS
|
| 67 |
-
constexpr Bitboard FileIBB = FileABB << 8;
|
| 68 |
-
constexpr Bitboard FileJBB = FileABB << 9;
|
| 69 |
-
constexpr Bitboard FileKBB = FileABB << 10;
|
| 70 |
-
constexpr Bitboard FileLBB = FileABB << 11;
|
| 71 |
-
#endif
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
#ifdef LARGEBOARDS
|
| 75 |
-
constexpr Bitboard Rank1BB = 0xFFF;
|
| 76 |
-
#else
|
| 77 |
-
constexpr Bitboard Rank1BB = 0xFF;
|
| 78 |
-
#endif
|
| 79 |
-
constexpr Bitboard Rank2BB = Rank1BB << (FILE_NB * 1);
|
| 80 |
-
constexpr Bitboard Rank3BB = Rank1BB << (FILE_NB * 2);
|
| 81 |
-
constexpr Bitboard Rank4BB = Rank1BB << (FILE_NB * 3);
|
| 82 |
-
constexpr Bitboard Rank5BB = Rank1BB << (FILE_NB * 4);
|
| 83 |
-
constexpr Bitboard Rank6BB = Rank1BB << (FILE_NB * 5);
|
| 84 |
-
constexpr Bitboard Rank7BB = Rank1BB << (FILE_NB * 6);
|
| 85 |
-
constexpr Bitboard Rank8BB = Rank1BB << (FILE_NB * 7);
|
| 86 |
-
#ifdef LARGEBOARDS
|
| 87 |
-
constexpr Bitboard Rank9BB = Rank1BB << (FILE_NB * 8);
|
| 88 |
-
constexpr Bitboard Rank10BB = Rank1BB << (FILE_NB * 9);
|
| 89 |
-
#endif
|
| 90 |
-
|
| 91 |
-
constexpr Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB;
|
| 92 |
-
constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
|
| 93 |
-
constexpr Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB;
|
| 94 |
-
constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
|
| 95 |
-
|
| 96 |
-
constexpr Bitboard KingFlank[FILE_NB] = {
|
| 97 |
-
QueenSide ^ FileDBB, QueenSide, QueenSide,
|
| 98 |
-
CenterFiles, CenterFiles,
|
| 99 |
-
KingSide, KingSide, KingSide ^ FileEBB
|
| 100 |
-
};
|
| 101 |
-
|
| 102 |
-
extern uint8_t PopCnt16[1 << 16];
|
| 103 |
-
extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
|
| 104 |
-
|
| 105 |
-
extern Bitboard SquareBB[SQUARE_NB];
|
| 106 |
-
extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
|
| 107 |
-
extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
|
| 108 |
-
extern Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 109 |
-
extern Bitboard PseudoMoves[2][COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 110 |
-
extern Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 111 |
-
extern Bitboard LeaperMoves[2][COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
| 112 |
-
extern Bitboard SquareBB[SQUARE_NB];
|
| 113 |
-
extern Bitboard BoardSizeBB[FILE_NB][RANK_NB];
|
| 114 |
-
extern RiderType AttackRiderTypes[PIECE_TYPE_NB];
|
| 115 |
-
extern RiderType MoveRiderTypes[2][PIECE_TYPE_NB];
|
| 116 |
-
|
| 117 |
-
#ifdef LARGEBOARDS
|
| 118 |
-
int popcount(Bitboard b); // required for 128 bit pext
|
| 119 |
-
#endif
|
| 120 |
-
|
| 121 |
-
/// Magic holds all magic bitboards relevant data for a single square
|
| 122 |
-
struct Magic {
|
| 123 |
-
Bitboard mask;
|
| 124 |
-
Bitboard magic;
|
| 125 |
-
Bitboard* attacks;
|
| 126 |
-
unsigned shift;
|
| 127 |
-
|
| 128 |
-
// Compute the attack's index using the 'magic bitboards' approach
|
| 129 |
-
unsigned index(Bitboard occupied) const {
|
| 130 |
-
|
| 131 |
-
if (HasPext)
|
| 132 |
-
return unsigned(pext(occupied, mask));
|
| 133 |
-
|
| 134 |
-
#ifdef LARGEBOARDS
|
| 135 |
-
return unsigned(((occupied & mask) * magic) >> shift);
|
| 136 |
-
#else
|
| 137 |
-
if (Is64Bit)
|
| 138 |
-
return unsigned(((occupied & mask) * magic) >> shift);
|
| 139 |
-
#endif
|
| 140 |
-
|
| 141 |
-
unsigned lo = unsigned(occupied) & unsigned(mask);
|
| 142 |
-
unsigned hi = unsigned(occupied >> 32) & unsigned(mask >> 32);
|
| 143 |
-
return (lo * unsigned(magic) ^ hi * unsigned(magic >> 32)) >> shift;
|
| 144 |
-
}
|
| 145 |
-
};
|
| 146 |
-
|
| 147 |
-
extern Magic RookMagicsH[SQUARE_NB];
|
| 148 |
-
extern Magic RookMagicsV[SQUARE_NB];
|
| 149 |
-
extern Magic BishopMagics[SQUARE_NB];
|
| 150 |
-
extern Magic CannonMagicsH[SQUARE_NB];
|
| 151 |
-
extern Magic CannonMagicsV[SQUARE_NB];
|
| 152 |
-
extern Magic LameDabbabaMagics[SQUARE_NB];
|
| 153 |
-
extern Magic HorseMagics[SQUARE_NB];
|
| 154 |
-
extern Magic ElephantMagics[SQUARE_NB];
|
| 155 |
-
extern Magic JanggiElephantMagics[SQUARE_NB];
|
| 156 |
-
extern Magic CannonDiagMagics[SQUARE_NB];
|
| 157 |
-
extern Magic NightriderMagics[SQUARE_NB];
|
| 158 |
-
extern Magic GrasshopperMagicsH[SQUARE_NB];
|
| 159 |
-
extern Magic GrasshopperMagicsV[SQUARE_NB];
|
| 160 |
-
extern Magic GrasshopperMagicsD[SQUARE_NB];
|
| 161 |
-
|
| 162 |
-
extern Magic* magics[];
|
| 163 |
-
|
| 164 |
-
constexpr Bitboard make_bitboard() { return 0; }
|
| 165 |
-
|
| 166 |
-
template<typename ...Squares>
|
| 167 |
-
constexpr Bitboard make_bitboard(Square s, Squares... squares) {
|
| 168 |
-
return (Bitboard(1) << s) | make_bitboard(squares...);
|
| 169 |
-
}
|
| 170 |
-
|
| 171 |
-
inline Bitboard square_bb(Square s) {
|
| 172 |
-
assert(is_ok(s));
|
| 173 |
-
return SquareBB[s];
|
| 174 |
-
}
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
/// Overloads of bitwise operators between a Bitboard and a Square for testing
|
| 178 |
-
/// whether a given bit is set in a bitboard, and for setting and clearing bits.
|
| 179 |
-
|
| 180 |
-
inline Bitboard operator&( Bitboard b, Square s) { return b & square_bb(s); }
|
| 181 |
-
inline Bitboard operator|( Bitboard b, Square s) { return b | square_bb(s); }
|
| 182 |
-
inline Bitboard operator^( Bitboard b, Square s) { return b ^ square_bb(s); }
|
| 183 |
-
inline Bitboard& operator|=(Bitboard& b, Square s) { return b |= square_bb(s); }
|
| 184 |
-
inline Bitboard& operator^=(Bitboard& b, Square s) { return b ^= square_bb(s); }
|
| 185 |
-
|
| 186 |
-
inline Bitboard operator-( Bitboard b, Square s) { return b & ~square_bb(s); }
|
| 187 |
-
inline Bitboard& operator-=(Bitboard& b, Square s) { return b &= ~square_bb(s); }
|
| 188 |
-
|
| 189 |
-
inline Bitboard operator&(Square s, Bitboard b) { return b & s; }
|
| 190 |
-
inline Bitboard operator|(Square s, Bitboard b) { return b | s; }
|
| 191 |
-
inline Bitboard operator^(Square s, Bitboard b) { return b ^ s; }
|
| 192 |
-
|
| 193 |
-
inline Bitboard operator|(Square s1, Square s2) { return square_bb(s1) | s2; }
|
| 194 |
-
|
| 195 |
-
constexpr bool more_than_one(Bitboard b) {
|
| 196 |
-
return b & (b - 1);
|
| 197 |
-
}
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
inline Bitboard undo_move_board(Bitboard b, Move m) {
|
| 201 |
-
return (from_sq(m) != SQ_NONE && (b & to_sq(m))) ? (b ^ to_sq(m)) | from_sq(m) : b;
|
| 202 |
-
}
|
| 203 |
-
|
| 204 |
-
/// board_size_bb() returns a bitboard representing all the squares
|
| 205 |
-
/// on a board with given size.
|
| 206 |
-
|
| 207 |
-
inline Bitboard board_size_bb(File f, Rank r) {
|
| 208 |
-
return BoardSizeBB[f][r];
|
| 209 |
-
}
|
| 210 |
-
|
| 211 |
-
constexpr bool opposite_colors(Square s1, Square s2) {
|
| 212 |
-
return (s1 + rank_of(s1) + s2 + rank_of(s2)) & 1;
|
| 213 |
-
}
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
/// rank_bb() and file_bb() return a bitboard representing all the squares on
|
| 217 |
-
/// the given file or rank.
|
| 218 |
-
|
| 219 |
-
constexpr Bitboard rank_bb(Rank r) {
|
| 220 |
-
return Rank1BB << (FILE_NB * r);
|
| 221 |
-
}
|
| 222 |
-
|
| 223 |
-
constexpr Bitboard rank_bb(Square s) {
|
| 224 |
-
return rank_bb(rank_of(s));
|
| 225 |
-
}
|
| 226 |
-
|
| 227 |
-
constexpr Bitboard file_bb(File f) {
|
| 228 |
-
return FileABB << f;
|
| 229 |
-
}
|
| 230 |
-
|
| 231 |
-
constexpr Bitboard file_bb(Square s) {
|
| 232 |
-
return file_bb(file_of(s));
|
| 233 |
-
}
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
/// shift() moves a bitboard one or two steps as specified by the direction D
|
| 237 |
-
|
| 238 |
-
template<Direction D>
|
| 239 |
-
constexpr Bitboard shift(Bitboard b) {
|
| 240 |
-
return D == NORTH ? b << NORTH : D == SOUTH ? b >> NORTH
|
| 241 |
-
: D == NORTH+NORTH? b <<(2 * NORTH) : D == SOUTH+SOUTH? b >> (2 * NORTH)
|
| 242 |
-
: D == EAST ? (b & ~file_bb(FILE_MAX)) << EAST : D == WEST ? (b & ~FileABB) >> EAST
|
| 243 |
-
: D == NORTH_EAST ? (b & ~file_bb(FILE_MAX)) << NORTH_EAST : D == NORTH_WEST ? (b & ~FileABB) << NORTH_WEST
|
| 244 |
-
: D == SOUTH_EAST ? (b & ~file_bb(FILE_MAX)) >> NORTH_WEST : D == SOUTH_WEST ? (b & ~FileABB) >> NORTH_EAST
|
| 245 |
-
: Bitboard(0);
|
| 246 |
-
}
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
/// shift() moves a bitboard one step along direction D (mainly for pawns)
|
| 250 |
-
|
| 251 |
-
constexpr Bitboard shift(Direction D, Bitboard b) {
|
| 252 |
-
return D == NORTH ? b << NORTH : D == SOUTH ? b >> NORTH
|
| 253 |
-
: D == NORTH+NORTH? b <<(2 * NORTH) : D == SOUTH+SOUTH? b >> (2 * NORTH)
|
| 254 |
-
: D == EAST ? (b & ~file_bb(FILE_MAX)) << EAST : D == WEST ? (b & ~FileABB) >> EAST
|
| 255 |
-
: D == NORTH_EAST ? (b & ~file_bb(FILE_MAX)) << NORTH_EAST : D == NORTH_WEST ? (b & ~FileABB) << NORTH_WEST
|
| 256 |
-
: D == SOUTH_EAST ? (b & ~file_bb(FILE_MAX)) >> NORTH_WEST : D == SOUTH_WEST ? (b & ~FileABB) >> NORTH_EAST
|
| 257 |
-
: Bitboard(0);
|
| 258 |
-
}
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
/// pawn_attacks_bb() returns the squares attacked by pawns of the given color
|
| 262 |
-
/// from the squares in the given bitboard.
|
| 263 |
-
|
| 264 |
-
template<Color C>
|
| 265 |
-
constexpr Bitboard pawn_attacks_bb(Bitboard b) {
|
| 266 |
-
return C == WHITE ? shift<NORTH_WEST>(b) | shift<NORTH_EAST>(b)
|
| 267 |
-
: shift<SOUTH_WEST>(b) | shift<SOUTH_EAST>(b);
|
| 268 |
-
}
|
| 269 |
-
|
| 270 |
-
inline Bitboard pawn_attacks_bb(Color c, Square s) {
|
| 271 |
-
|
| 272 |
-
assert(is_ok(s));
|
| 273 |
-
return PseudoAttacks[c][PAWN][s];
|
| 274 |
-
}
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
/// pawn_double_attacks_bb() returns the squares doubly attacked by pawns of the
|
| 278 |
-
/// given color from the squares in the given bitboard.
|
| 279 |
-
|
| 280 |
-
template<Color C>
|
| 281 |
-
constexpr Bitboard pawn_double_attacks_bb(Bitboard b) {
|
| 282 |
-
return C == WHITE ? shift<NORTH_WEST>(b) & shift<NORTH_EAST>(b)
|
| 283 |
-
: shift<SOUTH_WEST>(b) & shift<SOUTH_EAST>(b);
|
| 284 |
-
}
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
/// adjacent_files_bb() returns a bitboard representing all the squares on the
|
| 288 |
-
/// adjacent files of a given square.
|
| 289 |
-
|
| 290 |
-
constexpr Bitboard adjacent_files_bb(Square s) {
|
| 291 |
-
return shift<EAST>(file_bb(s)) | shift<WEST>(file_bb(s));
|
| 292 |
-
}
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
/// line_bb() returns a bitboard representing an entire line (from board edge
|
| 296 |
-
/// to board edge) that intersects the two given squares. If the given squares
|
| 297 |
-
/// are not on a same file/rank/diagonal, the function returns 0. For instance,
|
| 298 |
-
/// line_bb(SQ_C4, SQ_F7) will return a bitboard with the A2-G8 diagonal.
|
| 299 |
-
|
| 300 |
-
inline Bitboard line_bb(Square s1, Square s2) {
|
| 301 |
-
|
| 302 |
-
assert(is_ok(s1) && is_ok(s2));
|
| 303 |
-
|
| 304 |
-
return LineBB[s1][s2];
|
| 305 |
-
}
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
/// between_bb(s1, s2) returns a bitboard representing the squares in the semi-open
|
| 309 |
-
/// segment between the squares s1 and s2 (excluding s1 but including s2). If the
|
| 310 |
-
/// given squares are not on a same file/rank/diagonal, it returns s2. For instance,
|
| 311 |
-
/// between_bb(SQ_C4, SQ_F7) will return a bitboard with squares D5, E6 and F7, but
|
| 312 |
-
/// between_bb(SQ_E6, SQ_F8) will return a bitboard with the square F8. This trick
|
| 313 |
-
/// allows to generate non-king evasion moves faster: the defending piece must either
|
| 314 |
-
/// interpose itself to cover the check or capture the checking piece.
|
| 315 |
-
|
| 316 |
-
inline Bitboard between_bb(Square s1, Square s2) {
|
| 317 |
-
|
| 318 |
-
assert(is_ok(s1) && is_ok(s2));
|
| 319 |
-
|
| 320 |
-
return BetweenBB[s1][s2];
|
| 321 |
-
}
|
| 322 |
-
|
| 323 |
-
inline Bitboard between_bb(Square s1, Square s2, PieceType pt) {
|
| 324 |
-
if (pt == HORSE)
|
| 325 |
-
return PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][FERS][s1];
|
| 326 |
-
else if (pt == JANGGI_ELEPHANT)
|
| 327 |
-
return (PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][ALFIL][s1])
|
| 328 |
-
| (PseudoAttacks[WHITE][KNIGHT][s2] & PseudoAttacks[WHITE][FERS][s1]);
|
| 329 |
-
else
|
| 330 |
-
return between_bb(s1, s2);
|
| 331 |
-
}
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
/// forward_ranks_bb() returns a bitboard representing the squares on the ranks in
|
| 335 |
-
/// front of the given one, from the point of view of the given color. For instance,
|
| 336 |
-
/// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2.
|
| 337 |
-
|
| 338 |
-
constexpr Bitboard forward_ranks_bb(Color c, Square s) {
|
| 339 |
-
return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * relative_rank(WHITE, s, RANK_MAX)
|
| 340 |
-
: (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * relative_rank(BLACK, s, RANK_MAX);
|
| 341 |
-
}
|
| 342 |
-
|
| 343 |
-
constexpr Bitboard forward_ranks_bb(Color c, Rank r) {
|
| 344 |
-
return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * (r - RANK_1)
|
| 345 |
-
: (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * (RANK_MAX - r);
|
| 346 |
-
}
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
/// zone_bb() returns a bitboard representing the squares on all the ranks
|
| 350 |
-
/// in front of and on the given relative rank, from the point of view of the given color.
|
| 351 |
-
/// For instance, zone_bb(BLACK, RANK_7) will return the 16 squares on ranks 1 and 2.
|
| 352 |
-
|
| 353 |
-
inline Bitboard zone_bb(Color c, Rank r, Rank maxRank) {
|
| 354 |
-
return forward_ranks_bb(c, relative_rank(c, r, maxRank)) | rank_bb(relative_rank(c, r, maxRank));
|
| 355 |
-
}
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
/// forward_file_bb() returns a bitboard representing all the squares along the
|
| 359 |
-
/// line in front of the given one, from the point of view of the given color.
|
| 360 |
-
|
| 361 |
-
constexpr Bitboard forward_file_bb(Color c, Square s) {
|
| 362 |
-
return forward_ranks_bb(c, s) & file_bb(s);
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
/// pawn_attack_span() returns a bitboard representing all the squares that can
|
| 367 |
-
/// be attacked by a pawn of the given color when it moves along its file, starting
|
| 368 |
-
/// from the given square.
|
| 369 |
-
|
| 370 |
-
constexpr Bitboard pawn_attack_span(Color c, Square s) {
|
| 371 |
-
return forward_ranks_bb(c, s) & adjacent_files_bb(s);
|
| 372 |
-
}
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
/// passed_pawn_span() returns a bitboard which can be used to test if a pawn of
|
| 376 |
-
/// the given color and on the given square is a passed pawn.
|
| 377 |
-
|
| 378 |
-
constexpr Bitboard passed_pawn_span(Color c, Square s) {
|
| 379 |
-
return pawn_attack_span(c, s) | forward_file_bb(c, s);
|
| 380 |
-
}
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
/// aligned() returns true if the squares s1, s2 and s3 are aligned either on a
|
| 384 |
-
/// straight or on a diagonal line.
|
| 385 |
-
|
| 386 |
-
inline bool aligned(Square s1, Square s2, Square s3) {
|
| 387 |
-
return line_bb(s1, s2) & s3;
|
| 388 |
-
}
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
/// distance() functions return the distance between x and y, defined as the
|
| 392 |
-
/// number of steps for a king in x to reach y.
|
| 393 |
-
|
| 394 |
-
template<typename T1 = Square> inline int distance(Square x, Square y);
|
| 395 |
-
template<> inline int distance<File>(Square x, Square y) { return std::abs(file_of(x) - file_of(y)); }
|
| 396 |
-
template<> inline int distance<Rank>(Square x, Square y) { return std::abs(rank_of(x) - rank_of(y)); }
|
| 397 |
-
template<> inline int distance<Square>(Square x, Square y) { return SquareDistance[x][y]; }
|
| 398 |
-
|
| 399 |
-
inline int edge_distance(File f, File maxFile = FILE_H) { return std::min(f, File(maxFile - f)); }
|
| 400 |
-
inline int edge_distance(Rank r, Rank maxRank = RANK_8) { return std::min(r, Rank(maxRank - r)); }
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
template<RiderType R>
|
| 404 |
-
inline Bitboard rider_attacks_bb(Square s, Bitboard occupied) {
|
| 405 |
-
|
| 406 |
-
static_assert(R != NO_RIDER && !(R & (R - 1))); // exactly one bit
|
| 407 |
-
const Magic& m = R == RIDER_ROOK_H ? RookMagicsH[s]
|
| 408 |
-
: R == RIDER_ROOK_V ? RookMagicsV[s]
|
| 409 |
-
: R == RIDER_CANNON_H ? CannonMagicsH[s]
|
| 410 |
-
: R == RIDER_CANNON_V ? CannonMagicsV[s]
|
| 411 |
-
: R == RIDER_LAME_DABBABA ? LameDabbabaMagics[s]
|
| 412 |
-
: R == RIDER_HORSE ? HorseMagics[s]
|
| 413 |
-
: R == RIDER_ELEPHANT ? ElephantMagics[s]
|
| 414 |
-
: R == RIDER_JANGGI_ELEPHANT ? JanggiElephantMagics[s]
|
| 415 |
-
: R == RIDER_CANNON_DIAG ? CannonDiagMagics[s]
|
| 416 |
-
: R == RIDER_NIGHTRIDER ? NightriderMagics[s]
|
| 417 |
-
: R == RIDER_GRASSHOPPER_H ? GrasshopperMagicsH[s]
|
| 418 |
-
: R == RIDER_GRASSHOPPER_V ? GrasshopperMagicsV[s]
|
| 419 |
-
: R == RIDER_GRASSHOPPER_D ? GrasshopperMagicsD[s]
|
| 420 |
-
: BishopMagics[s];
|
| 421 |
-
return m.attacks[m.index(occupied)];
|
| 422 |
-
}
|
| 423 |
-
|
| 424 |
-
inline Square lsb(Bitboard b);
|
| 425 |
-
|
| 426 |
-
inline Bitboard rider_attacks_bb(RiderType R, Square s, Bitboard occupied) {
|
| 427 |
-
|
| 428 |
-
assert(R != NO_RIDER && !(R & (R - 1))); // exactly one bit
|
| 429 |
-
const Magic& m = magics[lsb(R)][s]; // re-use Bitboard lsb for riders
|
| 430 |
-
return m.attacks[m.index(occupied)];
|
| 431 |
-
}
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
/// attacks_bb(Square) returns the pseudo attacks of the give piece type
|
| 435 |
-
/// assuming an empty board.
|
| 436 |
-
|
| 437 |
-
template<PieceType Pt>
|
| 438 |
-
inline Bitboard attacks_bb(Square s) {
|
| 439 |
-
|
| 440 |
-
assert((Pt != PAWN) && (is_ok(s)));
|
| 441 |
-
|
| 442 |
-
return PseudoAttacks[WHITE][Pt][s];
|
| 443 |
-
}
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
/// attacks_bb(Square, Bitboard) returns the attacks by the given piece
|
| 447 |
-
/// assuming the board is occupied according to the passed Bitboard.
|
| 448 |
-
/// Sliding piece attacks do not continue passed an occupied square.
|
| 449 |
-
|
| 450 |
-
template<PieceType Pt>
|
| 451 |
-
inline Bitboard attacks_bb(Square s, Bitboard occupied) {
|
| 452 |
-
|
| 453 |
-
assert((Pt != PAWN) && (is_ok(s)));
|
| 454 |
-
|
| 455 |
-
switch (Pt)
|
| 456 |
-
{
|
| 457 |
-
case BISHOP: return rider_attacks_bb<RIDER_BISHOP>(s, occupied);
|
| 458 |
-
case ROOK : return rider_attacks_bb<RIDER_ROOK_H>(s, occupied) | rider_attacks_bb<RIDER_ROOK_V>(s, occupied);
|
| 459 |
-
case QUEEN : return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
|
| 460 |
-
default : return PseudoAttacks[WHITE][Pt][s];
|
| 461 |
-
}
|
| 462 |
-
}
|
| 463 |
-
|
| 464 |
-
/// pop_rider() finds and clears a rider in a (hybrid) rider type
|
| 465 |
-
|
| 466 |
-
inline RiderType pop_rider(RiderType* r) {
|
| 467 |
-
assert(*r);
|
| 468 |
-
const RiderType r2 = *r & ~(*r - 1);
|
| 469 |
-
*r &= *r - 1;
|
| 470 |
-
return r2;
|
| 471 |
-
}
|
| 472 |
-
|
| 473 |
-
inline Bitboard attacks_bb(Color c, PieceType pt, Square s, Bitboard occupied) {
|
| 474 |
-
Bitboard b = LeaperAttacks[c][pt][s];
|
| 475 |
-
RiderType r = AttackRiderTypes[pt];
|
| 476 |
-
while (r)
|
| 477 |
-
b |= rider_attacks_bb(pop_rider(&r), s, occupied);
|
| 478 |
-
return b & PseudoAttacks[c][pt][s];
|
| 479 |
-
}
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
template <bool Initial=false>
|
| 483 |
-
inline Bitboard moves_bb(Color c, PieceType pt, Square s, Bitboard occupied) {
|
| 484 |
-
Bitboard b = LeaperMoves[Initial][c][pt][s];
|
| 485 |
-
RiderType r = MoveRiderTypes[Initial][pt];
|
| 486 |
-
while (r)
|
| 487 |
-
b |= rider_attacks_bb(pop_rider(&r), s, occupied);
|
| 488 |
-
return b & PseudoMoves[Initial][c][pt][s];
|
| 489 |
-
}
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
/// popcount() counts the number of non-zero bits in a bitboard
|
| 493 |
-
|
| 494 |
-
inline int popcount(Bitboard b) {
|
| 495 |
-
|
| 496 |
-
#ifndef USE_POPCNT
|
| 497 |
-
|
| 498 |
-
#ifdef LARGEBOARDS
|
| 499 |
-
union { Bitboard bb; uint16_t u[8]; } v = { b };
|
| 500 |
-
return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]]
|
| 501 |
-
+ PopCnt16[v.u[4]] + PopCnt16[v.u[5]] + PopCnt16[v.u[6]] + PopCnt16[v.u[7]];
|
| 502 |
-
#else
|
| 503 |
-
union { Bitboard bb; uint16_t u[4]; } v = { b };
|
| 504 |
-
return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]];
|
| 505 |
-
#endif
|
| 506 |
-
|
| 507 |
-
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
| 508 |
-
|
| 509 |
-
#ifdef LARGEBOARDS
|
| 510 |
-
return (int)_mm_popcnt_u64(uint64_t(b >> 64)) + (int)_mm_popcnt_u64(uint64_t(b));
|
| 511 |
-
#else
|
| 512 |
-
return (int)_mm_popcnt_u64(b);
|
| 513 |
-
#endif
|
| 514 |
-
|
| 515 |
-
#else // Assumed gcc or compatible compiler
|
| 516 |
-
|
| 517 |
-
#ifdef LARGEBOARDS
|
| 518 |
-
return __builtin_popcountll(b >> 64) + __builtin_popcountll(b);
|
| 519 |
-
#else
|
| 520 |
-
return __builtin_popcountll(b);
|
| 521 |
-
#endif
|
| 522 |
-
|
| 523 |
-
#endif
|
| 524 |
-
}
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
/// lsb() and msb() return the least/most significant bit in a non-zero bitboard
|
| 528 |
-
|
| 529 |
-
#if defined(__GNUC__) // GCC, Clang, ICC
|
| 530 |
-
|
| 531 |
-
inline Square lsb(Bitboard b) {
|
| 532 |
-
assert(b);
|
| 533 |
-
#ifdef LARGEBOARDS
|
| 534 |
-
if (!(b << 64))
|
| 535 |
-
return Square(__builtin_ctzll(b >> 64) + 64);
|
| 536 |
-
#endif
|
| 537 |
-
return Square(__builtin_ctzll(b));
|
| 538 |
-
}
|
| 539 |
-
|
| 540 |
-
inline Square msb(Bitboard b) {
|
| 541 |
-
assert(b);
|
| 542 |
-
#ifdef LARGEBOARDS
|
| 543 |
-
if (b >> 64)
|
| 544 |
-
return Square(int(SQUARE_BIT_MASK) ^ __builtin_clzll(b >> 64));
|
| 545 |
-
return Square(int(SQUARE_BIT_MASK) ^ (__builtin_clzll(b) + 64));
|
| 546 |
-
#else
|
| 547 |
-
return Square(int(SQUARE_BIT_MASK) ^ __builtin_clzll(b));
|
| 548 |
-
#endif
|
| 549 |
-
}
|
| 550 |
-
|
| 551 |
-
#elif defined(_MSC_VER) // MSVC
|
| 552 |
-
|
| 553 |
-
#ifdef _WIN64 // MSVC, WIN64
|
| 554 |
-
|
| 555 |
-
inline Square lsb(Bitboard b) {
|
| 556 |
-
assert(b);
|
| 557 |
-
unsigned long idx;
|
| 558 |
-
#ifdef LARGEBOARDS
|
| 559 |
-
if (uint64_t(b))
|
| 560 |
-
{
|
| 561 |
-
_BitScanForward64(&idx, uint64_t(b));
|
| 562 |
-
return Square(idx);
|
| 563 |
-
}
|
| 564 |
-
else
|
| 565 |
-
{
|
| 566 |
-
_BitScanForward64(&idx, uint64_t(b >> 64));
|
| 567 |
-
return Square(idx + 64);
|
| 568 |
-
}
|
| 569 |
-
#else
|
| 570 |
-
_BitScanForward64(&idx, b);
|
| 571 |
-
return (Square) idx;
|
| 572 |
-
#endif
|
| 573 |
-
}
|
| 574 |
-
|
| 575 |
-
inline Square msb(Bitboard b) {
|
| 576 |
-
assert(b);
|
| 577 |
-
unsigned long idx;
|
| 578 |
-
#ifdef LARGEBOARDS
|
| 579 |
-
if (b >> 64)
|
| 580 |
-
{
|
| 581 |
-
_BitScanReverse64(&idx, uint64_t(b >> 64));
|
| 582 |
-
return Square(idx + 64);
|
| 583 |
-
}
|
| 584 |
-
else
|
| 585 |
-
{
|
| 586 |
-
_BitScanReverse64(&idx, uint64_t(b));
|
| 587 |
-
return Square(idx);
|
| 588 |
-
}
|
| 589 |
-
#else
|
| 590 |
-
_BitScanReverse64(&idx, b);
|
| 591 |
-
return (Square) idx;
|
| 592 |
-
#endif
|
| 593 |
-
}
|
| 594 |
-
|
| 595 |
-
#else // MSVC, WIN32
|
| 596 |
-
|
| 597 |
-
inline Square lsb(Bitboard b) {
|
| 598 |
-
assert(b);
|
| 599 |
-
unsigned long idx;
|
| 600 |
-
|
| 601 |
-
#ifdef LARGEBOARDS
|
| 602 |
-
if (b << 96) {
|
| 603 |
-
_BitScanForward(&idx, uint32_t(b));
|
| 604 |
-
return Square(idx);
|
| 605 |
-
} else if (b << 64) {
|
| 606 |
-
_BitScanForward(&idx, uint32_t(b >> 32));
|
| 607 |
-
return Square(idx + 32);
|
| 608 |
-
} else if (b << 32) {
|
| 609 |
-
_BitScanForward(&idx, uint32_t(b >> 64));
|
| 610 |
-
return Square(idx + 64);
|
| 611 |
-
} else {
|
| 612 |
-
_BitScanForward(&idx, uint32_t(b >> 96));
|
| 613 |
-
return Square(idx + 96);
|
| 614 |
-
}
|
| 615 |
-
#else
|
| 616 |
-
if (b & 0xffffffff) {
|
| 617 |
-
_BitScanForward(&idx, uint32_t(b));
|
| 618 |
-
return Square(idx);
|
| 619 |
-
} else {
|
| 620 |
-
_BitScanForward(&idx, uint32_t(b >> 32));
|
| 621 |
-
return Square(idx + 32);
|
| 622 |
-
}
|
| 623 |
-
#endif
|
| 624 |
-
}
|
| 625 |
-
|
| 626 |
-
inline Square msb(Bitboard b) {
|
| 627 |
-
assert(b);
|
| 628 |
-
unsigned long idx;
|
| 629 |
-
|
| 630 |
-
#ifdef LARGEBOARDS
|
| 631 |
-
if (b >> 96) {
|
| 632 |
-
_BitScanReverse(&idx, uint32_t(b >> 96));
|
| 633 |
-
return Square(idx + 96);
|
| 634 |
-
} else if (b >> 64) {
|
| 635 |
-
_BitScanReverse(&idx, uint32_t(b >> 64));
|
| 636 |
-
return Square(idx + 64);
|
| 637 |
-
} else
|
| 638 |
-
#endif
|
| 639 |
-
if (b >> 32) {
|
| 640 |
-
_BitScanReverse(&idx, uint32_t(b >> 32));
|
| 641 |
-
return Square(idx + 32);
|
| 642 |
-
} else {
|
| 643 |
-
_BitScanReverse(&idx, uint32_t(b));
|
| 644 |
-
return Square(idx);
|
| 645 |
-
}
|
| 646 |
-
}
|
| 647 |
-
|
| 648 |
-
#endif
|
| 649 |
-
|
| 650 |
-
#else // Compiler is neither GCC nor MSVC compatible
|
| 651 |
-
|
| 652 |
-
#error "Compiler not supported."
|
| 653 |
-
|
| 654 |
-
#endif
|
| 655 |
-
|
| 656 |
-
/// least_significant_square_bb() returns the bitboard of the least significant
|
| 657 |
-
/// square of a non-zero bitboard. It is equivalent to square_bb(lsb(bb)).
|
| 658 |
-
|
| 659 |
-
inline Bitboard least_significant_square_bb(Bitboard b) {
|
| 660 |
-
assert(b);
|
| 661 |
-
return b & -b;
|
| 662 |
-
}
|
| 663 |
-
|
| 664 |
-
/// pop_lsb() finds and clears the least significant bit in a non-zero bitboard
|
| 665 |
-
|
| 666 |
-
inline Square pop_lsb(Bitboard& b) {
|
| 667 |
-
assert(b);
|
| 668 |
-
const Square s = lsb(b);
|
| 669 |
-
b &= b - 1;
|
| 670 |
-
return s;
|
| 671 |
-
}
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
/// frontmost_sq() returns the most advanced square for the given color,
|
| 675 |
-
/// requires a non-zero bitboard.
|
| 676 |
-
inline Square frontmost_sq(Color c, Bitboard b) {
|
| 677 |
-
assert(b);
|
| 678 |
-
return c == WHITE ? msb(b) : lsb(b);
|
| 679 |
-
}
|
| 680 |
-
|
| 681 |
-
|
| 682 |
-
/// popcount() counts the number of non-zero bits in a piece set
|
| 683 |
-
|
| 684 |
-
inline int popcount(PieceSet ps) {
|
| 685 |
-
|
| 686 |
-
#ifndef USE_POPCNT
|
| 687 |
-
|
| 688 |
-
union { uint64_t bb; uint16_t u[4]; } v = { (uint64_t)ps };
|
| 689 |
-
return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]];
|
| 690 |
-
|
| 691 |
-
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
| 692 |
-
|
| 693 |
-
return (int)_mm_popcnt_u64(ps);
|
| 694 |
-
|
| 695 |
-
#else // Assumed gcc or compatible compiler
|
| 696 |
-
|
| 697 |
-
return __builtin_popcountll(ps);
|
| 698 |
-
|
| 699 |
-
#endif
|
| 700 |
-
}
|
| 701 |
-
|
| 702 |
-
/// lsb() and msb() return the least/most significant bit in a non-zero piece set
|
| 703 |
-
|
| 704 |
-
#if defined(__GNUC__) // GCC, Clang, ICC
|
| 705 |
-
|
| 706 |
-
inline PieceType lsb(PieceSet ps) {
|
| 707 |
-
assert(ps);
|
| 708 |
-
return PieceType(__builtin_ctzll(ps));
|
| 709 |
-
}
|
| 710 |
-
|
| 711 |
-
inline PieceType msb(PieceSet ps) {
|
| 712 |
-
assert(ps);
|
| 713 |
-
return PieceType((PIECE_TYPE_NB - 1) ^ __builtin_clzll(ps));
|
| 714 |
-
}
|
| 715 |
-
|
| 716 |
-
#elif defined(_MSC_VER) // MSVC
|
| 717 |
-
|
| 718 |
-
#ifdef _WIN64 // MSVC, WIN64
|
| 719 |
-
|
| 720 |
-
inline PieceType lsb(PieceSet ps) {
|
| 721 |
-
assert(ps);
|
| 722 |
-
unsigned long idx;
|
| 723 |
-
_BitScanForward64(&idx, ps);
|
| 724 |
-
return (PieceType) idx;
|
| 725 |
-
}
|
| 726 |
-
|
| 727 |
-
inline PieceType msb(PieceSet ps) {
|
| 728 |
-
assert(ps);
|
| 729 |
-
unsigned long idx;
|
| 730 |
-
_BitScanReverse64(&idx, ps);
|
| 731 |
-
return (PieceType) idx;
|
| 732 |
-
}
|
| 733 |
-
|
| 734 |
-
#else // MSVC, WIN32
|
| 735 |
-
|
| 736 |
-
inline PieceType lsb(PieceSet ps) {
|
| 737 |
-
assert(ps);
|
| 738 |
-
unsigned long idx;
|
| 739 |
-
|
| 740 |
-
if (ps & 0xffffffff) {
|
| 741 |
-
_BitScanForward(&idx, uint32_t(ps));
|
| 742 |
-
return PieceType(idx);
|
| 743 |
-
} else {
|
| 744 |
-
_BitScanForward(&idx, uint32_t(ps >> 32));
|
| 745 |
-
return PieceType(idx + 32);
|
| 746 |
-
}
|
| 747 |
-
}
|
| 748 |
-
|
| 749 |
-
inline PieceType msb(PieceSet ps) {
|
| 750 |
-
assert(ps);
|
| 751 |
-
unsigned long idx;
|
| 752 |
-
if (ps >> 32) {
|
| 753 |
-
_BitScanReverse(&idx, uint32_t(ps >> 32));
|
| 754 |
-
return PieceType(idx + 32);
|
| 755 |
-
} else {
|
| 756 |
-
_BitScanReverse(&idx, uint32_t(ps));
|
| 757 |
-
return PieceType(idx);
|
| 758 |
-
}
|
| 759 |
-
}
|
| 760 |
-
|
| 761 |
-
#endif
|
| 762 |
-
|
| 763 |
-
#else // Compiler is neither GCC nor MSVC compatible
|
| 764 |
-
|
| 765 |
-
#error "Compiler not supported."
|
| 766 |
-
|
| 767 |
-
#endif
|
| 768 |
-
|
| 769 |
-
/// pop_lsb() and pop_msb() find and clear the least/most significant bit in a non-zero piece set
|
| 770 |
-
|
| 771 |
-
inline PieceType pop_lsb(PieceSet& ps) {
|
| 772 |
-
assert(ps);
|
| 773 |
-
const PieceType pt = lsb(ps);
|
| 774 |
-
ps &= PieceSet(ps - 1);
|
| 775 |
-
return pt;
|
| 776 |
-
}
|
| 777 |
-
|
| 778 |
-
inline PieceType pop_msb(PieceSet& ps) {
|
| 779 |
-
assert(ps);
|
| 780 |
-
const PieceType pt = msb(ps);
|
| 781 |
-
ps &= ~piece_set(pt);
|
| 782 |
-
return pt;
|
| 783 |
-
}
|
| 784 |
-
|
| 785 |
-
} // namespace Stockfish
|
| 786 |
-
|
| 787 |
-
#endif // #ifndef BITBOARD_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/endgame.cpp
DELETED
|
@@ -1,1321 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <cassert>
|
| 20 |
-
|
| 21 |
-
#include "bitboard.h"
|
| 22 |
-
#include "endgame.h"
|
| 23 |
-
#include "movegen.h"
|
| 24 |
-
|
| 25 |
-
namespace Stockfish {
|
| 26 |
-
|
| 27 |
-
namespace {
|
| 28 |
-
|
| 29 |
-
// Used to drive the king towards the edge of the board
|
| 30 |
-
// in KX vs K and KQ vs KR endgames.
|
| 31 |
-
// Values range from 27 (center squares) to 90 (in the corners)
|
| 32 |
-
inline int push_to_edge(Square s, const Position& pos) {
|
| 33 |
-
int rd = edge_distance(rank_of(s), pos.max_rank()), fd = edge_distance(file_of(s), pos.max_file());
|
| 34 |
-
return 90 - (7 * fd * fd / 2 + 7 * rd * rd / 2);
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
// Used to drive the king towards A1H8 corners in KBN vs K endgames.
|
| 38 |
-
// Values range from 0 on A8H1 diagonal to 7 in A1H8 corners.
|
| 39 |
-
inline int push_to_corner(Square s, const Position& pos) {
|
| 40 |
-
return abs((pos.max_file() + pos.max_rank()) / 2 - rank_of(s) - file_of(s));
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
// Used to drive the king towards the edge of the board in KSF vs K.
|
| 44 |
-
inline int push_to_opposing_edge(Square s, const Position& pos) {
|
| 45 |
-
int rd = rank_of(s), fd = edge_distance(file_of(s), pos.max_file());
|
| 46 |
-
return 20 - (7 * fd * fd / 2 - 7 * rd * rd / 4);
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
// Drive a piece close to or away from another piece
|
| 50 |
-
inline int push_close(Square s1, Square s2) { return 140 - 20 * distance(s1, s2); }
|
| 51 |
-
inline int push_away(Square s1, Square s2) { return 120 - push_close(s1, s2); }
|
| 52 |
-
|
| 53 |
-
#ifndef NDEBUG
|
| 54 |
-
bool verify_material(const Position& pos, Color c, Value npm, int pawnsCnt) {
|
| 55 |
-
return pos.non_pawn_material(c) == npm && pos.count<PAWN>(c) == pawnsCnt;
|
| 56 |
-
}
|
| 57 |
-
#endif
|
| 58 |
-
|
| 59 |
-
// Map the square as if strongSide is white and strongSide's only pawn
|
| 60 |
-
// is on the left half of the board.
|
| 61 |
-
Square normalize(const Position& pos, Color strongSide, Square sq) {
|
| 62 |
-
|
| 63 |
-
assert(pos.count<PAWN>(strongSide) == 1);
|
| 64 |
-
|
| 65 |
-
if (file_of(pos.square<PAWN>(strongSide)) > pos.max_file() / 2)
|
| 66 |
-
sq = flip_file(sq, pos.max_file());
|
| 67 |
-
|
| 68 |
-
return strongSide == WHITE ? sq : flip_rank(sq, pos.max_rank());
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
} // namespace
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
namespace Endgames {
|
| 75 |
-
|
| 76 |
-
std::pair<Map<Value>, Map<ScaleFactor>> maps;
|
| 77 |
-
|
| 78 |
-
void init() {
|
| 79 |
-
|
| 80 |
-
add<KPK>("KPK");
|
| 81 |
-
add<KNNK>("KNNK");
|
| 82 |
-
add<KBNK>("KBNK");
|
| 83 |
-
add<KRKP>("KRKP");
|
| 84 |
-
add<KRKB>("KRKB");
|
| 85 |
-
add<KRKN>("KRKN");
|
| 86 |
-
add<KQKP>("KQKP");
|
| 87 |
-
add<KQKR>("KQKR");
|
| 88 |
-
add<KNNKP>("KNNKP");
|
| 89 |
-
|
| 90 |
-
// Fairy piece endgames
|
| 91 |
-
add<KNSK>("KNSK");
|
| 92 |
-
add<KNFK>("KNFK");
|
| 93 |
-
add<KNSFKR>("KNSFKR");
|
| 94 |
-
add<KSFK>("KSFK");
|
| 95 |
-
add<KSFKF>("KSFKF");
|
| 96 |
-
add<KRKS>("KRKS");
|
| 97 |
-
add<KCKR>("KCKR");
|
| 98 |
-
add<KAKR>("KAKR");
|
| 99 |
-
|
| 100 |
-
// Anti
|
| 101 |
-
add<RK, EG_EVAL_ANTI>("RvM");
|
| 102 |
-
add<KN, EG_EVAL_ANTI>("MvN");
|
| 103 |
-
add<NN, EG_EVAL_ANTI>("NvN");
|
| 104 |
-
|
| 105 |
-
// Atomic
|
| 106 |
-
add<KPK, EG_EVAL_ATOMIC>("MPvM");
|
| 107 |
-
add<KNK, EG_EVAL_ATOMIC>("MNvM");
|
| 108 |
-
add<KBK, EG_EVAL_ATOMIC>("MBvM");
|
| 109 |
-
add<KRK, EG_EVAL_ATOMIC>("MRvM");
|
| 110 |
-
add<KQK, EG_EVAL_ATOMIC>("MQvM");
|
| 111 |
-
add<KNNK, EG_EVAL_ATOMIC>("MNNvM");
|
| 112 |
-
|
| 113 |
-
// Duck
|
| 114 |
-
add<KBK, EG_EVAL_DUCK>("MBvM");
|
| 115 |
-
add<KNK, EG_EVAL_DUCK>("MNvM");
|
| 116 |
-
add<KPK, EG_EVAL_DUCK>("MPvM");
|
| 117 |
-
|
| 118 |
-
// Racing kings
|
| 119 |
-
add<KQK, EG_EVAL_RK>("KQK");
|
| 120 |
-
add<KRK, EG_EVAL_RK>("KRK");
|
| 121 |
-
add<KK, EG_EVAL_RK>("KK");
|
| 122 |
-
|
| 123 |
-
add<KRPKB>("KRPKB");
|
| 124 |
-
add<KBPKB>("KBPKB");
|
| 125 |
-
add<KBPKN>("KBPKN");
|
| 126 |
-
add<KBPPKB>("KBPPKB");
|
| 127 |
-
add<KRPPKRP>("KRPPKRP");
|
| 128 |
-
}
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
/// Mate with KX vs K. This function is used to evaluate positions with
|
| 133 |
-
/// king and plenty of material vs a lone king. It simply gives the
|
| 134 |
-
/// attacking side a bonus for driving the defending king towards the edge
|
| 135 |
-
/// of the board, and for keeping the distance between the two kings small.
|
| 136 |
-
template<>
|
| 137 |
-
Value Endgame<KXK>::operator()(const Position& pos) const {
|
| 138 |
-
|
| 139 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 140 |
-
assert(!pos.checkers()); // Eval is never called when in check
|
| 141 |
-
|
| 142 |
-
// Stalemate detection with lone king
|
| 143 |
-
if (pos.side_to_move() == weakSide && !MoveList<LEGAL>(pos).size())
|
| 144 |
-
return VALUE_DRAW;
|
| 145 |
-
|
| 146 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 147 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 148 |
-
|
| 149 |
-
Value result = pos.non_pawn_material(strongSide)
|
| 150 |
-
+ pos.count<PAWN>(strongSide) * PawnValueEg
|
| 151 |
-
+ push_to_edge(weakKing, pos)
|
| 152 |
-
+ push_close(strongKing, weakKing);
|
| 153 |
-
|
| 154 |
-
if ( pos.count<QUEEN>(strongSide)
|
| 155 |
-
|| pos.count<ROOK>(strongSide)
|
| 156 |
-
||(pos.count<BISHOP>(strongSide) && pos.count<KNIGHT>(strongSide))
|
| 157 |
-
|| ( (pos.pieces(strongSide, BISHOP) & ~DarkSquares)
|
| 158 |
-
&& (pos.pieces(strongSide, BISHOP) & DarkSquares))
|
| 159 |
-
|| pos.count<SILVER>(strongSide) >= 2
|
| 160 |
-
||(pos.count<SILVER>(strongSide) && pos.count<KNIGHT>(strongSide))
|
| 161 |
-
||(pos.count<SILVER>(strongSide) && pos.count<FERS>(strongSide))
|
| 162 |
-
||(pos.count<KNIGHT>(strongSide) && pos.count<FERS>(strongSide) >= 2)
|
| 163 |
-
||(pos.count<FERS>(strongSide) >= 3
|
| 164 |
-
&& ( DarkSquares & pos.pieces(strongSide, FERS))
|
| 165 |
-
&& (~DarkSquares & pos.pieces(strongSide, FERS))))
|
| 166 |
-
result = std::min(result + VALUE_KNOWN_WIN, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
| 167 |
-
|
| 168 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 169 |
-
}
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
|
| 173 |
-
/// defending king towards a corner square that our bishop attacks.
|
| 174 |
-
template<>
|
| 175 |
-
Value Endgame<KBNK>::operator()(const Position& pos) const {
|
| 176 |
-
|
| 177 |
-
assert(verify_material(pos, strongSide, KnightValueMg + BishopValueMg, 0));
|
| 178 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 179 |
-
|
| 180 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 181 |
-
Square strongBishop = pos.square<BISHOP>(strongSide);
|
| 182 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 183 |
-
|
| 184 |
-
// If our bishop does not attack A1/H8, we flip the enemy king square
|
| 185 |
-
// to drive to opposite corners (A8/H1).
|
| 186 |
-
|
| 187 |
-
Value result = (VALUE_KNOWN_WIN + 3520)
|
| 188 |
-
+ push_close(strongKing, weakKing)
|
| 189 |
-
+ 420 * push_to_corner(opposite_colors(strongBishop, SQ_A1) ? flip_file(weakKing, pos.max_file()) : weakKing, pos);
|
| 190 |
-
|
| 191 |
-
assert(abs(result) < VALUE_TB_WIN_IN_MAX_PLY);
|
| 192 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 193 |
-
}
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
/// KP vs K. This endgame is evaluated with the help of a bitbase
|
| 197 |
-
template<>
|
| 198 |
-
Value Endgame<KPK>::operator()(const Position& pos) const {
|
| 199 |
-
|
| 200 |
-
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
| 201 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 202 |
-
|
| 203 |
-
// Assume strongSide is white and the pawn is on files A-D
|
| 204 |
-
Square strongKing = normalize(pos, strongSide, pos.square<KING>(strongSide));
|
| 205 |
-
Square strongPawn = normalize(pos, strongSide, pos.square<PAWN>(strongSide));
|
| 206 |
-
Square weakKing = normalize(pos, strongSide, pos.square<KING>(weakSide));
|
| 207 |
-
|
| 208 |
-
Color us = strongSide == pos.side_to_move() ? WHITE : BLACK;
|
| 209 |
-
|
| 210 |
-
// Non-standard promotion, evaluation unclear
|
| 211 |
-
if ( pos.promotion_zone(us) != rank_bb(relative_rank(us, RANK_8, pos.max_rank()))
|
| 212 |
-
|| RANK_MAX != RANK_8
|
| 213 |
-
|| !(pos.promotion_piece_types(us) & QUEEN))
|
| 214 |
-
{
|
| 215 |
-
Value result = PawnValueEg + Value(rank_of(strongPawn));
|
| 216 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 217 |
-
}
|
| 218 |
-
|
| 219 |
-
if (!Bitbases::probe(strongKing, strongPawn, weakKing, us))
|
| 220 |
-
return VALUE_DRAW;
|
| 221 |
-
|
| 222 |
-
Value result = VALUE_KNOWN_WIN + PawnValueEg + Value(rank_of(strongPawn));
|
| 223 |
-
|
| 224 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 225 |
-
}
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
/// KR vs KP. This is a somewhat tricky endgame to evaluate precisely without
|
| 229 |
-
/// a bitbase. The function below returns drawish scores when the pawn is
|
| 230 |
-
/// far advanced with support of the king, while the attacking king is far
|
| 231 |
-
/// away.
|
| 232 |
-
template<>
|
| 233 |
-
Value Endgame<KRKP>::operator()(const Position& pos) const {
|
| 234 |
-
|
| 235 |
-
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
| 236 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
| 237 |
-
|
| 238 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 239 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 240 |
-
Square strongRook = pos.square<ROOK>(strongSide);
|
| 241 |
-
Square weakPawn = pos.square<PAWN>(weakSide);
|
| 242 |
-
Square queeningSquare = make_square(file_of(weakPawn), relative_rank(weakSide, RANK_8));
|
| 243 |
-
Value result;
|
| 244 |
-
|
| 245 |
-
// If the stronger side's king is in front of the pawn, it's a win
|
| 246 |
-
if (forward_file_bb(strongSide, strongKing) & weakPawn)
|
| 247 |
-
result = RookValueEg - distance(strongKing, weakPawn);
|
| 248 |
-
|
| 249 |
-
// If the weaker side's king is too far from the pawn and the rook,
|
| 250 |
-
// it's a win.
|
| 251 |
-
else if ( distance(weakKing, weakPawn) >= 3 + (pos.side_to_move() == weakSide)
|
| 252 |
-
&& distance(weakKing, strongRook) >= 3)
|
| 253 |
-
result = RookValueEg - distance(strongKing, weakPawn);
|
| 254 |
-
|
| 255 |
-
// If the pawn is far advanced and supported by the defending king,
|
| 256 |
-
// the position is drawish
|
| 257 |
-
else if ( relative_rank(strongSide, weakKing) <= RANK_3
|
| 258 |
-
&& distance(weakKing, weakPawn) == 1
|
| 259 |
-
&& relative_rank(strongSide, strongKing) >= RANK_4
|
| 260 |
-
&& distance(strongKing, weakPawn) > 2 + (pos.side_to_move() == strongSide))
|
| 261 |
-
result = Value(80) - 8 * distance(strongKing, weakPawn);
|
| 262 |
-
|
| 263 |
-
else
|
| 264 |
-
result = Value(200) - 8 * ( distance(strongKing, weakPawn + pawn_push(weakSide))
|
| 265 |
-
- distance(weakKing, weakPawn + pawn_push(weakSide))
|
| 266 |
-
- distance(weakPawn, queeningSquare));
|
| 267 |
-
|
| 268 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 269 |
-
}
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
/// KR vs KB. This is very simple, and always returns drawish scores. The
|
| 273 |
-
/// score is slightly bigger when the defending king is close to the edge.
|
| 274 |
-
template<>
|
| 275 |
-
Value Endgame<KRKB>::operator()(const Position& pos) const {
|
| 276 |
-
|
| 277 |
-
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
| 278 |
-
assert(verify_material(pos, weakSide, BishopValueMg, 0));
|
| 279 |
-
|
| 280 |
-
Value result = Value(push_to_edge(pos.square<KING>(weakSide), pos));
|
| 281 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 282 |
-
}
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
/// KR vs KN. The attacking side has slightly better winning chances than
|
| 286 |
-
/// in KR vs KB, particularly if the king and the knight are far apart.
|
| 287 |
-
template<>
|
| 288 |
-
Value Endgame<KRKN>::operator()(const Position& pos) const {
|
| 289 |
-
|
| 290 |
-
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
| 291 |
-
assert(verify_material(pos, weakSide, KnightValueMg, 0));
|
| 292 |
-
|
| 293 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 294 |
-
Square weakKnight = pos.square<KNIGHT>(weakSide);
|
| 295 |
-
Value result = Value(push_to_edge(weakKing, pos) + push_away(weakKing, weakKnight));
|
| 296 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 297 |
-
}
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
/// KQ vs KP. In general, this is a win for the stronger side, but there are a
|
| 301 |
-
/// few important exceptions. A pawn on 7th rank and on the A,C,F or H files
|
| 302 |
-
/// with a king positioned next to it can be a draw, so in that case, we only
|
| 303 |
-
/// use the distance between the kings.
|
| 304 |
-
template<>
|
| 305 |
-
Value Endgame<KQKP>::operator()(const Position& pos) const {
|
| 306 |
-
|
| 307 |
-
assert(verify_material(pos, strongSide, QueenValueMg, 0));
|
| 308 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
| 309 |
-
|
| 310 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 311 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 312 |
-
Square weakPawn = pos.square<PAWN>(weakSide);
|
| 313 |
-
|
| 314 |
-
Value result = Value(push_close(strongKing, weakKing));
|
| 315 |
-
|
| 316 |
-
if ( relative_rank(weakSide, weakPawn) != RANK_7
|
| 317 |
-
|| distance(weakKing, weakPawn) != 1
|
| 318 |
-
|| ((FileBBB | FileDBB | FileEBB | FileGBB) & weakPawn))
|
| 319 |
-
result += QueenValueEg - PawnValueEg;
|
| 320 |
-
|
| 321 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 322 |
-
}
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
/// KQ vs KR. This is almost identical to KX vs K: we give the attacking
|
| 326 |
-
/// king a bonus for having the kings close together, and for forcing the
|
| 327 |
-
/// defending king towards the edge. If we also take care to avoid null move for
|
| 328 |
-
/// the defending side in the search, this is usually sufficient to win KQ vs KR.
|
| 329 |
-
template<>
|
| 330 |
-
Value Endgame<KQKR>::operator()(const Position& pos) const {
|
| 331 |
-
|
| 332 |
-
assert(verify_material(pos, strongSide, QueenValueMg, 0));
|
| 333 |
-
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
| 334 |
-
|
| 335 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 336 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 337 |
-
|
| 338 |
-
Value result = QueenValueEg
|
| 339 |
-
- RookValueEg
|
| 340 |
-
+ push_to_edge(weakKing, pos)
|
| 341 |
-
+ push_close(strongKing, weakKing);
|
| 342 |
-
|
| 343 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 344 |
-
}
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
/// KC vs KR. Drawish, but good winning chances if king and rook are close.
|
| 348 |
-
template<>
|
| 349 |
-
Value Endgame<KCKR>::operator()(const Position& pos) const {
|
| 350 |
-
|
| 351 |
-
assert(verify_material(pos, strongSide, ChancellorValueMg, 0));
|
| 352 |
-
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
| 353 |
-
|
| 354 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 355 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 356 |
-
Square weakRook = pos.square<ROOK>(weakSide);
|
| 357 |
-
|
| 358 |
-
Value result = Value(push_to_edge(weakKing, pos))
|
| 359 |
-
+ push_close(strongKing, weakKing)
|
| 360 |
-
+ push_close(weakRook, weakKing);
|
| 361 |
-
|
| 362 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
/// KA vs KR. Very drawish.
|
| 367 |
-
template<>
|
| 368 |
-
Value Endgame<KAKR>::operator()(const Position& pos) const {
|
| 369 |
-
|
| 370 |
-
assert(verify_material(pos, strongSide, ArchbishopValueMg, 0));
|
| 371 |
-
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
| 372 |
-
|
| 373 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 374 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 375 |
-
|
| 376 |
-
Value result = Value(push_to_edge(weakKing, pos))
|
| 377 |
-
+ push_close(strongKing, weakKing);
|
| 378 |
-
|
| 379 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 380 |
-
}
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
/// KNN vs KP. Very drawish, but there are some mate opportunities if we can
|
| 384 |
-
/// press the weakSide King to a corner before the pawn advances too much.
|
| 385 |
-
template<>
|
| 386 |
-
Value Endgame<KNNKP>::operator()(const Position& pos) const {
|
| 387 |
-
|
| 388 |
-
assert(verify_material(pos, strongSide, 2 * KnightValueMg, 0));
|
| 389 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
| 390 |
-
|
| 391 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 392 |
-
Square weakPawn = pos.square<PAWN>(weakSide);
|
| 393 |
-
|
| 394 |
-
Value result = PawnValueEg
|
| 395 |
-
+ 2 * push_to_edge(weakKing, pos)
|
| 396 |
-
- 10 * relative_rank(weakSide, weakPawn);
|
| 397 |
-
|
| 398 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 399 |
-
}
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
/// Some cases of trivial draws
|
| 403 |
-
template<> Value Endgame<KNNK>::operator()(const Position&) const { return VALUE_DRAW; }
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
/// KFsPs vs K.
|
| 407 |
-
template<>
|
| 408 |
-
Value Endgame<KFsPsK>::operator()(const Position& pos) const {
|
| 409 |
-
|
| 410 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 411 |
-
|
| 412 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 413 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 414 |
-
|
| 415 |
-
Value result = pos.non_pawn_material(strongSide)
|
| 416 |
-
+ pos.count<PAWN>(strongSide) * PawnValueEg
|
| 417 |
-
+ push_to_edge(loserKSq, pos)
|
| 418 |
-
+ push_close(winnerKSq, loserKSq);
|
| 419 |
-
|
| 420 |
-
if ( pos.count<FERS>(strongSide) >= 3
|
| 421 |
-
&& ( DarkSquares & pos.pieces(strongSide, FERS))
|
| 422 |
-
&& (~DarkSquares & pos.pieces(strongSide, FERS)))
|
| 423 |
-
result = std::min(result + VALUE_KNOWN_WIN, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
| 424 |
-
else if (pos.count<FERS>(strongSide) + pos.count<PAWN>(strongSide) < 3)
|
| 425 |
-
return VALUE_DRAW;
|
| 426 |
-
else
|
| 427 |
-
{
|
| 428 |
-
bool dark = DarkSquares & pos.pieces(strongSide, FERS);
|
| 429 |
-
bool light = ~DarkSquares & pos.pieces(strongSide, FERS);
|
| 430 |
-
|
| 431 |
-
// Determine the color of ferzes from promoting pawns
|
| 432 |
-
Bitboard b = pos.pieces(strongSide, PAWN);
|
| 433 |
-
while (b && (!dark || !light))
|
| 434 |
-
{
|
| 435 |
-
Square s = pos.promotion_square(strongSide, pop_lsb(b));
|
| 436 |
-
if (s != SQ_NONE)
|
| 437 |
-
{
|
| 438 |
-
if (DarkSquares & s)
|
| 439 |
-
dark = true;
|
| 440 |
-
else
|
| 441 |
-
light = true;
|
| 442 |
-
}
|
| 443 |
-
}
|
| 444 |
-
if (!dark || !light)
|
| 445 |
-
return VALUE_DRAW; // we can not checkmate with same colored ferzes
|
| 446 |
-
}
|
| 447 |
-
|
| 448 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 449 |
-
}
|
| 450 |
-
|
| 451 |
-
|
| 452 |
-
/// Mate with KNS vs K.
|
| 453 |
-
template<>
|
| 454 |
-
Value Endgame<KNSK>::operator()(const Position& pos) const {
|
| 455 |
-
|
| 456 |
-
assert(verify_material(pos, strongSide, KnightValueMg + SilverValueMg, 0));
|
| 457 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 458 |
-
|
| 459 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 460 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 461 |
-
|
| 462 |
-
Value result = VALUE_KNOWN_WIN
|
| 463 |
-
+ push_close(winnerKSq, loserKSq)
|
| 464 |
-
+ push_to_opposing_edge(relative_square(strongSide, loserKSq, pos.max_rank()), pos);
|
| 465 |
-
|
| 466 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 467 |
-
}
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
/// KNF vs K. Can only be won if the weaker side's king
|
| 471 |
-
/// is close to a corner of the same color as the fers.
|
| 472 |
-
template<>
|
| 473 |
-
Value Endgame<KNFK>::operator()(const Position& pos) const {
|
| 474 |
-
|
| 475 |
-
assert(verify_material(pos, strongSide, KnightValueMg + FersValueMg, 0));
|
| 476 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 477 |
-
|
| 478 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 479 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 480 |
-
Square fersSq = pos.square<FERS>(strongSide);
|
| 481 |
-
|
| 482 |
-
// tries to drive toward corners A1 or H8. If we have a
|
| 483 |
-
// fers that cannot reach the above squares, we flip the kings in order
|
| 484 |
-
// to drive the enemy toward corners A8 or H1.
|
| 485 |
-
if (opposite_colors(fersSq, SQ_A1))
|
| 486 |
-
{
|
| 487 |
-
winnerKSq = relative_square(BLACK, winnerKSq, pos.max_rank());
|
| 488 |
-
loserKSq = relative_square(BLACK, loserKSq, pos.max_rank());
|
| 489 |
-
}
|
| 490 |
-
|
| 491 |
-
Value result = Value(push_close(winnerKSq, loserKSq))
|
| 492 |
-
+ 50 * push_to_corner(loserKSq, pos);
|
| 493 |
-
|
| 494 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 495 |
-
}
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
/// KNSFKR vs K.
|
| 499 |
-
template<>
|
| 500 |
-
Value Endgame<KNSFKR>::operator()(const Position& pos) const {
|
| 501 |
-
|
| 502 |
-
assert(verify_material(pos, strongSide, KnightValueMg + SilverValueMg + FersValueMg, 0));
|
| 503 |
-
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
| 504 |
-
|
| 505 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 506 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 507 |
-
|
| 508 |
-
Value result = KnightValueEg + SilverValueEg + FersValueEg - RookValueEg
|
| 509 |
-
+ push_close(winnerKSq, loserKSq)
|
| 510 |
-
+ push_to_opposing_edge(relative_square(strongSide, loserKSq, pos.max_rank()), pos);
|
| 511 |
-
|
| 512 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 513 |
-
}
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
/// Mate with KSF vs K.
|
| 517 |
-
template<>
|
| 518 |
-
Value Endgame<KSFK>::operator()(const Position& pos) const {
|
| 519 |
-
|
| 520 |
-
assert(verify_material(pos, strongSide, SilverValueMg + FersValueMg, 0));
|
| 521 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 522 |
-
|
| 523 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 524 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 525 |
-
|
| 526 |
-
Value result = VALUE_KNOWN_WIN
|
| 527 |
-
+ push_close(winnerKSq, loserKSq)
|
| 528 |
-
+ push_to_opposing_edge(relative_square(strongSide, loserKSq, pos.max_rank()), pos);
|
| 529 |
-
|
| 530 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 531 |
-
}
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
/// Mate with KSF vs KF.
|
| 535 |
-
template<>
|
| 536 |
-
Value Endgame<KSFKF>::operator()(const Position& pos) const {
|
| 537 |
-
|
| 538 |
-
assert(verify_material(pos, strongSide, SilverValueMg + FersValueMg, 0));
|
| 539 |
-
assert(verify_material(pos, weakSide, FersValueMg, 0));
|
| 540 |
-
|
| 541 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 542 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 543 |
-
Square fersSq = pos.square<FERS>(weakSide);
|
| 544 |
-
|
| 545 |
-
Value result = SilverValueEg
|
| 546 |
-
+ push_close(winnerKSq, loserKSq)
|
| 547 |
-
+ push_away(fersSq, loserKSq)
|
| 548 |
-
+ push_to_opposing_edge(relative_square(strongSide, loserKSq, pos.max_rank()), pos);
|
| 549 |
-
|
| 550 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 551 |
-
}
|
| 552 |
-
|
| 553 |
-
|
| 554 |
-
/// KR vs KS
|
| 555 |
-
template<>
|
| 556 |
-
Value Endgame<KRKS>::operator()(const Position& pos) const {
|
| 557 |
-
|
| 558 |
-
assert(verify_material(pos, strongSide, RookValueMg, 0));
|
| 559 |
-
assert(verify_material(pos, weakSide, SilverValueMg, 0));
|
| 560 |
-
|
| 561 |
-
Square winnerKSq = pos.square<KING>(strongSide);
|
| 562 |
-
Square loserKSq = pos.square<KING>(weakSide);
|
| 563 |
-
|
| 564 |
-
Value result = RookValueEg
|
| 565 |
-
- SilverValueEg
|
| 566 |
-
+ push_to_edge(loserKSq, pos)
|
| 567 |
-
+ push_close(winnerKSq, loserKSq);
|
| 568 |
-
|
| 569 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 570 |
-
}
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
/// KB and one or more pawns vs K. It checks for draws with rook pawns and
|
| 574 |
-
/// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW
|
| 575 |
-
/// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
|
| 576 |
-
/// will be used.
|
| 577 |
-
template<>
|
| 578 |
-
ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const {
|
| 579 |
-
|
| 580 |
-
assert(pos.non_pawn_material(strongSide) == BishopValueMg);
|
| 581 |
-
assert(pos.count<PAWN>(strongSide) >= 1);
|
| 582 |
-
|
| 583 |
-
// No assertions about the material of weakSide, because we want draws to
|
| 584 |
-
// be detected even when the weaker side has some pawns.
|
| 585 |
-
|
| 586 |
-
Bitboard strongPawns = pos.pieces(strongSide, PAWN);
|
| 587 |
-
Bitboard allPawns = pos.pieces(PAWN);
|
| 588 |
-
|
| 589 |
-
Square strongBishop = pos.square<BISHOP>(strongSide);
|
| 590 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 591 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 592 |
-
|
| 593 |
-
// All strongSide pawns are on a single rook file?
|
| 594 |
-
if (!(strongPawns & ~FileABB) || !(strongPawns & ~FileHBB))
|
| 595 |
-
{
|
| 596 |
-
Square queeningSquare = relative_square(strongSide, make_square(file_of(lsb(strongPawns)), RANK_8));
|
| 597 |
-
|
| 598 |
-
if ( opposite_colors(queeningSquare, strongBishop)
|
| 599 |
-
&& distance(queeningSquare, weakKing) <= 1)
|
| 600 |
-
return SCALE_FACTOR_DRAW;
|
| 601 |
-
}
|
| 602 |
-
|
| 603 |
-
// If all the pawns are on the same B or G file, then it's potentially a draw
|
| 604 |
-
if ((!(allPawns & ~FileBBB) || !(allPawns & ~FileGBB))
|
| 605 |
-
&& pos.non_pawn_material(weakSide) == 0
|
| 606 |
-
&& pos.count<PAWN>(weakSide) >= 1)
|
| 607 |
-
{
|
| 608 |
-
// Get the least advanced weakSide pawn
|
| 609 |
-
Square weakPawn = frontmost_sq(strongSide, pos.pieces(weakSide, PAWN));
|
| 610 |
-
|
| 611 |
-
// There's potential for a draw if our pawn is blocked on the 7th rank,
|
| 612 |
-
// the bishop cannot attack it or they only have one pawn left.
|
| 613 |
-
if ( relative_rank(strongSide, weakPawn) == RANK_7
|
| 614 |
-
&& (strongPawns & (weakPawn + pawn_push(weakSide)))
|
| 615 |
-
&& (opposite_colors(strongBishop, weakPawn) || !more_than_one(strongPawns)))
|
| 616 |
-
{
|
| 617 |
-
int strongKingDist = distance(weakPawn, strongKing);
|
| 618 |
-
int weakKingDist = distance(weakPawn, weakKing);
|
| 619 |
-
|
| 620 |
-
// It's a draw if the weak king is on its back two ranks, within 2
|
| 621 |
-
// squares of the blocking pawn and the strong king is not
|
| 622 |
-
// closer. (I think this rule only fails in practically
|
| 623 |
-
// unreachable positions such as 5k1K/6p1/6P1/8/8/3B4/8/8 w
|
| 624 |
-
// and positions where qsearch will immediately correct the
|
| 625 |
-
// problem such as 8/4k1p1/6P1/1K6/3B4/8/8/8 w).
|
| 626 |
-
if ( relative_rank(strongSide, weakKing) >= RANK_7
|
| 627 |
-
&& weakKingDist <= 2
|
| 628 |
-
&& weakKingDist <= strongKingDist)
|
| 629 |
-
return SCALE_FACTOR_DRAW;
|
| 630 |
-
}
|
| 631 |
-
}
|
| 632 |
-
|
| 633 |
-
return SCALE_FACTOR_NONE;
|
| 634 |
-
}
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
/// KQ vs KR and one or more pawns. It tests for fortress draws with a rook on
|
| 638 |
-
/// the third rank defended by a pawn.
|
| 639 |
-
template<>
|
| 640 |
-
ScaleFactor Endgame<KQKRPs>::operator()(const Position& pos) const {
|
| 641 |
-
|
| 642 |
-
assert(verify_material(pos, strongSide, QueenValueMg, 0));
|
| 643 |
-
assert(pos.count<ROOK>(weakSide) == 1);
|
| 644 |
-
assert(pos.count<PAWN>(weakSide) >= 1);
|
| 645 |
-
|
| 646 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 647 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 648 |
-
Square weakRook = pos.square<ROOK>(weakSide);
|
| 649 |
-
|
| 650 |
-
if ( relative_rank(weakSide, weakKing) <= RANK_2
|
| 651 |
-
&& relative_rank(weakSide, strongKing) >= RANK_4
|
| 652 |
-
&& relative_rank(weakSide, weakRook) == RANK_3
|
| 653 |
-
&& ( pos.pieces(weakSide, PAWN)
|
| 654 |
-
& attacks_bb<KING>(weakKing)
|
| 655 |
-
& pawn_attacks_bb(strongSide, weakRook)))
|
| 656 |
-
return SCALE_FACTOR_DRAW;
|
| 657 |
-
|
| 658 |
-
return SCALE_FACTOR_NONE;
|
| 659 |
-
}
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
/// KRP vs KR. This function knows a handful of the most important classes of
|
| 663 |
-
/// drawn positions, but is far from perfect. It would probably be a good idea
|
| 664 |
-
/// to add more knowledge in the future.
|
| 665 |
-
///
|
| 666 |
-
/// It would also be nice to rewrite the actual code for this function,
|
| 667 |
-
/// which is mostly copied from Glaurung 1.x, and isn't very pretty.
|
| 668 |
-
template<>
|
| 669 |
-
ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
|
| 670 |
-
|
| 671 |
-
assert(verify_material(pos, strongSide, RookValueMg, 1));
|
| 672 |
-
assert(verify_material(pos, weakSide, RookValueMg, 0));
|
| 673 |
-
|
| 674 |
-
// Assume strongSide is white and the pawn is on files A-D
|
| 675 |
-
Square strongKing = normalize(pos, strongSide, pos.square<KING>(strongSide));
|
| 676 |
-
Square strongRook = normalize(pos, strongSide, pos.square<ROOK>(strongSide));
|
| 677 |
-
Square strongPawn = normalize(pos, strongSide, pos.square<PAWN>(strongSide));
|
| 678 |
-
Square weakKing = normalize(pos, strongSide, pos.square<KING>(weakSide));
|
| 679 |
-
Square weakRook = normalize(pos, strongSide, pos.square<ROOK>(weakSide));
|
| 680 |
-
|
| 681 |
-
File pawnFile = file_of(strongPawn);
|
| 682 |
-
Rank pawnRank = rank_of(strongPawn);
|
| 683 |
-
Square queeningSquare = make_square(pawnFile, RANK_8);
|
| 684 |
-
int tempo = (pos.side_to_move() == strongSide);
|
| 685 |
-
|
| 686 |
-
// If the pawn is not too far advanced and the defending king defends the
|
| 687 |
-
// queening square, use the third-rank defence.
|
| 688 |
-
if ( pawnRank <= RANK_5
|
| 689 |
-
&& distance(weakKing, queeningSquare) <= 1
|
| 690 |
-
&& strongKing <= SQ_H5
|
| 691 |
-
&& (rank_of(weakRook) == RANK_6 || (pawnRank <= RANK_3 && rank_of(strongRook) != RANK_6)))
|
| 692 |
-
return SCALE_FACTOR_DRAW;
|
| 693 |
-
|
| 694 |
-
// The defending side saves a draw by checking from behind in case the pawn
|
| 695 |
-
// has advanced to the 6th rank with the king behind.
|
| 696 |
-
if ( pawnRank == RANK_6
|
| 697 |
-
&& distance(weakKing, queeningSquare) <= 1
|
| 698 |
-
&& rank_of(strongKing) + tempo <= RANK_6
|
| 699 |
-
&& (rank_of(weakRook) == RANK_1 || (!tempo && distance<File>(weakRook, strongPawn) >= 3)))
|
| 700 |
-
return SCALE_FACTOR_DRAW;
|
| 701 |
-
|
| 702 |
-
if ( pawnRank >= RANK_6
|
| 703 |
-
&& weakKing == queeningSquare
|
| 704 |
-
&& rank_of(weakRook) == RANK_1
|
| 705 |
-
&& (!tempo || distance(strongKing, strongPawn) >= 2))
|
| 706 |
-
return SCALE_FACTOR_DRAW;
|
| 707 |
-
|
| 708 |
-
// White pawn on a7 and rook on a8 is a draw if black's king is on g7 or h7
|
| 709 |
-
// and the black rook is behind the pawn.
|
| 710 |
-
if ( strongPawn == SQ_A7
|
| 711 |
-
&& strongRook == SQ_A8
|
| 712 |
-
&& (weakKing == SQ_H7 || weakKing == SQ_G7)
|
| 713 |
-
&& file_of(weakRook) == FILE_A
|
| 714 |
-
&& (rank_of(weakRook) <= RANK_3 || file_of(strongKing) >= FILE_D || rank_of(strongKing) <= RANK_5))
|
| 715 |
-
return SCALE_FACTOR_DRAW;
|
| 716 |
-
|
| 717 |
-
// If the defending king blocks the pawn and the attacking king is too far
|
| 718 |
-
// away, it's a draw.
|
| 719 |
-
if ( pawnRank <= RANK_5
|
| 720 |
-
&& weakKing == strongPawn + NORTH
|
| 721 |
-
&& distance(strongKing, strongPawn) - tempo >= 2
|
| 722 |
-
&& distance(strongKing, weakRook) - tempo >= 2)
|
| 723 |
-
return SCALE_FACTOR_DRAW;
|
| 724 |
-
|
| 725 |
-
// Pawn on the 7th rank supported by the rook from behind usually wins if the
|
| 726 |
-
// attacking king is closer to the queening square than the defending king,
|
| 727 |
-
// and the defending king cannot gain tempi by threatening the attacking rook.
|
| 728 |
-
if ( pawnRank == RANK_7
|
| 729 |
-
&& pawnFile != FILE_A
|
| 730 |
-
&& file_of(strongRook) == pawnFile
|
| 731 |
-
&& strongRook != queeningSquare
|
| 732 |
-
&& (distance(strongKing, queeningSquare) < distance(weakKing, queeningSquare) - 2 + tempo)
|
| 733 |
-
&& (distance(strongKing, queeningSquare) < distance(weakKing, strongRook) + tempo))
|
| 734 |
-
return ScaleFactor(SCALE_FACTOR_MAX - 2 * distance(strongKing, queeningSquare));
|
| 735 |
-
|
| 736 |
-
// Similar to the above, but with the pawn further back
|
| 737 |
-
if ( pawnFile != FILE_A
|
| 738 |
-
&& file_of(strongRook) == pawnFile
|
| 739 |
-
&& strongRook < strongPawn
|
| 740 |
-
&& (distance(strongKing, queeningSquare) < distance(weakKing, queeningSquare) - 2 + tempo)
|
| 741 |
-
&& (distance(strongKing, strongPawn + NORTH) < distance(weakKing, strongPawn + NORTH) - 2 + tempo)
|
| 742 |
-
&& ( distance(weakKing, strongRook) + tempo >= 3
|
| 743 |
-
|| ( distance(strongKing, queeningSquare) < distance(weakKing, strongRook) + tempo
|
| 744 |
-
&& (distance(strongKing, strongPawn + NORTH) < distance(weakKing, strongPawn) + tempo))))
|
| 745 |
-
return ScaleFactor( SCALE_FACTOR_MAX
|
| 746 |
-
- 8 * distance(strongPawn, queeningSquare)
|
| 747 |
-
- 2 * distance(strongKing, queeningSquare));
|
| 748 |
-
|
| 749 |
-
// If the pawn is not far advanced and the defending king is somewhere in
|
| 750 |
-
// the pawn's path, it's probably a draw.
|
| 751 |
-
if (pawnRank <= RANK_4 && weakKing > strongPawn)
|
| 752 |
-
{
|
| 753 |
-
if (file_of(weakKing) == file_of(strongPawn))
|
| 754 |
-
return ScaleFactor(10);
|
| 755 |
-
if ( distance<File>(weakKing, strongPawn) == 1
|
| 756 |
-
&& distance(strongKing, weakKing) > 2)
|
| 757 |
-
return ScaleFactor(24 - 2 * distance(strongKing, weakKing));
|
| 758 |
-
}
|
| 759 |
-
return SCALE_FACTOR_NONE;
|
| 760 |
-
}
|
| 761 |
-
|
| 762 |
-
template<>
|
| 763 |
-
ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const {
|
| 764 |
-
|
| 765 |
-
assert(verify_material(pos, strongSide, RookValueMg, 1));
|
| 766 |
-
assert(verify_material(pos, weakSide, BishopValueMg, 0));
|
| 767 |
-
|
| 768 |
-
// Test for a rook pawn
|
| 769 |
-
if (pos.pieces(PAWN) & (FileABB | FileHBB))
|
| 770 |
-
{
|
| 771 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 772 |
-
Square weakBishop = pos.square<BISHOP>(weakSide);
|
| 773 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 774 |
-
Square strongPawn = pos.square<PAWN>(strongSide);
|
| 775 |
-
Rank pawnRank = relative_rank(strongSide, strongPawn);
|
| 776 |
-
Direction push = pawn_push(strongSide);
|
| 777 |
-
|
| 778 |
-
// If the pawn is on the 5th rank and the pawn (currently) is on
|
| 779 |
-
// the same color square as the bishop then there is a chance of
|
| 780 |
-
// a fortress. Depending on the king position give a moderate
|
| 781 |
-
// reduction or a stronger one if the defending king is near the
|
| 782 |
-
// corner but not trapped there.
|
| 783 |
-
if (pawnRank == RANK_5 && !opposite_colors(weakBishop, strongPawn))
|
| 784 |
-
{
|
| 785 |
-
int d = distance(strongPawn + 3 * push, weakKing);
|
| 786 |
-
|
| 787 |
-
if (d <= 2 && !(d == 0 && weakKing == strongKing + 2 * push))
|
| 788 |
-
return ScaleFactor(24);
|
| 789 |
-
else
|
| 790 |
-
return ScaleFactor(48);
|
| 791 |
-
}
|
| 792 |
-
|
| 793 |
-
// When the pawn has moved to the 6th rank we can be fairly sure
|
| 794 |
-
// it's drawn if the bishop attacks the square in front of the
|
| 795 |
-
// pawn from a reasonable distance and the defending king is near
|
| 796 |
-
// the corner
|
| 797 |
-
if ( pawnRank == RANK_6
|
| 798 |
-
&& distance(strongPawn + 2 * push, weakKing) <= 1
|
| 799 |
-
&& (attacks_bb<BISHOP>(weakBishop) & (strongPawn + push))
|
| 800 |
-
&& distance<File>(weakBishop, strongPawn) >= 2)
|
| 801 |
-
return ScaleFactor(8);
|
| 802 |
-
}
|
| 803 |
-
|
| 804 |
-
return SCALE_FACTOR_NONE;
|
| 805 |
-
}
|
| 806 |
-
|
| 807 |
-
/// KRPP vs KRP. There is just a single rule: if the stronger side has no passed
|
| 808 |
-
/// pawns and the defending king is actively placed, the position is drawish.
|
| 809 |
-
template<>
|
| 810 |
-
ScaleFactor Endgame<KRPPKRP>::operator()(const Position& pos) const {
|
| 811 |
-
|
| 812 |
-
assert(verify_material(pos, strongSide, RookValueMg, 2));
|
| 813 |
-
assert(verify_material(pos, weakSide, RookValueMg, 1));
|
| 814 |
-
|
| 815 |
-
Square strongPawn1 = lsb(pos.pieces(strongSide, PAWN));
|
| 816 |
-
Square strongPawn2 = msb(pos.pieces(strongSide, PAWN));
|
| 817 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 818 |
-
|
| 819 |
-
// Does the stronger side have a passed pawn?
|
| 820 |
-
if (pos.pawn_passed(strongSide, strongPawn1) || pos.pawn_passed(strongSide, strongPawn2))
|
| 821 |
-
return SCALE_FACTOR_NONE;
|
| 822 |
-
|
| 823 |
-
Rank pawnRank = std::max(relative_rank(strongSide, strongPawn1), relative_rank(strongSide, strongPawn2));
|
| 824 |
-
|
| 825 |
-
if ( distance<File>(weakKing, strongPawn1) <= 1
|
| 826 |
-
&& distance<File>(weakKing, strongPawn2) <= 1
|
| 827 |
-
&& relative_rank(strongSide, weakKing) > pawnRank)
|
| 828 |
-
{
|
| 829 |
-
assert(pawnRank > RANK_1 && pawnRank < RANK_7);
|
| 830 |
-
return ScaleFactor(7 * pawnRank);
|
| 831 |
-
}
|
| 832 |
-
return SCALE_FACTOR_NONE;
|
| 833 |
-
}
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
/// K and two or more pawns vs K. There is just a single rule here: if all pawns
|
| 837 |
-
/// are on the same rook file and are blocked by the defending king, it's a draw.
|
| 838 |
-
template<>
|
| 839 |
-
ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
|
| 840 |
-
|
| 841 |
-
assert(pos.non_pawn_material(strongSide) == VALUE_ZERO);
|
| 842 |
-
assert(pos.count<PAWN>(strongSide) >= 2);
|
| 843 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 0));
|
| 844 |
-
|
| 845 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 846 |
-
Bitboard strongPawns = pos.pieces(strongSide, PAWN);
|
| 847 |
-
|
| 848 |
-
// If all pawns are ahead of the king on a single rook file, it's a draw.
|
| 849 |
-
if ( !(strongPawns & ~(FileABB | FileHBB))
|
| 850 |
-
&& !(strongPawns & ~passed_pawn_span(weakSide, weakKing)))
|
| 851 |
-
return SCALE_FACTOR_DRAW;
|
| 852 |
-
|
| 853 |
-
return SCALE_FACTOR_NONE;
|
| 854 |
-
}
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
/// KBP vs KB. There are two rules: if the defending king is somewhere along the
|
| 858 |
-
/// path of the pawn, and the square of the king is not of the same color as the
|
| 859 |
-
/// stronger side's bishop, it's a draw. If the two bishops have opposite color,
|
| 860 |
-
/// it's almost always a draw.
|
| 861 |
-
template<>
|
| 862 |
-
ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
|
| 863 |
-
|
| 864 |
-
assert(verify_material(pos, strongSide, BishopValueMg, 1));
|
| 865 |
-
assert(verify_material(pos, weakSide, BishopValueMg, 0));
|
| 866 |
-
|
| 867 |
-
Square strongPawn = pos.square<PAWN>(strongSide);
|
| 868 |
-
Square strongBishop = pos.square<BISHOP>(strongSide);
|
| 869 |
-
Square weakBishop = pos.square<BISHOP>(weakSide);
|
| 870 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 871 |
-
|
| 872 |
-
// Case 1: Defending king blocks the pawn, and cannot be driven away
|
| 873 |
-
if ( (forward_file_bb(strongSide, strongPawn) & weakKing)
|
| 874 |
-
&& ( opposite_colors(weakKing, strongBishop)
|
| 875 |
-
|| relative_rank(strongSide, weakKing) <= RANK_6))
|
| 876 |
-
return SCALE_FACTOR_DRAW;
|
| 877 |
-
|
| 878 |
-
// Case 2: Opposite colored bishops
|
| 879 |
-
if (opposite_colors(strongBishop, weakBishop))
|
| 880 |
-
return SCALE_FACTOR_DRAW;
|
| 881 |
-
|
| 882 |
-
return SCALE_FACTOR_NONE;
|
| 883 |
-
}
|
| 884 |
-
|
| 885 |
-
|
| 886 |
-
/// KBPP vs KB. It detects a few basic draws with opposite-colored bishops
|
| 887 |
-
template<>
|
| 888 |
-
ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
|
| 889 |
-
|
| 890 |
-
assert(verify_material(pos, strongSide, BishopValueMg, 2));
|
| 891 |
-
assert(verify_material(pos, weakSide, BishopValueMg, 0));
|
| 892 |
-
|
| 893 |
-
Square strongBishop = pos.square<BISHOP>(strongSide);
|
| 894 |
-
Square weakBishop = pos.square<BISHOP>(weakSide);
|
| 895 |
-
|
| 896 |
-
if (!opposite_colors(strongBishop, weakBishop))
|
| 897 |
-
return SCALE_FACTOR_NONE;
|
| 898 |
-
|
| 899 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 900 |
-
Square strongPawn1 = lsb(pos.pieces(strongSide, PAWN));
|
| 901 |
-
Square strongPawn2 = msb(pos.pieces(strongSide, PAWN));
|
| 902 |
-
Square blockSq1, blockSq2;
|
| 903 |
-
|
| 904 |
-
if (relative_rank(strongSide, strongPawn1) > relative_rank(strongSide, strongPawn2))
|
| 905 |
-
{
|
| 906 |
-
blockSq1 = strongPawn1 + pawn_push(strongSide);
|
| 907 |
-
blockSq2 = make_square(file_of(strongPawn2), rank_of(strongPawn1));
|
| 908 |
-
}
|
| 909 |
-
else
|
| 910 |
-
{
|
| 911 |
-
blockSq1 = strongPawn2 + pawn_push(strongSide);
|
| 912 |
-
blockSq2 = make_square(file_of(strongPawn1), rank_of(strongPawn2));
|
| 913 |
-
}
|
| 914 |
-
|
| 915 |
-
switch (distance<File>(strongPawn1, strongPawn2))
|
| 916 |
-
{
|
| 917 |
-
case 0:
|
| 918 |
-
// Both pawns are on the same file. It's an easy draw if the defender firmly
|
| 919 |
-
// controls some square in the frontmost pawn's path.
|
| 920 |
-
if ( file_of(weakKing) == file_of(blockSq1)
|
| 921 |
-
&& relative_rank(strongSide, weakKing) >= relative_rank(strongSide, blockSq1)
|
| 922 |
-
&& opposite_colors(weakKing, strongBishop))
|
| 923 |
-
return SCALE_FACTOR_DRAW;
|
| 924 |
-
else
|
| 925 |
-
return SCALE_FACTOR_NONE;
|
| 926 |
-
|
| 927 |
-
case 1:
|
| 928 |
-
// Pawns on adjacent files. It's a draw if the defender firmly controls the
|
| 929 |
-
// square in front of the frontmost pawn's path, and the square diagonally
|
| 930 |
-
// behind this square on the file of the other pawn.
|
| 931 |
-
if ( weakKing == blockSq1
|
| 932 |
-
&& opposite_colors(weakKing, strongBishop)
|
| 933 |
-
&& ( weakBishop == blockSq2
|
| 934 |
-
|| (attacks_bb<BISHOP>(blockSq2, pos.pieces()) & pos.pieces(weakSide, BISHOP))
|
| 935 |
-
|| distance<Rank>(strongPawn1, strongPawn2) >= 2))
|
| 936 |
-
return SCALE_FACTOR_DRAW;
|
| 937 |
-
|
| 938 |
-
else if ( weakKing == blockSq2
|
| 939 |
-
&& opposite_colors(weakKing, strongBishop)
|
| 940 |
-
&& ( weakBishop == blockSq1
|
| 941 |
-
|| (attacks_bb<BISHOP>(blockSq1, pos.pieces()) & pos.pieces(weakSide, BISHOP))))
|
| 942 |
-
return SCALE_FACTOR_DRAW;
|
| 943 |
-
else
|
| 944 |
-
return SCALE_FACTOR_NONE;
|
| 945 |
-
|
| 946 |
-
default:
|
| 947 |
-
// The pawns are not on the same file or adjacent files. No scaling.
|
| 948 |
-
return SCALE_FACTOR_NONE;
|
| 949 |
-
}
|
| 950 |
-
}
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
/// KBP vs KN. There is a single rule: if the defending king is somewhere along
|
| 954 |
-
/// the path of the pawn, and the square of the king is not of the same color as
|
| 955 |
-
/// the stronger side's bishop, it's a draw.
|
| 956 |
-
template<>
|
| 957 |
-
ScaleFactor Endgame<KBPKN>::operator()(const Position& pos) const {
|
| 958 |
-
|
| 959 |
-
assert(verify_material(pos, strongSide, BishopValueMg, 1));
|
| 960 |
-
assert(verify_material(pos, weakSide, KnightValueMg, 0));
|
| 961 |
-
|
| 962 |
-
Square strongPawn = pos.square<PAWN>(strongSide);
|
| 963 |
-
Square strongBishop = pos.square<BISHOP>(strongSide);
|
| 964 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 965 |
-
|
| 966 |
-
if ( file_of(weakKing) == file_of(strongPawn)
|
| 967 |
-
&& relative_rank(strongSide, strongPawn) < relative_rank(strongSide, weakKing)
|
| 968 |
-
&& ( opposite_colors(weakKing, strongBishop)
|
| 969 |
-
|| relative_rank(strongSide, weakKing) <= RANK_6))
|
| 970 |
-
return SCALE_FACTOR_DRAW;
|
| 971 |
-
|
| 972 |
-
return SCALE_FACTOR_NONE;
|
| 973 |
-
}
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
/// KP vs KP. This is done by removing the weakest side's pawn and probing the
|
| 977 |
-
/// KP vs K bitbase: if the weakest side has a draw without the pawn, it probably
|
| 978 |
-
/// has at least a draw with the pawn as well. The exception is when the stronger
|
| 979 |
-
/// side's pawn is far advanced and not on a rook file; in this case it is often
|
| 980 |
-
/// possible to win (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1).
|
| 981 |
-
template<>
|
| 982 |
-
ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const {
|
| 983 |
-
|
| 984 |
-
assert(verify_material(pos, strongSide, VALUE_ZERO, 1));
|
| 985 |
-
assert(verify_material(pos, weakSide, VALUE_ZERO, 1));
|
| 986 |
-
|
| 987 |
-
// Assume strongSide is white and the pawn is on files A-D
|
| 988 |
-
Square strongKing = normalize(pos, strongSide, pos.square<KING>(strongSide));
|
| 989 |
-
Square weakKing = normalize(pos, strongSide, pos.square<KING>(weakSide));
|
| 990 |
-
Square strongPawn = normalize(pos, strongSide, pos.square<PAWN>(strongSide));
|
| 991 |
-
|
| 992 |
-
Color us = strongSide == pos.side_to_move() ? WHITE : BLACK;
|
| 993 |
-
|
| 994 |
-
// If the pawn has advanced to the fifth rank or further, and is not a
|
| 995 |
-
// rook pawn, it's too dangerous to assume that it's at least a draw.
|
| 996 |
-
if (rank_of(strongPawn) >= RANK_5 && file_of(strongPawn) != FILE_A)
|
| 997 |
-
return SCALE_FACTOR_NONE;
|
| 998 |
-
|
| 999 |
-
// Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw,
|
| 1000 |
-
// it's probably at least a draw even with the pawn.
|
| 1001 |
-
if ( pos.promotion_zone(us) != rank_bb(relative_rank(us, RANK_8, pos.max_rank()))
|
| 1002 |
-
|| RANK_MAX != RANK_8
|
| 1003 |
-
|| !(pos.promotion_piece_types(us) & QUEEN))
|
| 1004 |
-
return SCALE_FACTOR_NONE;
|
| 1005 |
-
|
| 1006 |
-
return Bitbases::probe(strongKing, strongPawn, weakKing, us) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW;
|
| 1007 |
-
}
|
| 1008 |
-
|
| 1009 |
-
|
| 1010 |
-
/// Endgame evals for special variants
|
| 1011 |
-
/// R vs K. The rook side always wins if there is no immediate forced capture.
|
| 1012 |
-
template<>
|
| 1013 |
-
Value Endgame<RK, EG_EVAL_ANTI>::operator()(const Position& pos) const {
|
| 1014 |
-
|
| 1015 |
-
assert(pos.endgame_eval() == EG_EVAL_ANTI);
|
| 1016 |
-
|
| 1017 |
-
Square RSq = pos.square<ROOK>(strongSide);
|
| 1018 |
-
Square KSq = pos.square<COMMONER>(weakSide);
|
| 1019 |
-
|
| 1020 |
-
Value result = Value(push_to_edge(KSq, pos)) + push_close(RSq, KSq);
|
| 1021 |
-
|
| 1022 |
-
int dist_min = std::min(distance<Rank>(RSq, KSq), distance<File>(RSq, KSq));
|
| 1023 |
-
int dist_max = std::max(distance<Rank>(RSq, KSq), distance<File>(RSq, KSq));
|
| 1024 |
-
|
| 1025 |
-
if (dist_min == 0)
|
| 1026 |
-
result += strongSide == pos.side_to_move() || dist_max > 1 ? -VALUE_KNOWN_WIN : VALUE_KNOWN_WIN;
|
| 1027 |
-
else if (dist_min == 1)
|
| 1028 |
-
result += weakSide == pos.side_to_move() && dist_max > 1 ? -VALUE_KNOWN_WIN : VALUE_KNOWN_WIN;
|
| 1029 |
-
else
|
| 1030 |
-
result += VALUE_KNOWN_WIN;
|
| 1031 |
-
|
| 1032 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1033 |
-
}
|
| 1034 |
-
|
| 1035 |
-
|
| 1036 |
-
/// K vs N. The king usually wins, but there are a few exceptions.
|
| 1037 |
-
template<>
|
| 1038 |
-
Value Endgame<KN, EG_EVAL_ANTI>::operator()(const Position& pos) const {
|
| 1039 |
-
|
| 1040 |
-
assert(pos.endgame_eval() == EG_EVAL_ANTI);
|
| 1041 |
-
|
| 1042 |
-
Square KSq = pos.square<COMMONER>(strongSide);
|
| 1043 |
-
Square NSq = pos.square<KNIGHT>(weakSide);
|
| 1044 |
-
Bitboard kingAttacks = attacks_bb<KING>(KSq) & pos.board_bb();
|
| 1045 |
-
Bitboard knightAttacks = attacks_bb<KNIGHT>(NSq) & pos.board_bb();
|
| 1046 |
-
bool strongSideToMove = pos.side_to_move() == strongSide;
|
| 1047 |
-
|
| 1048 |
-
// Loss in 1 play
|
| 1049 |
-
if (strongSideToMove ? kingAttacks & NSq : knightAttacks & KSq)
|
| 1050 |
-
return VALUE_TB_LOSS_IN_MAX_PLY + 1;
|
| 1051 |
-
// Win in 2 ply
|
| 1052 |
-
if (kingAttacks & knightAttacks)
|
| 1053 |
-
return VALUE_TB_WIN_IN_MAX_PLY - 2;
|
| 1054 |
-
// Loss in 3 ply
|
| 1055 |
-
if (strongSideToMove ? knightAttacks & KSq : kingAttacks & NSq)
|
| 1056 |
-
return VALUE_TB_LOSS_IN_MAX_PLY + 3;
|
| 1057 |
-
|
| 1058 |
-
Value result = Value(push_to_edge(NSq, pos)) - push_to_edge(KSq, pos);
|
| 1059 |
-
// The king usually wins, but scenarios with king on the edge are more complicated
|
| 1060 |
-
if (!(KSq & (FileABB | FileHBB | Rank1BB | Rank8BB)))
|
| 1061 |
-
result += VALUE_KNOWN_WIN;
|
| 1062 |
-
|
| 1063 |
-
return strongSideToMove ? result : -result;
|
| 1064 |
-
}
|
| 1065 |
-
|
| 1066 |
-
/// N vs N. The side to move always wins/loses if the knights are on
|
| 1067 |
-
/// same/opposite colored squares.
|
| 1068 |
-
template<>
|
| 1069 |
-
Value Endgame<NN, EG_EVAL_ANTI>::operator()(const Position& pos) const {
|
| 1070 |
-
|
| 1071 |
-
assert(pos.endgame_eval() == EG_EVAL_ANTI);
|
| 1072 |
-
|
| 1073 |
-
Square N1Sq = pos.square<KNIGHT>(pos.side_to_move());
|
| 1074 |
-
Square N2Sq = pos.square<KNIGHT>(~pos.side_to_move());
|
| 1075 |
-
|
| 1076 |
-
Value result = VALUE_KNOWN_WIN + push_close(N1Sq, N2Sq);
|
| 1077 |
-
|
| 1078 |
-
return !opposite_colors(N1Sq, N2Sq) ? result : -result;
|
| 1079 |
-
}
|
| 1080 |
-
|
| 1081 |
-
|
| 1082 |
-
template<>
|
| 1083 |
-
Value Endgame<KXK, EG_EVAL_ATOMIC>::operator()(const Position& pos) const {
|
| 1084 |
-
|
| 1085 |
-
assert(pos.endgame_eval() == EG_EVAL_ATOMIC);
|
| 1086 |
-
|
| 1087 |
-
// Stalemate/checkmate detection with lone king
|
| 1088 |
-
if (pos.side_to_move() == weakSide && !MoveList<LEGAL>(pos).size())
|
| 1089 |
-
return std::min(pos.stalemate_value(), VALUE_MATE_IN_MAX_PLY - 1);
|
| 1090 |
-
|
| 1091 |
-
Square winnerKSq = pos.square<COMMONER>(strongSide);
|
| 1092 |
-
Square loserKSq = pos.square<COMMONER>(weakSide);
|
| 1093 |
-
|
| 1094 |
-
Value result = pos.non_pawn_material(strongSide)
|
| 1095 |
-
+ pos.count<PAWN>(strongSide) * PawnValueEg
|
| 1096 |
-
+ push_to_edge(loserKSq, pos)
|
| 1097 |
-
+ push_away(winnerKSq, loserKSq);
|
| 1098 |
-
|
| 1099 |
-
// We need at least a major and a minor, or three minors to force checkmate
|
| 1100 |
-
if ( ((pos.count<QUEEN>(strongSide) || pos.count<ROOK>(strongSide)) && pos.count<ALL_PIECES>(strongSide) >= 3)
|
| 1101 |
-
|| (pos.count<BISHOP>(strongSide) + pos.count<KNIGHT>(strongSide) >= 3
|
| 1102 |
-
&& (pos.count<KNIGHT>(strongSide) >= 2 || ((pos.pieces(strongSide, BISHOP) & DarkSquares)
|
| 1103 |
-
&& (pos.pieces(strongSide, BISHOP) & ~DarkSquares)))))
|
| 1104 |
-
result = std::min(result + VALUE_KNOWN_WIN, VALUE_MATE_IN_MAX_PLY - 1);
|
| 1105 |
-
|
| 1106 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1107 |
-
}
|
| 1108 |
-
|
| 1109 |
-
template<>
|
| 1110 |
-
Value Endgame<KPK, EG_EVAL_ATOMIC>::operator()(const Position& pos) const {
|
| 1111 |
-
|
| 1112 |
-
assert(pos.endgame_eval() == EG_EVAL_ATOMIC);
|
| 1113 |
-
|
| 1114 |
-
Square winnerKSq = pos.square<COMMONER>(strongSide);
|
| 1115 |
-
Square loserKSq = pos.square<COMMONER>(weakSide);
|
| 1116 |
-
|
| 1117 |
-
int dist = distance(winnerKSq, loserKSq);
|
| 1118 |
-
// Draw in case of adjacent kings
|
| 1119 |
-
if (dist <= (strongSide == pos.side_to_move() ? 1 : 2))
|
| 1120 |
-
return VALUE_DRAW;
|
| 1121 |
-
|
| 1122 |
-
Value result = PawnValueEg
|
| 1123 |
-
+ 20 * relative_rank(strongSide, pos.square<PAWN>(strongSide), pos.max_rank()) - 20
|
| 1124 |
-
+ push_away(winnerKSq, loserKSq);
|
| 1125 |
-
|
| 1126 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1127 |
-
}
|
| 1128 |
-
|
| 1129 |
-
template<> Value Endgame<KNK, EG_EVAL_ATOMIC>::operator()(const Position&) const { return VALUE_DRAW; }
|
| 1130 |
-
|
| 1131 |
-
template<> Value Endgame<KBK, EG_EVAL_ATOMIC>::operator()(const Position&) const { return VALUE_DRAW; }
|
| 1132 |
-
|
| 1133 |
-
template<> Value Endgame<KRK, EG_EVAL_ATOMIC>::operator()(const Position&) const { return VALUE_DRAW; }
|
| 1134 |
-
|
| 1135 |
-
template<>
|
| 1136 |
-
Value Endgame<KQK, EG_EVAL_ATOMIC>::operator()(const Position& pos) const {
|
| 1137 |
-
|
| 1138 |
-
assert(pos.endgame_eval() == EG_EVAL_ATOMIC);
|
| 1139 |
-
|
| 1140 |
-
// Stalemate/checkmate detection with lone king
|
| 1141 |
-
if (pos.side_to_move() == weakSide && !MoveList<LEGAL>(pos).size())
|
| 1142 |
-
return std::min(pos.stalemate_value(), VALUE_MATE_IN_MAX_PLY - 1);
|
| 1143 |
-
|
| 1144 |
-
Square winnerKSq = pos.square<COMMONER>(strongSide);
|
| 1145 |
-
Square loserKSq = pos.square<COMMONER>(weakSide);
|
| 1146 |
-
|
| 1147 |
-
int dist = distance(winnerKSq, loserKSq);
|
| 1148 |
-
// Draw in case of adjacent kings
|
| 1149 |
-
if (dist == 1)
|
| 1150 |
-
return VALUE_DRAW;
|
| 1151 |
-
// If the weaker side is to move and there is a way to connect kings, it is a draw
|
| 1152 |
-
if ( pos.side_to_move() == weakSide
|
| 1153 |
-
&& (attacks_bb<KING>(winnerKSq) & attacks_bb<KING>(loserKSq) & ~pos.pieces()))
|
| 1154 |
-
return VALUE_DRAW;
|
| 1155 |
-
|
| 1156 |
-
Value result = Value(push_to_edge(loserKSq, pos))
|
| 1157 |
-
+ push_away(winnerKSq, loserKSq);
|
| 1158 |
-
|
| 1159 |
-
if (dist >= (strongSide == pos.side_to_move() ? 3 : 4))
|
| 1160 |
-
result += VALUE_KNOWN_WIN;
|
| 1161 |
-
|
| 1162 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1163 |
-
}
|
| 1164 |
-
|
| 1165 |
-
template<> Value Endgame<KNNK, EG_EVAL_ATOMIC>::operator()(const Position&) const { return VALUE_DRAW; }
|
| 1166 |
-
|
| 1167 |
-
|
| 1168 |
-
/// Self-mate with KX vs KX.
|
| 1169 |
-
template<>
|
| 1170 |
-
Value Endgame<KXKX, EG_EVAL_MISERE>::operator()(const Position& pos) const {
|
| 1171 |
-
|
| 1172 |
-
assert(!pos.checkers()); // Eval is never called when in check
|
| 1173 |
-
|
| 1174 |
-
// Stalemate detection with lone king
|
| 1175 |
-
if (pos.side_to_move() == weakSide && !MoveList<LEGAL>(pos).size())
|
| 1176 |
-
return VALUE_DRAW;
|
| 1177 |
-
|
| 1178 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 1179 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 1180 |
-
|
| 1181 |
-
Value result = pos.non_pawn_material(strongSide) * int(VALUE_KNOWN_WIN) / int(VALUE_KNOWN_WIN + pos.non_pawn_material(strongSide))
|
| 1182 |
-
- pos.non_pawn_material(weakSide)
|
| 1183 |
-
+ pos.count<PAWN>(weakSide) * PawnValueEg
|
| 1184 |
-
+ push_to_opposing_edge(relative_square(weakSide, strongKing, pos.max_rank()), pos) * 2
|
| 1185 |
-
+ push_close(strongKing, weakKing) * 2;
|
| 1186 |
-
|
| 1187 |
-
for (Bitboard b = pos.pieces(PAWN); b;)
|
| 1188 |
-
{
|
| 1189 |
-
Square s = pop_lsb(b);
|
| 1190 |
-
result += (push_close(strongKing, s) + push_close(weakKing, s)) / 2;
|
| 1191 |
-
}
|
| 1192 |
-
|
| 1193 |
-
if (!pos.count<PAWN>(weakSide))
|
| 1194 |
-
result = VALUE_DRAW;
|
| 1195 |
-
else if (pos.count<PAWN>(weakSide) == 1)
|
| 1196 |
-
result = result / 2;
|
| 1197 |
-
|
| 1198 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1199 |
-
}
|
| 1200 |
-
|
| 1201 |
-
|
| 1202 |
-
/// Mate with KX vs K. This function is used to evaluate positions with
|
| 1203 |
-
/// king and plenty of material vs a lone king. It simply gives the
|
| 1204 |
-
/// attacking side a bonus for driving the defending king towards the edge
|
| 1205 |
-
/// of the board, and for keeping the distance between the two kings small.
|
| 1206 |
-
template<>
|
| 1207 |
-
Value Endgame<KXK, EG_EVAL_DUCK>::operator()(const Position& pos) const {
|
| 1208 |
-
|
| 1209 |
-
Square strongKing = pos.square<COMMONER>(strongSide);
|
| 1210 |
-
Square weakKing = pos.square<COMMONER>(weakSide);
|
| 1211 |
-
|
| 1212 |
-
Value result = pos.non_pawn_material(strongSide)
|
| 1213 |
-
+ pos.count<PAWN>(strongSide) * PawnValueEg
|
| 1214 |
-
+ push_to_edge(weakKing, pos)
|
| 1215 |
-
+ push_close(strongKing, weakKing);
|
| 1216 |
-
|
| 1217 |
-
result = std::min(result + VALUE_KNOWN_WIN, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
| 1218 |
-
|
| 1219 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1220 |
-
}
|
| 1221 |
-
|
| 1222 |
-
|
| 1223 |
-
/// Drawish, but king should stay away from the edge
|
| 1224 |
-
template<>
|
| 1225 |
-
Value Endgame<KNK, EG_EVAL_DUCK>::operator()(const Position& pos) const {
|
| 1226 |
-
|
| 1227 |
-
Square strongKing = pos.square<COMMONER>(strongSide);
|
| 1228 |
-
Square weakKing = pos.square<COMMONER>(weakSide);
|
| 1229 |
-
|
| 1230 |
-
Value result = Value(push_to_edge(weakKing, pos))
|
| 1231 |
-
+ push_close(strongKing, weakKing);
|
| 1232 |
-
|
| 1233 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1234 |
-
}
|
| 1235 |
-
|
| 1236 |
-
|
| 1237 |
-
/// Drawish, but king should stay away from the edge
|
| 1238 |
-
template<>
|
| 1239 |
-
Value Endgame<KBK, EG_EVAL_DUCK>::operator()(const Position& pos) const {
|
| 1240 |
-
|
| 1241 |
-
Square strongKing = pos.square<COMMONER>(strongSide);
|
| 1242 |
-
Square weakKing = pos.square<COMMONER>(weakSide);
|
| 1243 |
-
|
| 1244 |
-
Value result = Value(push_to_edge(weakKing, pos))
|
| 1245 |
-
+ push_close(strongKing, weakKing);
|
| 1246 |
-
|
| 1247 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1248 |
-
}
|
| 1249 |
-
|
| 1250 |
-
|
| 1251 |
-
/// Winning as long as pawn is safe
|
| 1252 |
-
template<>
|
| 1253 |
-
Value Endgame<KPK, EG_EVAL_DUCK>::operator()(const Position& pos) const {
|
| 1254 |
-
|
| 1255 |
-
Square strongKing = pos.square<COMMONER>(strongSide);
|
| 1256 |
-
Square weakKing = pos.square<COMMONER>(weakSide);
|
| 1257 |
-
Square strongPawn = pos.square<PAWN>(strongSide);
|
| 1258 |
-
|
| 1259 |
-
Value result = PawnValueEg + 50 * relative_rank(strongSide, strongPawn, pos.max_rank())
|
| 1260 |
-
+ push_to_edge(weakKing, pos)
|
| 1261 |
-
+ push_close(strongKing, weakKing)
|
| 1262 |
-
+ push_close(strongKing, strongPawn) / 2
|
| 1263 |
-
+ push_away(weakKing, strongPawn) / 2;
|
| 1264 |
-
|
| 1265 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1266 |
-
}
|
| 1267 |
-
|
| 1268 |
-
/// Winning as long as last rank can be blocked
|
| 1269 |
-
template<>
|
| 1270 |
-
Value Endgame<KQK, EG_EVAL_RK>::operator()(const Position& pos) const {
|
| 1271 |
-
|
| 1272 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 1273 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 1274 |
-
Square strongQueen = pos.square<QUEEN>(strongSide);
|
| 1275 |
-
|
| 1276 |
-
Value result;
|
| 1277 |
-
|
| 1278 |
-
if ( rank_of(weakKing) < rank_of(strongQueen)
|
| 1279 |
-
|| rank_of(weakKing) + (weakSide == pos.side_to_move()) < RANK_7
|
| 1280 |
-
|| (Rank8BB & attacks_bb<QUEEN>(strongQueen, pos.pieces()) & ~(attacks_bb<QUEEN>(weakKing) | attacks_bb<SHOGI_KNIGHT>(weakKing))))
|
| 1281 |
-
result = VALUE_KNOWN_WIN + 100 * rank_of(strongKing);
|
| 1282 |
-
else
|
| 1283 |
-
result = -VALUE_KNOWN_WIN;
|
| 1284 |
-
|
| 1285 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1286 |
-
}
|
| 1287 |
-
|
| 1288 |
-
/// Winning as long as last rank can be blocked
|
| 1289 |
-
template<>
|
| 1290 |
-
Value Endgame<KRK, EG_EVAL_RK>::operator()(const Position& pos) const {
|
| 1291 |
-
|
| 1292 |
-
Square strongKing = pos.square<KING>(strongSide);
|
| 1293 |
-
Square weakKing = pos.square<KING>(weakSide);
|
| 1294 |
-
Square strongRook = pos.square<ROOK>(strongSide);
|
| 1295 |
-
|
| 1296 |
-
Value result;
|
| 1297 |
-
|
| 1298 |
-
if ( rank_of(weakKing) < rank_of(strongRook)
|
| 1299 |
-
|| rank_of(weakKing) + (weakSide == pos.side_to_move()) < RANK_7
|
| 1300 |
-
|| (Rank8BB & attacks_bb<ROOK>(strongRook, pos.pieces()) & ~(attacks_bb<QUEEN>(weakKing) | attacks_bb<SHOGI_KNIGHT>(weakKing))))
|
| 1301 |
-
result = VALUE_KNOWN_WIN + 100 * rank_of(strongKing);
|
| 1302 |
-
else
|
| 1303 |
-
result = -VALUE_KNOWN_WIN;
|
| 1304 |
-
|
| 1305 |
-
return strongSide == pos.side_to_move() ? result : -result;
|
| 1306 |
-
}
|
| 1307 |
-
|
| 1308 |
-
/// KvK. Pure race
|
| 1309 |
-
template<>
|
| 1310 |
-
Value Endgame<KK, EG_EVAL_RK>::operator()(const Position& pos) const {
|
| 1311 |
-
|
| 1312 |
-
Square whiteKing = pos.square<KING>(WHITE);
|
| 1313 |
-
Square blackKing = pos.square<KING>(BLACK);
|
| 1314 |
-
|
| 1315 |
-
Value result = (VALUE_KNOWN_WIN + 100 * std::max(rank_of(whiteKing), rank_of(blackKing)))
|
| 1316 |
-
* std::clamp(rank_of(whiteKing) - rank_of(blackKing) - (pos.side_to_move() == BLACK), -1, 1);
|
| 1317 |
-
|
| 1318 |
-
return pos.side_to_move() == WHITE ? result : -result;
|
| 1319 |
-
}
|
| 1320 |
-
|
| 1321 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/endgame.h
DELETED
|
@@ -1,148 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef ENDGAME_H_INCLUDED
|
| 20 |
-
#define ENDGAME_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <memory>
|
| 23 |
-
#include <string>
|
| 24 |
-
#include <type_traits>
|
| 25 |
-
#include <unordered_map>
|
| 26 |
-
#include <utility>
|
| 27 |
-
|
| 28 |
-
#include "position.h"
|
| 29 |
-
#include "types.h"
|
| 30 |
-
|
| 31 |
-
namespace Stockfish {
|
| 32 |
-
|
| 33 |
-
/// EndgameCode lists all supported endgame functions by corresponding codes
|
| 34 |
-
|
| 35 |
-
enum EndgameCode {
|
| 36 |
-
|
| 37 |
-
EVALUATION_FUNCTIONS,
|
| 38 |
-
KNNK, // KNN vs K
|
| 39 |
-
KNNKP, // KNN vs KP
|
| 40 |
-
KXK, // Generic "mate lone king" eval
|
| 41 |
-
KBNK, // KBN vs K
|
| 42 |
-
KPK, // KP vs K
|
| 43 |
-
KRKP, // KR vs KP
|
| 44 |
-
KRKB, // KR vs KB
|
| 45 |
-
KRKN, // KR vs KN
|
| 46 |
-
KQKP, // KQ vs KP
|
| 47 |
-
KQKR, // KQ vs KR
|
| 48 |
-
|
| 49 |
-
// Fairy piece endgames
|
| 50 |
-
KFsPsK, // KFsPsK vs K
|
| 51 |
-
KNSK, // KNS vs K
|
| 52 |
-
KNFK, // KNF vs K
|
| 53 |
-
KNSFKR, // KNSFKR vs K
|
| 54 |
-
KSFK, // KSF vs K
|
| 55 |
-
KSFKF, // KSF vs KF
|
| 56 |
-
KRKS, // KR vs KS
|
| 57 |
-
KCKR, // KC vs KR
|
| 58 |
-
KAKR, // KA vs KR
|
| 59 |
-
|
| 60 |
-
// Special
|
| 61 |
-
KXKX,
|
| 62 |
-
RK,
|
| 63 |
-
KN,
|
| 64 |
-
NN,
|
| 65 |
-
KQK,
|
| 66 |
-
KRK,
|
| 67 |
-
KBK,
|
| 68 |
-
KNK,
|
| 69 |
-
KK,
|
| 70 |
-
|
| 71 |
-
SCALING_FUNCTIONS,
|
| 72 |
-
KBPsK, // KB and pawns vs K
|
| 73 |
-
KQKRPs, // KQ vs KR and pawns
|
| 74 |
-
KRPKR, // KRP vs KR
|
| 75 |
-
KRPKB, // KRP vs KB
|
| 76 |
-
KRPPKRP, // KRPP vs KRP
|
| 77 |
-
KPsK, // K and pawns vs K
|
| 78 |
-
KBPKB, // KBP vs KB
|
| 79 |
-
KBPPKB, // KBPP vs KB
|
| 80 |
-
KBPKN, // KBP vs KN
|
| 81 |
-
KPKP // KP vs KP
|
| 82 |
-
};
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
/// Endgame functions can be of two types depending on whether they return a
|
| 86 |
-
/// Value or a ScaleFactor.
|
| 87 |
-
|
| 88 |
-
template<EndgameCode E, EndgameEval V = EG_EVAL_CHESS> using
|
| 89 |
-
eg_type = typename std::conditional<(E < SCALING_FUNCTIONS), Value, ScaleFactor>::type;
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
/// Base and derived functors for endgame evaluation and scaling functions
|
| 93 |
-
|
| 94 |
-
template<typename T>
|
| 95 |
-
struct EndgameBase {
|
| 96 |
-
|
| 97 |
-
explicit EndgameBase(Color c) : strongSide(c), weakSide(~c) {}
|
| 98 |
-
virtual ~EndgameBase() = default;
|
| 99 |
-
virtual T operator()(const Position&) const = 0;
|
| 100 |
-
|
| 101 |
-
const Color strongSide, weakSide;
|
| 102 |
-
};
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
template<EndgameCode E, EndgameEval V = EG_EVAL_CHESS, typename T = eg_type<E, V>>
|
| 106 |
-
struct Endgame : public EndgameBase<T> {
|
| 107 |
-
|
| 108 |
-
explicit Endgame(Color c) : EndgameBase<T>(c) {}
|
| 109 |
-
T operator()(const Position&) const override;
|
| 110 |
-
};
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
/// The Endgames namespace handles the pointers to endgame evaluation and scaling
|
| 114 |
-
/// base objects in two std::map. We use polymorphism to invoke the actual
|
| 115 |
-
/// endgame function by calling its virtual operator().
|
| 116 |
-
|
| 117 |
-
namespace Endgames {
|
| 118 |
-
|
| 119 |
-
template<typename T> using Ptr = std::unique_ptr<EndgameBase<T>>;
|
| 120 |
-
template<typename T> using Map = std::unordered_map<Key, Ptr<T>>;
|
| 121 |
-
|
| 122 |
-
extern std::pair<Map<Value>, Map<ScaleFactor>> maps;
|
| 123 |
-
|
| 124 |
-
void init();
|
| 125 |
-
|
| 126 |
-
template<typename T>
|
| 127 |
-
Map<T>& map() {
|
| 128 |
-
return std::get<std::is_same<T, ScaleFactor>::value>(maps);
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
template<EndgameCode E, EndgameEval V = EG_EVAL_CHESS, typename T = eg_type<E, V>>
|
| 132 |
-
void add(const std::string& code) {
|
| 133 |
-
|
| 134 |
-
StateInfo st;
|
| 135 |
-
map<T>()[Position().set(code, WHITE, &st).material_key(V)] = Ptr<T>(new Endgame<E, V>(WHITE));
|
| 136 |
-
map<T>()[Position().set(code, BLACK, &st).material_key(V)] = Ptr<T>(new Endgame<E, V>(BLACK));
|
| 137 |
-
}
|
| 138 |
-
|
| 139 |
-
template<typename T>
|
| 140 |
-
const EndgameBase<T>* probe(Key key) {
|
| 141 |
-
auto it = map<T>().find(key);
|
| 142 |
-
return it != map<T>().end() ? it->second.get() : nullptr;
|
| 143 |
-
}
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
} // namespace Stockfish
|
| 147 |
-
|
| 148 |
-
#endif // #ifndef ENDGAME_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/evaluate.cpp
DELETED
|
@@ -1,1736 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <algorithm>
|
| 20 |
-
#include <cassert>
|
| 21 |
-
#include <cstdlib>
|
| 22 |
-
#include <cstring> // For std::memset
|
| 23 |
-
#include <fstream>
|
| 24 |
-
#include <iomanip>
|
| 25 |
-
#include <sstream>
|
| 26 |
-
#include <iostream>
|
| 27 |
-
#include <streambuf>
|
| 28 |
-
#include <vector>
|
| 29 |
-
|
| 30 |
-
#include "bitboard.h"
|
| 31 |
-
#include "evaluate.h"
|
| 32 |
-
#include "material.h"
|
| 33 |
-
#include "misc.h"
|
| 34 |
-
#include "pawns.h"
|
| 35 |
-
#include "thread.h"
|
| 36 |
-
#include "timeman.h"
|
| 37 |
-
#include "uci.h"
|
| 38 |
-
#include "incbin/incbin.h"
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
// Macro to embed the default efficiently updatable neural network (NNUE) file
|
| 42 |
-
// data in the engine binary (using incbin.h, by Dale Weiler).
|
| 43 |
-
// This macro invocation will declare the following three variables
|
| 44 |
-
// const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
|
| 45 |
-
// const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
|
| 46 |
-
// const unsigned int gEmbeddedNNUESize; // the size of the embedded file
|
| 47 |
-
// Note that this does not work in Microsoft Visual Studio.
|
| 48 |
-
#if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
|
| 49 |
-
INCBIN(EmbeddedNNUE, EvalFileDefaultName);
|
| 50 |
-
#else
|
| 51 |
-
const unsigned char gEmbeddedNNUEData[1] = {0x0};
|
| 52 |
-
[[maybe_unused]]
|
| 53 |
-
const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
|
| 54 |
-
const unsigned int gEmbeddedNNUESize = 1;
|
| 55 |
-
#endif
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
using namespace std;
|
| 59 |
-
|
| 60 |
-
namespace Stockfish {
|
| 61 |
-
|
| 62 |
-
const Variant* currentNnueVariant;
|
| 63 |
-
|
| 64 |
-
namespace Eval {
|
| 65 |
-
|
| 66 |
-
bool useNNUE;
|
| 67 |
-
string eval_file_loaded = "None";
|
| 68 |
-
|
| 69 |
-
/// NNUE::init() tries to load a NNUE network at startup time, or when the engine
|
| 70 |
-
/// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
|
| 71 |
-
/// The name of the NNUE network is always retrieved from the EvalFile option.
|
| 72 |
-
/// We search the given network in three locations: internally (the default
|
| 73 |
-
/// network may be embedded in the binary), in the active working directory and
|
| 74 |
-
/// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
|
| 75 |
-
/// variable to have the engine search in a special directory in their distro.
|
| 76 |
-
|
| 77 |
-
void NNUE::init() {
|
| 78 |
-
|
| 79 |
-
useNNUE = Options["Use NNUE"];
|
| 80 |
-
if (!useNNUE)
|
| 81 |
-
return;
|
| 82 |
-
|
| 83 |
-
string eval_file = string(Options["EvalFile"]);
|
| 84 |
-
|
| 85 |
-
// Restrict NNUE usage to corresponding variant
|
| 86 |
-
// Support multiple variant networks separated by semicolon(Windows)/colon(Unix)
|
| 87 |
-
stringstream ss(eval_file);
|
| 88 |
-
string variant = string(Options["UCI_Variant"]);
|
| 89 |
-
useNNUE = false;
|
| 90 |
-
while (getline(ss, eval_file, UCI::SepChar))
|
| 91 |
-
{
|
| 92 |
-
string basename = eval_file.substr(eval_file.find_last_of("\\/") + 1);
|
| 93 |
-
string nnueAlias = variants.find(variant)->second->nnueAlias;
|
| 94 |
-
if (basename.rfind(variant, 0) != string::npos || (!nnueAlias.empty() && basename.rfind(nnueAlias, 0) != string::npos))
|
| 95 |
-
{
|
| 96 |
-
useNNUE = true;
|
| 97 |
-
break;
|
| 98 |
-
}
|
| 99 |
-
}
|
| 100 |
-
if (!useNNUE)
|
| 101 |
-
return;
|
| 102 |
-
|
| 103 |
-
currentNnueVariant = variants.find(variant)->second;
|
| 104 |
-
|
| 105 |
-
#if defined(DEFAULT_NNUE_DIRECTORY)
|
| 106 |
-
#define stringify2(x) #x
|
| 107 |
-
#define stringify(x) stringify2(x)
|
| 108 |
-
vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
|
| 109 |
-
#else
|
| 110 |
-
vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
|
| 111 |
-
#endif
|
| 112 |
-
|
| 113 |
-
for (string directory : dirs)
|
| 114 |
-
if (eval_file_loaded != eval_file)
|
| 115 |
-
{
|
| 116 |
-
if (directory != "<internal>")
|
| 117 |
-
{
|
| 118 |
-
ifstream stream(directory + eval_file, ios::binary);
|
| 119 |
-
if (load_eval(eval_file, stream))
|
| 120 |
-
eval_file_loaded = eval_file;
|
| 121 |
-
}
|
| 122 |
-
|
| 123 |
-
if (directory == "<internal>" && eval_file == EvalFileDefaultName)
|
| 124 |
-
{
|
| 125 |
-
// C++ way to prepare a buffer for a memory stream
|
| 126 |
-
class MemoryBuffer : public basic_streambuf<char> {
|
| 127 |
-
public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
|
| 128 |
-
};
|
| 129 |
-
|
| 130 |
-
MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
|
| 131 |
-
size_t(gEmbeddedNNUESize));
|
| 132 |
-
|
| 133 |
-
istream stream(&buffer);
|
| 134 |
-
if (load_eval(eval_file, stream))
|
| 135 |
-
eval_file_loaded = eval_file;
|
| 136 |
-
}
|
| 137 |
-
}
|
| 138 |
-
}
|
| 139 |
-
|
| 140 |
-
/// NNUE::verify() verifies that the last net used was loaded successfully
|
| 141 |
-
void NNUE::verify() {
|
| 142 |
-
|
| 143 |
-
string eval_file = string(Options["EvalFile"]);
|
| 144 |
-
|
| 145 |
-
if (useNNUE && eval_file.find(eval_file_loaded) == string::npos)
|
| 146 |
-
{
|
| 147 |
-
UCI::OptionsMap defaults;
|
| 148 |
-
UCI::init(defaults);
|
| 149 |
-
|
| 150 |
-
string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
|
| 151 |
-
string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
|
| 152 |
-
string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
|
| 153 |
-
string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
|
| 154 |
-
string msg5 = "The engine will be terminated now.";
|
| 155 |
-
|
| 156 |
-
sync_cout << "info string ERROR: " << msg1 << sync_endl;
|
| 157 |
-
sync_cout << "info string ERROR: " << msg2 << sync_endl;
|
| 158 |
-
sync_cout << "info string ERROR: " << msg3 << sync_endl;
|
| 159 |
-
sync_cout << "info string ERROR: " << msg4 << sync_endl;
|
| 160 |
-
sync_cout << "info string ERROR: " << msg5 << sync_endl;
|
| 161 |
-
|
| 162 |
-
exit(EXIT_FAILURE);
|
| 163 |
-
}
|
| 164 |
-
|
| 165 |
-
if (CurrentProtocol != XBOARD)
|
| 166 |
-
{
|
| 167 |
-
if (useNNUE)
|
| 168 |
-
sync_cout << "info string NNUE evaluation using " << eval_file_loaded << " enabled" << sync_endl;
|
| 169 |
-
else
|
| 170 |
-
sync_cout << "info string classical evaluation enabled" << sync_endl;
|
| 171 |
-
}
|
| 172 |
-
}
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
namespace Trace {
|
| 176 |
-
|
| 177 |
-
enum Tracing { NO_TRACE, TRACE };
|
| 178 |
-
|
| 179 |
-
enum Term { // The first PIECE_TYPE_NB entries are reserved for PieceType
|
| 180 |
-
MATERIAL = PIECE_TYPE_NB, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, VARIANT, WINNABLE, TOTAL, TERM_NB
|
| 181 |
-
};
|
| 182 |
-
|
| 183 |
-
Score scores[TERM_NB][COLOR_NB];
|
| 184 |
-
|
| 185 |
-
double to_cp(Value v) { return double(v) / PawnValueEg; }
|
| 186 |
-
|
| 187 |
-
void add(int idx, Color c, Score s) {
|
| 188 |
-
scores[idx][c] = s;
|
| 189 |
-
}
|
| 190 |
-
|
| 191 |
-
void add(int idx, Score w, Score b = SCORE_ZERO) {
|
| 192 |
-
scores[idx][WHITE] = w;
|
| 193 |
-
scores[idx][BLACK] = b;
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
std::ostream& operator<<(std::ostream& os, Score s) {
|
| 197 |
-
os << std::setw(5) << to_cp(mg_value(s)) << " "
|
| 198 |
-
<< std::setw(5) << to_cp(eg_value(s));
|
| 199 |
-
return os;
|
| 200 |
-
}
|
| 201 |
-
|
| 202 |
-
std::ostream& operator<<(std::ostream& os, Term t) {
|
| 203 |
-
|
| 204 |
-
if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
|
| 205 |
-
os << " ---- ----" << " | " << " ---- ----";
|
| 206 |
-
else
|
| 207 |
-
os << scores[t][WHITE] << " | " << scores[t][BLACK];
|
| 208 |
-
|
| 209 |
-
os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
|
| 210 |
-
return os;
|
| 211 |
-
}
|
| 212 |
-
}
|
| 213 |
-
|
| 214 |
-
using namespace Trace;
|
| 215 |
-
|
| 216 |
-
namespace {
|
| 217 |
-
|
| 218 |
-
// Threshold for lazy and space evaluation
|
| 219 |
-
constexpr Value LazyThreshold1 = Value(1565);
|
| 220 |
-
constexpr Value LazyThreshold2 = Value(1102);
|
| 221 |
-
constexpr Value SpaceThreshold = Value(11551);
|
| 222 |
-
|
| 223 |
-
// KingAttackWeights[PieceType] contains king attack weights by piece type
|
| 224 |
-
constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10, 40 };
|
| 225 |
-
|
| 226 |
-
// SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
|
| 227 |
-
// higher if multiple safe checks are possible for that piece type.
|
| 228 |
-
constexpr int SafeCheck[][2] = {
|
| 229 |
-
{}, {600, 600}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}, {600, 900}
|
| 230 |
-
};
|
| 231 |
-
|
| 232 |
-
#define S(mg, eg) make_score(mg, eg)
|
| 233 |
-
|
| 234 |
-
// MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
|
| 235 |
-
// indexed by piece type and number of attacked squares in the mobility area.
|
| 236 |
-
constexpr Score MobilityBonus[][4 * RANK_NB] = {
|
| 237 |
-
{ S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
|
| 238 |
-
S( 21, 16), S( 28, 21), S( 37, 26) },
|
| 239 |
-
{ S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
|
| 240 |
-
S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
|
| 241 |
-
S( 91, 88), S( 96, 98) },
|
| 242 |
-
{ S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
|
| 243 |
-
S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
|
| 244 |
-
S( 57,165), S( 58,170), S( 67,175) },
|
| 245 |
-
{ S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
|
| 246 |
-
S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
|
| 247 |
-
S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
|
| 248 |
-
S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
|
| 249 |
-
S(112,178), S(114,185), S(114,187), S(119,221) }
|
| 250 |
-
};
|
| 251 |
-
constexpr Score MaxMobility = S(150, 200);
|
| 252 |
-
constexpr Score DropMobility = S(10, 10);
|
| 253 |
-
|
| 254 |
-
// BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
|
| 255 |
-
// squares of the same color as our bishop.
|
| 256 |
-
constexpr Score BishopPawns[int(FILE_NB) / 2] = {
|
| 257 |
-
S(3, 8), S(3, 9), S(2, 8), S(3, 8)
|
| 258 |
-
};
|
| 259 |
-
|
| 260 |
-
// KingProtector[knight/bishop] contains penalty for each distance unit to own king
|
| 261 |
-
constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
|
| 262 |
-
|
| 263 |
-
// Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
|
| 264 |
-
// pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
|
| 265 |
-
constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
|
| 266 |
-
|
| 267 |
-
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
| 268 |
-
constexpr Score PassedRank[RANK_NB] = {
|
| 269 |
-
S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
|
| 270 |
-
};
|
| 271 |
-
|
| 272 |
-
constexpr Score RookOnClosedFile = S(10, 5);
|
| 273 |
-
constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
|
| 274 |
-
|
| 275 |
-
// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
|
| 276 |
-
// which piece type attacks which one. Attacks on lesser pieces which are
|
| 277 |
-
// pawn-defended are not considered.
|
| 278 |
-
constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
|
| 279 |
-
S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
|
| 280 |
-
};
|
| 281 |
-
|
| 282 |
-
constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
|
| 283 |
-
S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
|
| 284 |
-
};
|
| 285 |
-
|
| 286 |
-
constexpr Value CorneredBishop = Value(50);
|
| 287 |
-
|
| 288 |
-
// Assorted bonuses and penalties
|
| 289 |
-
constexpr Score UncontestedOutpost = S( 1, 10);
|
| 290 |
-
constexpr Score BishopOnKingRing = S( 24, 0);
|
| 291 |
-
constexpr Score BishopXRayPawns = S( 4, 5);
|
| 292 |
-
constexpr Score FlankAttacks = S( 8, 0);
|
| 293 |
-
constexpr Score Hanging = S( 69, 36);
|
| 294 |
-
constexpr Score KnightOnQueen = S( 16, 11);
|
| 295 |
-
constexpr Score LongDiagonalBishop = S( 45, 0);
|
| 296 |
-
constexpr Score MinorBehindPawn = S( 18, 3);
|
| 297 |
-
constexpr Score PassedFile = S( 11, 8);
|
| 298 |
-
constexpr Score PawnlessFlank = S( 17, 95);
|
| 299 |
-
constexpr Score ReachableOutpost = S( 31, 22);
|
| 300 |
-
constexpr Score RestrictedPiece = S( 7, 7);
|
| 301 |
-
constexpr Score RookOnKingRing = S( 16, 0);
|
| 302 |
-
constexpr Score SliderOnQueen = S( 60, 18);
|
| 303 |
-
constexpr Score ThreatByKing = S( 24, 89);
|
| 304 |
-
constexpr Score ThreatByPawnPush = S( 48, 39);
|
| 305 |
-
constexpr Score ThreatBySafePawn = S(173, 94);
|
| 306 |
-
constexpr Score TrappedRook = S( 55, 13);
|
| 307 |
-
constexpr Score WeakQueenProtection = S( 14, 0);
|
| 308 |
-
constexpr Score WeakQueen = S( 56, 15);
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
// Variant and fairy piece bonuses
|
| 312 |
-
constexpr Score KingProximity = S(2, 6);
|
| 313 |
-
constexpr Score EndgameKingProximity = S(0, 10);
|
| 314 |
-
constexpr Score ConnectedSoldier = S(20, 20);
|
| 315 |
-
|
| 316 |
-
constexpr int VirtualCheck = 600;
|
| 317 |
-
|
| 318 |
-
#undef S
|
| 319 |
-
|
| 320 |
-
// Evaluation class computes and stores attacks tables and other working data
|
| 321 |
-
template<Tracing T>
|
| 322 |
-
class Evaluation {
|
| 323 |
-
|
| 324 |
-
public:
|
| 325 |
-
Evaluation() = delete;
|
| 326 |
-
explicit Evaluation(const Position& p) : pos(p) {}
|
| 327 |
-
Evaluation& operator=(const Evaluation&) = delete;
|
| 328 |
-
Value value();
|
| 329 |
-
|
| 330 |
-
private:
|
| 331 |
-
template<Color Us> void initialize();
|
| 332 |
-
template<Color Us> Score pieces(PieceType Pt);
|
| 333 |
-
template<Color Us> Score hand(PieceType pt);
|
| 334 |
-
template<Color Us> Score king() const;
|
| 335 |
-
template<Color Us> Score threats() const;
|
| 336 |
-
template<Color Us> Score passed() const;
|
| 337 |
-
template<Color Us> Score space() const;
|
| 338 |
-
template<Color Us> Score variant() const;
|
| 339 |
-
Value winnable(Score score) const;
|
| 340 |
-
|
| 341 |
-
const Position& pos;
|
| 342 |
-
Material::Entry* me;
|
| 343 |
-
Pawns::Entry* pe;
|
| 344 |
-
Bitboard mobilityArea[COLOR_NB];
|
| 345 |
-
Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
|
| 346 |
-
|
| 347 |
-
// attackedBy[color][piece type] is a bitboard representing all squares
|
| 348 |
-
// attacked by a given color and piece type. Special "piece types" which
|
| 349 |
-
// is also calculated is ALL_PIECES.
|
| 350 |
-
Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
|
| 351 |
-
|
| 352 |
-
// attackedBy2[color] are the squares attacked by at least 2 units of a given
|
| 353 |
-
// color, including x-rays. But diagonal x-rays through pawns are not computed.
|
| 354 |
-
Bitboard attackedBy2[COLOR_NB];
|
| 355 |
-
|
| 356 |
-
// kingRing[color] are the squares adjacent to the king plus some other
|
| 357 |
-
// very near squares, depending on king position.
|
| 358 |
-
Bitboard kingRing[COLOR_NB];
|
| 359 |
-
|
| 360 |
-
// kingAttackersCount[color] is the number of pieces of the given color
|
| 361 |
-
// which attack a square in the kingRing of the enemy king.
|
| 362 |
-
int kingAttackersCount[COLOR_NB];
|
| 363 |
-
int kingAttackersCountInHand[COLOR_NB];
|
| 364 |
-
|
| 365 |
-
// kingAttackersWeight[color] is the sum of the "weights" of the pieces of
|
| 366 |
-
// the given color which attack a square in the kingRing of the enemy king.
|
| 367 |
-
// The weights of the individual piece types are given by the elements in
|
| 368 |
-
// the KingAttackWeights array.
|
| 369 |
-
int kingAttackersWeight[COLOR_NB];
|
| 370 |
-
int kingAttackersWeightInHand[COLOR_NB];
|
| 371 |
-
|
| 372 |
-
// kingAttacksCount[color] is the number of attacks by the given color to
|
| 373 |
-
// squares directly adjacent to the enemy king. Pieces which attack more
|
| 374 |
-
// than one square are counted multiple times. For instance, if there is
|
| 375 |
-
// a white knight on g5 and black's king is on g8, this white knight adds 2
|
| 376 |
-
// to kingAttacksCount[WHITE].
|
| 377 |
-
int kingAttacksCount[COLOR_NB];
|
| 378 |
-
};
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
// Evaluation::initialize() computes king and pawn attacks, and the king ring
|
| 382 |
-
// bitboard for a given color. This is done at the beginning of the evaluation.
|
| 383 |
-
|
| 384 |
-
template<Tracing T> template<Color Us>
|
| 385 |
-
void Evaluation<T>::initialize() {
|
| 386 |
-
|
| 387 |
-
constexpr Color Them = ~Us;
|
| 388 |
-
constexpr Direction Up = pawn_push(Us);
|
| 389 |
-
constexpr Direction Down = -Up;
|
| 390 |
-
Bitboard LowRanks = rank_bb(relative_rank(Us, RANK_2, pos.max_rank())) | rank_bb(relative_rank(Us, RANK_3, pos.max_rank()));
|
| 391 |
-
|
| 392 |
-
const Square ksq = pos.count<KING>(Us) ? pos.square<KING>(Us) : SQ_NONE;
|
| 393 |
-
|
| 394 |
-
Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
|
| 395 |
-
|
| 396 |
-
// Find our pawns that are blocked or on the first two ranks
|
| 397 |
-
Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
|
| 398 |
-
|
| 399 |
-
// Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
|
| 400 |
-
// or controlled by enemy pawns are excluded from the mobility area.
|
| 401 |
-
if (pos.must_capture())
|
| 402 |
-
mobilityArea[Us] = AllSquares;
|
| 403 |
-
else
|
| 404 |
-
mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them)
|
| 405 |
-
| (pos.pieces(Us, SHOGI_PAWN) & shift<Down>(pos.pieces(Us)))
|
| 406 |
-
| shift<Down>(pos.pieces(Them, SHOGI_PAWN, SOLDIER))
|
| 407 |
-
| shift<EAST>(pos.promoted_soldiers(Them))
|
| 408 |
-
| shift<WEST>(pos.promoted_soldiers(Them)));
|
| 409 |
-
|
| 410 |
-
// Initialize attackedBy[] for king and pawns
|
| 411 |
-
attackedBy[Us][KING] = pos.count<KING>(Us) ? pos.attacks_from(Us, KING, ksq) : Bitboard(0);
|
| 412 |
-
attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
|
| 413 |
-
attackedBy[Us][SHOGI_PAWN] = shift<Up>(pos.pieces(Us, SHOGI_PAWN));
|
| 414 |
-
attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN];
|
| 415 |
-
attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN])
|
| 416 |
-
| (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN])
|
| 417 |
-
| (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN])
|
| 418 |
-
| dblAttackByPawn;
|
| 419 |
-
|
| 420 |
-
// Init our king safety tables
|
| 421 |
-
if (!pos.count<KING>(Us))
|
| 422 |
-
kingRing[Us] = Bitboard(0);
|
| 423 |
-
else
|
| 424 |
-
{
|
| 425 |
-
Square s = make_square(std::clamp(file_of(ksq), FILE_B, File(pos.max_file() - 1)),
|
| 426 |
-
std::clamp(rank_of(ksq), RANK_2, Rank(pos.max_rank() - 1)));
|
| 427 |
-
kingRing[Us] = attacks_bb<KING>(s) | s;
|
| 428 |
-
}
|
| 429 |
-
|
| 430 |
-
kingAttackersCount[Them] = popcount(kingRing[Us] & (pe->pawn_attacks(Them) | shift<Down>(pos.pieces(Them, SHOGI_PAWN))));
|
| 431 |
-
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
|
| 432 |
-
kingAttackersCountInHand[Them] = kingAttackersWeightInHand[Them] = 0;
|
| 433 |
-
|
| 434 |
-
// Remove from kingRing[] the squares defended by two pawns
|
| 435 |
-
kingRing[Us] &= ~dblAttackByPawn;
|
| 436 |
-
|
| 437 |
-
kingRing[Us] &= pos.board_bb();
|
| 438 |
-
}
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
// Evaluation::pieces() scores pieces of a given color and type
|
| 442 |
-
|
| 443 |
-
template<Tracing T> template<Color Us>
|
| 444 |
-
Score Evaluation<T>::pieces(PieceType Pt) {
|
| 445 |
-
|
| 446 |
-
constexpr Color Them = ~Us;
|
| 447 |
-
constexpr Direction Down = -pawn_push(Us);
|
| 448 |
-
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
| 449 |
-
: Rank5BB | Rank4BB | Rank3BB);
|
| 450 |
-
Bitboard b1 = pos.pieces(Us, Pt);
|
| 451 |
-
Bitboard b, bb;
|
| 452 |
-
Score score = SCORE_ZERO;
|
| 453 |
-
|
| 454 |
-
attackedBy[Us][Pt] = 0;
|
| 455 |
-
|
| 456 |
-
while (b1)
|
| 457 |
-
{
|
| 458 |
-
Square s = pop_lsb(b1);
|
| 459 |
-
|
| 460 |
-
// Find attacked squares, including x-ray attacks for bishops and rooks
|
| 461 |
-
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
|
| 462 |
-
: Pt == ROOK && !pos.diagonal_lines() ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
|
| 463 |
-
: pos.attacks_from(Us, Pt, s);
|
| 464 |
-
|
| 465 |
-
// Restrict mobility to actual squares of board
|
| 466 |
-
b &= pos.board_bb(Us, Pt);
|
| 467 |
-
|
| 468 |
-
if (pos.blockers_for_king(Us) & s)
|
| 469 |
-
b &= line_bb(pos.square<KING>(Us), s);
|
| 470 |
-
|
| 471 |
-
attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
|
| 472 |
-
attackedBy[Us][Pt] |= b;
|
| 473 |
-
attackedBy[Us][ALL_PIECES] |= b;
|
| 474 |
-
|
| 475 |
-
if (b & kingRing[Them])
|
| 476 |
-
{
|
| 477 |
-
kingAttackersCount[Us]++;
|
| 478 |
-
kingAttackersWeight[Us] += KingAttackWeights[std::min(Pt, FAIRY_PIECES)];
|
| 479 |
-
kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
|
| 480 |
-
}
|
| 481 |
-
|
| 482 |
-
else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
|
| 483 |
-
score += RookOnKingRing;
|
| 484 |
-
|
| 485 |
-
else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
|
| 486 |
-
score += BishopOnKingRing;
|
| 487 |
-
|
| 488 |
-
if (Pt > QUEEN)
|
| 489 |
-
b = (b & pos.pieces()) | (pos.moves_from(Us, Pt, s) & ~pos.pieces() & pos.board_bb());
|
| 490 |
-
|
| 491 |
-
int mob = popcount(b & mobilityArea[Us]);
|
| 492 |
-
if (Pt <= QUEEN)
|
| 493 |
-
mobility[Us] += MobilityBonus[Pt - 2][mob];
|
| 494 |
-
else
|
| 495 |
-
mobility[Us] += MaxMobility * (mob - 2) / (8 + mob);
|
| 496 |
-
|
| 497 |
-
// Piece promotion bonus
|
| 498 |
-
if (pos.promoted_piece_type(Pt) != NO_PIECE_TYPE)
|
| 499 |
-
{
|
| 500 |
-
Bitboard zone = pos.promotion_zone(Us);
|
| 501 |
-
if (zone & (b | s))
|
| 502 |
-
score += make_score(PieceValue[MG][pos.promoted_piece_type(Pt)] - PieceValue[MG][Pt],
|
| 503 |
-
PieceValue[EG][pos.promoted_piece_type(Pt)] - PieceValue[EG][Pt]) / (zone & s && b ? 6 : 12);
|
| 504 |
-
}
|
| 505 |
-
else if (pos.piece_demotion() && pos.unpromoted_piece_on(s))
|
| 506 |
-
score -= make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)],
|
| 507 |
-
PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 4;
|
| 508 |
-
else if (pos.captures_to_hand() && pos.unpromoted_piece_on(s))
|
| 509 |
-
score += make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)],
|
| 510 |
-
PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 8;
|
| 511 |
-
|
| 512 |
-
// Penalty if the piece is far from the kings in drop variants
|
| 513 |
-
if ((pos.captures_to_hand() || pos.two_boards()) && pos.count<KING>(Them) && pos.count<KING>(Us))
|
| 514 |
-
{
|
| 515 |
-
if (!(b & (kingRing[Us] | kingRing[Them])))
|
| 516 |
-
score -= KingProximity * distance(s, pos.square<KING>(Us)) * distance(s, pos.square<KING>(Them));
|
| 517 |
-
}
|
| 518 |
-
|
| 519 |
-
else if (pos.count<KING>(Us) && (Pt == FERS || Pt == SILVER))
|
| 520 |
-
score -= EndgameKingProximity * (distance(s, pos.square<KING>(Us)) - 2);
|
| 521 |
-
|
| 522 |
-
if (Pt == SOLDIER && (pos.pieces(Us, SOLDIER) & rank_bb(s) & adjacent_files_bb(s)))
|
| 523 |
-
score += ConnectedSoldier;
|
| 524 |
-
|
| 525 |
-
if (Pt == BISHOP || Pt == KNIGHT)
|
| 526 |
-
{
|
| 527 |
-
// Bonus if the piece is on an outpost square or can reach one
|
| 528 |
-
// Bonus for knights (UncontestedOutpost) if few relevant targets
|
| 529 |
-
bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
|
| 530 |
-
& ~pe->pawn_attacks_span(Them);
|
| 531 |
-
Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
|
| 532 |
-
|
| 533 |
-
if ( Pt == KNIGHT
|
| 534 |
-
&& bb & s & ~CenterFiles // on a side outpost
|
| 535 |
-
&& !(b & targets) // no relevant attacks
|
| 536 |
-
&& (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
|
| 537 |
-
score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
|
| 538 |
-
else if (bb & s)
|
| 539 |
-
score += Outpost[Pt == BISHOP];
|
| 540 |
-
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
|
| 541 |
-
score += ReachableOutpost;
|
| 542 |
-
|
| 543 |
-
// Bonus for a knight or bishop shielded by pawn
|
| 544 |
-
if (shift<Down>(pos.pieces(PAWN)) & s)
|
| 545 |
-
score += MinorBehindPawn;
|
| 546 |
-
|
| 547 |
-
// Penalty if the piece is far from the king
|
| 548 |
-
if (pos.count<KING>(Us))
|
| 549 |
-
score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
|
| 550 |
-
|
| 551 |
-
if (Pt == BISHOP)
|
| 552 |
-
{
|
| 553 |
-
// Penalty according to the number of our pawns on the same color square as the
|
| 554 |
-
// bishop, bigger when the center files are blocked with pawns and smaller
|
| 555 |
-
// when the bishop is outside the pawn chain.
|
| 556 |
-
Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
|
| 557 |
-
|
| 558 |
-
score -= BishopPawns[edge_distance(file_of(s), pos.max_file())] * pos.pawns_on_same_color_squares(Us, s)
|
| 559 |
-
* (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
|
| 560 |
-
|
| 561 |
-
// Penalty for all enemy pawns x-rayed
|
| 562 |
-
score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
|
| 563 |
-
|
| 564 |
-
// Bonus for bishop on a long diagonal which can "see" both center squares
|
| 565 |
-
if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
|
| 566 |
-
score += LongDiagonalBishop;
|
| 567 |
-
|
| 568 |
-
// An important Chess960 pattern: a cornered bishop blocked by a friendly
|
| 569 |
-
// pawn diagonally in front of it is a very serious problem, especially
|
| 570 |
-
// when that pawn is also blocked.
|
| 571 |
-
if ( pos.is_chess960()
|
| 572 |
-
&& (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
|
| 573 |
-
{
|
| 574 |
-
Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
|
| 575 |
-
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
|
| 576 |
-
score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
|
| 577 |
-
: 3 * make_score(CorneredBishop, CorneredBishop);
|
| 578 |
-
}
|
| 579 |
-
}
|
| 580 |
-
}
|
| 581 |
-
|
| 582 |
-
if (Pt == ROOK)
|
| 583 |
-
{
|
| 584 |
-
// Bonuses for rook on a (semi-)open or closed file
|
| 585 |
-
if (pos.is_on_semiopen_file(Us, s))
|
| 586 |
-
{
|
| 587 |
-
score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
|
| 588 |
-
}
|
| 589 |
-
else
|
| 590 |
-
{
|
| 591 |
-
// If our pawn on this file is blocked, increase penalty
|
| 592 |
-
if ( pos.pieces(Us, PAWN)
|
| 593 |
-
& shift<Down>(pos.pieces())
|
| 594 |
-
& file_bb(s))
|
| 595 |
-
{
|
| 596 |
-
score -= RookOnClosedFile;
|
| 597 |
-
}
|
| 598 |
-
|
| 599 |
-
// Penalty when trapped by the king, even more if the king cannot castle
|
| 600 |
-
if (mob <= 3 && pos.count<KING>(Us))
|
| 601 |
-
{
|
| 602 |
-
File kf = file_of(pos.square<KING>(Us));
|
| 603 |
-
if ((kf < FILE_E) == (file_of(s) < kf))
|
| 604 |
-
score -= TrappedRook * (1 + !pos.castling_rights(Us));
|
| 605 |
-
}
|
| 606 |
-
}
|
| 607 |
-
}
|
| 608 |
-
|
| 609 |
-
if (Pt == QUEEN)
|
| 610 |
-
{
|
| 611 |
-
// Penalty if any relative pin or discovered attack against the queen
|
| 612 |
-
Bitboard queenPinners;
|
| 613 |
-
if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners, Them))
|
| 614 |
-
score -= WeakQueen;
|
| 615 |
-
}
|
| 616 |
-
}
|
| 617 |
-
if constexpr (T)
|
| 618 |
-
Trace::add(Pt, Us, score);
|
| 619 |
-
|
| 620 |
-
return score;
|
| 621 |
-
}
|
| 622 |
-
|
| 623 |
-
// Evaluation::hand() scores pieces of a given color and type in hand
|
| 624 |
-
template<Tracing T> template<Color Us>
|
| 625 |
-
Score Evaluation<T>::hand(PieceType pt) {
|
| 626 |
-
|
| 627 |
-
constexpr Color Them = ~Us;
|
| 628 |
-
|
| 629 |
-
Score score = SCORE_ZERO;
|
| 630 |
-
|
| 631 |
-
if (pos.count_in_hand(Us, pt) > 0 && pt != KING)
|
| 632 |
-
{
|
| 633 |
-
Bitboard b = pos.drop_region(Us, pt) & ~pos.pieces() & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
|
| 634 |
-
if ((b & kingRing[Them]) && pt != SHOGI_PAWN)
|
| 635 |
-
{
|
| 636 |
-
kingAttackersCountInHand[Us] += pos.count_in_hand(Us, pt);
|
| 637 |
-
kingAttackersWeightInHand[Us] += KingAttackWeights[std::min(pt, FAIRY_PIECES)] * pos.count_in_hand(Us, pt);
|
| 638 |
-
kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
|
| 639 |
-
}
|
| 640 |
-
Bitboard theirHalf = pos.board_bb() & ~forward_ranks_bb(Them, relative_rank(Them, Rank((pos.max_rank() - 1) / 2), pos.max_rank()));
|
| 641 |
-
mobility[Us] += DropMobility * popcount(b & theirHalf & ~attackedBy[Them][ALL_PIECES]);
|
| 642 |
-
|
| 643 |
-
// Bonus for Kyoto shogi style drops of promoted pieces
|
| 644 |
-
if (pos.promoted_piece_type(pt) != NO_PIECE_TYPE && pos.drop_promoted())
|
| 645 |
-
score += make_score(std::max(PieceValue[MG][pos.promoted_piece_type(pt)] - PieceValue[MG][pt], VALUE_ZERO),
|
| 646 |
-
std::max(PieceValue[EG][pos.promoted_piece_type(pt)] - PieceValue[EG][pt], VALUE_ZERO)) / 4 * pos.count_in_hand(Us, pt);
|
| 647 |
-
|
| 648 |
-
// Mobility bonus for reversi variants
|
| 649 |
-
if (pos.enclosing_drop())
|
| 650 |
-
mobility[Us] += make_score(500, 500) * popcount(b);
|
| 651 |
-
|
| 652 |
-
// Reduce score if there is a deficit of gates
|
| 653 |
-
if (pos.seirawan_gating() && !pos.piece_drops() && pos.count_in_hand(Us, ALL_PIECES) > popcount(pos.gates(Us)))
|
| 654 |
-
score -= make_score(200, 900) / pos.count_in_hand(Us, ALL_PIECES) * (pos.count_in_hand(Us, ALL_PIECES) - popcount(pos.gates(Us)));
|
| 655 |
-
|
| 656 |
-
// Redundant pieces that can not be doubled per file (e.g., shogi pawns)
|
| 657 |
-
if (pt == pos.drop_no_doubled())
|
| 658 |
-
score -= make_score(50, 20) * std::max(pos.count_with_hand(Us, pt) - pos.max_file() - 1, 0);
|
| 659 |
-
}
|
| 660 |
-
|
| 661 |
-
return score;
|
| 662 |
-
}
|
| 663 |
-
|
| 664 |
-
// Evaluation::king() assigns bonuses and penalties to a king of a given color
|
| 665 |
-
|
| 666 |
-
template<Tracing T> template<Color Us>
|
| 667 |
-
Score Evaluation<T>::king() const {
|
| 668 |
-
|
| 669 |
-
constexpr Color Them = ~Us;
|
| 670 |
-
Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
|
| 671 |
-
Bitboard Camp = pos.board_bb() & ~forward_ranks_bb(Us, r);
|
| 672 |
-
|
| 673 |
-
if (!pos.count<KING>(Us) || !pos.checking_permitted() || pos.checkmate_value() != -VALUE_MATE)
|
| 674 |
-
return SCORE_ZERO;
|
| 675 |
-
|
| 676 |
-
Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
|
| 677 |
-
Bitboard queenChecks, knightChecks, pawnChecks, otherChecks;
|
| 678 |
-
int kingDanger = 0;
|
| 679 |
-
const Square ksq = pos.square<KING>(Us);
|
| 680 |
-
|
| 681 |
-
// Init the score with king shelter and enemy pawns storm
|
| 682 |
-
Score score = pe->king_safety<Us>(pos);
|
| 683 |
-
|
| 684 |
-
// Attacked squares defended at most once by our queen or king
|
| 685 |
-
weak = attackedBy[Them][ALL_PIECES]
|
| 686 |
-
& ~attackedBy2[Us]
|
| 687 |
-
& (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
|
| 688 |
-
|
| 689 |
-
// Analyse the safe enemy's checks which are possible on next move
|
| 690 |
-
safe = ~pos.pieces(Them);
|
| 691 |
-
if (!pos.check_counting() || pos.checks_remaining(Them) > 1)
|
| 692 |
-
safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
|
| 693 |
-
|
| 694 |
-
b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
|
| 695 |
-
b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
|
| 696 |
-
|
| 697 |
-
std::function <Bitboard (Color, PieceType)> get_attacks = [this](Color c, PieceType pt) {
|
| 698 |
-
return attackedBy[c][pt] | (pos.piece_drops() && pos.count_in_hand(c, pt) > 0 ? pos.drop_region(c, pt) & ~pos.pieces() : Bitboard(0));
|
| 699 |
-
};
|
| 700 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 701 |
-
{
|
| 702 |
-
PieceType pt = pop_lsb(ps);
|
| 703 |
-
switch (pt)
|
| 704 |
-
{
|
| 705 |
-
case QUEEN:
|
| 706 |
-
// Enemy queen safe checks: we count them only if they are from squares from
|
| 707 |
-
// which we can't give a rook check, because rook checks are more valuable.
|
| 708 |
-
queenChecks = (b1 | b2)
|
| 709 |
-
& get_attacks(Them, QUEEN)
|
| 710 |
-
& pos.board_bb()
|
| 711 |
-
& safe
|
| 712 |
-
& ~attackedBy[Us][QUEEN]
|
| 713 |
-
& ~(b1 & attackedBy[Them][ROOK]);
|
| 714 |
-
|
| 715 |
-
if (queenChecks)
|
| 716 |
-
kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
|
| 717 |
-
break;
|
| 718 |
-
case ROOK:
|
| 719 |
-
case BISHOP:
|
| 720 |
-
case KNIGHT:
|
| 721 |
-
knightChecks = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & pos.board_bb();
|
| 722 |
-
if (knightChecks & safe)
|
| 723 |
-
kingDanger += SafeCheck[pt][more_than_one(knightChecks & safe)];
|
| 724 |
-
else
|
| 725 |
-
unsafeChecks |= knightChecks;
|
| 726 |
-
break;
|
| 727 |
-
case PAWN:
|
| 728 |
-
if (pos.piece_drops() && pos.count_in_hand(Them, pt) > 0)
|
| 729 |
-
{
|
| 730 |
-
pawnChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb();
|
| 731 |
-
if (pawnChecks & safe)
|
| 732 |
-
kingDanger += SafeCheck[PAWN][more_than_one(pawnChecks & safe)];
|
| 733 |
-
else
|
| 734 |
-
unsafeChecks |= pawnChecks;
|
| 735 |
-
}
|
| 736 |
-
break;
|
| 737 |
-
case SHOGI_PAWN:
|
| 738 |
-
if (pos.promoted_piece_type(pt))
|
| 739 |
-
{
|
| 740 |
-
otherChecks = attacks_bb(Us, pos.promoted_piece_type(pt), ksq, pos.pieces()) & attackedBy[Them][pt]
|
| 741 |
-
& pos.promotion_zone(Them) & pos.board_bb();
|
| 742 |
-
if (otherChecks & safe)
|
| 743 |
-
kingDanger += SafeCheck[FAIRY_PIECES][more_than_one(otherChecks & safe)];
|
| 744 |
-
else
|
| 745 |
-
unsafeChecks |= otherChecks;
|
| 746 |
-
}
|
| 747 |
-
break;
|
| 748 |
-
case KING:
|
| 749 |
-
break;
|
| 750 |
-
default:
|
| 751 |
-
otherChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & get_attacks(Them, pt) & pos.board_bb();
|
| 752 |
-
if (otherChecks & safe)
|
| 753 |
-
kingDanger += SafeCheck[FAIRY_PIECES][more_than_one(otherChecks & safe)];
|
| 754 |
-
else
|
| 755 |
-
unsafeChecks |= otherChecks;
|
| 756 |
-
}
|
| 757 |
-
}
|
| 758 |
-
|
| 759 |
-
// Virtual piece drops
|
| 760 |
-
if (pos.two_boards() && pos.piece_drops())
|
| 761 |
-
{
|
| 762 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 763 |
-
{
|
| 764 |
-
PieceType pt = pop_lsb(ps);
|
| 765 |
-
if (pos.count_in_hand(Them, pt) <= 0 && (attacks_bb(Us, pt, ksq, pos.pieces()) & safe & pos.drop_region(Them, pt) & ~pos.pieces()))
|
| 766 |
-
{
|
| 767 |
-
kingDanger += VirtualCheck * 500 / (500 + PieceValue[MG][pt]);
|
| 768 |
-
// Presumably a mate threat
|
| 769 |
-
if (!(attackedBy[Us][KING] & ~(attackedBy[Them][ALL_PIECES] | pos.pieces(Us))))
|
| 770 |
-
kingDanger += 2000;
|
| 771 |
-
}
|
| 772 |
-
}
|
| 773 |
-
}
|
| 774 |
-
|
| 775 |
-
if (pos.check_counting())
|
| 776 |
-
kingDanger += kingDanger * 7 / (3 + pos.checks_remaining(Them));
|
| 777 |
-
|
| 778 |
-
Square s = file_of(ksq) == FILE_A ? ksq + EAST : file_of(ksq) == pos.max_file() ? ksq + WEST : ksq;
|
| 779 |
-
Bitboard kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(s) | adjacent_files_bb(s);
|
| 780 |
-
|
| 781 |
-
// Find the squares that opponent attacks in our king flank, the squares
|
| 782 |
-
// which they attack twice in that flank, and the squares that we defend.
|
| 783 |
-
b1 = attackedBy[Them][ALL_PIECES] & kingFlank & Camp;
|
| 784 |
-
b2 = b1 & attackedBy2[Them];
|
| 785 |
-
b3 = attackedBy[Us][ALL_PIECES] & kingFlank & Camp;
|
| 786 |
-
|
| 787 |
-
int kingFlankAttack = popcount(b1) + popcount(b2);
|
| 788 |
-
int kingFlankDefense = popcount(b3);
|
| 789 |
-
|
| 790 |
-
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
|
| 791 |
-
+ kingAttackersCountInHand[Them] * kingAttackersWeight[Them]
|
| 792 |
-
+ kingAttackersCount[Them] * kingAttackersWeightInHand[Them]
|
| 793 |
-
+ 183 * popcount(kingRing[Us] & (weak | ~pos.board_bb(Us, KING))) * (1 + pos.captures_to_hand() + pos.check_counting())
|
| 794 |
-
+ 148 * popcount(unsafeChecks) * (1 + pos.check_counting())
|
| 795 |
-
+ 98 * popcount(pos.blockers_for_king(Us))
|
| 796 |
-
+ 69 * kingAttacksCount[Them] * (2 + 8 * pos.check_counting() + pos.captures_to_hand()) / 2
|
| 797 |
-
+ 3 * kingFlankAttack * kingFlankAttack / 8
|
| 798 |
-
+ mg_value(mobility[Them] - mobility[Us]) * int(!pos.captures_to_hand())
|
| 799 |
-
- 873 * !(pos.major_pieces(Them) || pos.captures_to_hand())
|
| 800 |
-
* 2 / (2 + 2 * pos.check_counting() + 2 * pos.two_boards() + 2 * pos.makpong()
|
| 801 |
-
+ (pos.king_type() != KING) * (pos.diagonal_lines() ? 1 : 2))
|
| 802 |
-
- 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
|
| 803 |
-
- 6 * mg_value(score) / 8
|
| 804 |
-
- 4 * kingFlankDefense
|
| 805 |
-
+ 37;
|
| 806 |
-
|
| 807 |
-
// Transform the kingDanger units into a Score, and subtract it from the evaluation
|
| 808 |
-
if (kingDanger > 100)
|
| 809 |
-
score -= make_score(std::min(kingDanger, 3500) * kingDanger / 4096, kingDanger / 16);
|
| 810 |
-
|
| 811 |
-
// Penalty when our king is on a pawnless flank
|
| 812 |
-
if (!(pos.pieces(PAWN) & kingFlank))
|
| 813 |
-
score -= PawnlessFlank;
|
| 814 |
-
|
| 815 |
-
// Penalty if king flank is under attack, potentially moving toward the king
|
| 816 |
-
score -= FlankAttacks * kingFlankAttack * (1 + 5 * pos.captures_to_hand() + pos.check_counting());
|
| 817 |
-
|
| 818 |
-
if (pos.check_counting())
|
| 819 |
-
score += make_score(0, mg_value(score) * 2 / (2 + pos.checks_remaining(Them)));
|
| 820 |
-
|
| 821 |
-
if (pos.king_type() == WAZIR)
|
| 822 |
-
score += make_score(0, mg_value(score) / 2);
|
| 823 |
-
|
| 824 |
-
// For drop games, king danger is independent of game phase, but dependent on material density
|
| 825 |
-
if (pos.captures_to_hand() || pos.two_boards())
|
| 826 |
-
score = make_score(mg_value(score) * me->material_density() / 11000,
|
| 827 |
-
mg_value(score) * me->material_density() / 11000);
|
| 828 |
-
|
| 829 |
-
if constexpr (T)
|
| 830 |
-
Trace::add(KING, Us, score);
|
| 831 |
-
|
| 832 |
-
return score;
|
| 833 |
-
}
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
// Evaluation::threats() assigns bonuses according to the types of the
|
| 837 |
-
// attacking and the attacked pieces.
|
| 838 |
-
|
| 839 |
-
template<Tracing T> template<Color Us>
|
| 840 |
-
Score Evaluation<T>::threats() const {
|
| 841 |
-
|
| 842 |
-
constexpr Color Them = ~Us;
|
| 843 |
-
constexpr Direction Up = pawn_push(Us);
|
| 844 |
-
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
|
| 845 |
-
|
| 846 |
-
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
|
| 847 |
-
Score score = SCORE_ZERO;
|
| 848 |
-
|
| 849 |
-
// Bonuses for variants with mandatory captures
|
| 850 |
-
if (pos.must_capture())
|
| 851 |
-
{
|
| 852 |
-
// Penalties for possible captures
|
| 853 |
-
Bitboard captures = attackedBy[Us][ALL_PIECES] & pos.pieces(Them);
|
| 854 |
-
if (captures)
|
| 855 |
-
score -= make_score(2000, 2000) / (1 + popcount(captures & attackedBy[Them][ALL_PIECES] & ~attackedBy2[Us]));
|
| 856 |
-
|
| 857 |
-
// Bonus if we threaten to force captures
|
| 858 |
-
Bitboard moves = 0, piecebb = pos.pieces(Us);
|
| 859 |
-
while (piecebb)
|
| 860 |
-
{
|
| 861 |
-
Square s = pop_lsb(piecebb);
|
| 862 |
-
if (type_of(pos.piece_on(s)) != KING)
|
| 863 |
-
moves |= pos.moves_from(Us, type_of(pos.piece_on(s)), s);
|
| 864 |
-
}
|
| 865 |
-
score += make_score(200, 200) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces());
|
| 866 |
-
score += make_score(200, 220) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces() & ~attackedBy2[Us]);
|
| 867 |
-
}
|
| 868 |
-
|
| 869 |
-
// Extinction threats
|
| 870 |
-
if (pos.extinction_value() == -VALUE_MATE)
|
| 871 |
-
{
|
| 872 |
-
Bitboard bExt = attackedBy[Us][ALL_PIECES] & pos.pieces(Them);
|
| 873 |
-
for (PieceSet ps = pos.extinction_piece_types(); ps;)
|
| 874 |
-
{
|
| 875 |
-
PieceType pt = pop_lsb(ps);
|
| 876 |
-
if (pt == ALL_PIECES)
|
| 877 |
-
continue;
|
| 878 |
-
int denom = std::max(pos.count_with_hand(Them, pt) - pos.extinction_piece_count(), 1);
|
| 879 |
-
// Explosion threats
|
| 880 |
-
if (pos.blast_on_capture())
|
| 881 |
-
{
|
| 882 |
-
int evasions = popcount(((attackedBy[Them][pt] & ~pos.pieces(Them)) | pos.pieces(Them, pt)) & ~attackedBy[Us][ALL_PIECES]) * denom;
|
| 883 |
-
int attacks = popcount((attackedBy[Them][pt] | pos.pieces(Them, pt)) & attackedBy[Us][ALL_PIECES]);
|
| 884 |
-
int explosions = 0;
|
| 885 |
-
|
| 886 |
-
Bitboard bExtBlast = bExt & (attackedBy2[Us] | ~attackedBy[Us][pt]);
|
| 887 |
-
while (bExtBlast)
|
| 888 |
-
{
|
| 889 |
-
Square s = pop_lsb(bExtBlast);
|
| 890 |
-
if (((attacks_bb<KING>(s) | s) & pos.pieces(Them, pt)) && !(attacks_bb<KING>(s) & pos.pieces(Us, pt)))
|
| 891 |
-
explosions++;
|
| 892 |
-
}
|
| 893 |
-
int danger = 20 * attacks / (evasions + 1) + 40 * explosions;
|
| 894 |
-
score += make_score(danger * (100 + danger), 0);
|
| 895 |
-
}
|
| 896 |
-
else
|
| 897 |
-
// Direct extinction threats
|
| 898 |
-
score += make_score(1000, 1000) / (denom * denom) * popcount(bExt & pos.pieces(Them, pt));
|
| 899 |
-
}
|
| 900 |
-
}
|
| 901 |
-
|
| 902 |
-
// Non-pawn enemies
|
| 903 |
-
nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN, SHOGI_PAWN) & ~pos.pieces(SOLDIER);
|
| 904 |
-
|
| 905 |
-
// Squares strongly protected by the enemy, either because they defend the
|
| 906 |
-
// square with a pawn, or because they defend the square twice and we don't.
|
| 907 |
-
stronglyProtected = (attackedBy[Them][PAWN] | attackedBy[Them][SHOGI_PAWN] | attackedBy[Them][SOLDIER])
|
| 908 |
-
| (attackedBy2[Them] & ~attackedBy2[Us]);
|
| 909 |
-
|
| 910 |
-
// Non-pawn enemies, strongly protected
|
| 911 |
-
defended = nonPawnEnemies & stronglyProtected;
|
| 912 |
-
|
| 913 |
-
// Enemies not strongly protected and under our attack
|
| 914 |
-
weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
|
| 915 |
-
|
| 916 |
-
// Bonus according to the kind of attacking pieces
|
| 917 |
-
if (defended | weak)
|
| 918 |
-
{
|
| 919 |
-
b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
|
| 920 |
-
while (b)
|
| 921 |
-
score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
|
| 922 |
-
|
| 923 |
-
b = weak & attackedBy[Us][ROOK];
|
| 924 |
-
while (b)
|
| 925 |
-
score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
|
| 926 |
-
|
| 927 |
-
if (weak & attackedBy[Us][KING])
|
| 928 |
-
score += ThreatByKing;
|
| 929 |
-
|
| 930 |
-
b = ~attackedBy[Them][ALL_PIECES]
|
| 931 |
-
| (nonPawnEnemies & attackedBy2[Us]);
|
| 932 |
-
score += Hanging * popcount(weak & b);
|
| 933 |
-
|
| 934 |
-
// Additional bonus if weak piece is only protected by a queen
|
| 935 |
-
score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
|
| 936 |
-
}
|
| 937 |
-
|
| 938 |
-
// Bonus for restricting their piece moves
|
| 939 |
-
b = attackedBy[Them][ALL_PIECES]
|
| 940 |
-
& ~stronglyProtected
|
| 941 |
-
& attackedBy[Us][ALL_PIECES];
|
| 942 |
-
score += RestrictedPiece * popcount(b);
|
| 943 |
-
|
| 944 |
-
// Protected or unattacked squares
|
| 945 |
-
safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
|
| 946 |
-
|
| 947 |
-
// Bonus for attacking enemy pieces with our relatively safe pawns
|
| 948 |
-
b = pos.pieces(Us, PAWN) & safe;
|
| 949 |
-
b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
|
| 950 |
-
score += ThreatBySafePawn * popcount(b);
|
| 951 |
-
|
| 952 |
-
// Find squares where our pawns can push on the next move
|
| 953 |
-
b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
|
| 954 |
-
b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
|
| 955 |
-
|
| 956 |
-
// Keep only the squares which are relatively safe
|
| 957 |
-
b &= ~attackedBy[Them][PAWN] & safe;
|
| 958 |
-
|
| 959 |
-
// Bonus for safe pawn threats on the next move
|
| 960 |
-
b = (pawn_attacks_bb<Us>(b) | shift<Up>(shift<Up>(pos.pieces(Us, SHOGI_PAWN, SOLDIER)))) & nonPawnEnemies;
|
| 961 |
-
score += ThreatByPawnPush * popcount(b);
|
| 962 |
-
|
| 963 |
-
// Bonus for threats on the next moves against enemy queen
|
| 964 |
-
if (pos.count<QUEEN>(Them) == 1)
|
| 965 |
-
{
|
| 966 |
-
bool queenImbalance = pos.count<QUEEN>() == 1;
|
| 967 |
-
|
| 968 |
-
Square s = pos.square<QUEEN>(Them);
|
| 969 |
-
safe = mobilityArea[Us]
|
| 970 |
-
& ~pos.pieces(Us, PAWN)
|
| 971 |
-
& ~stronglyProtected;
|
| 972 |
-
|
| 973 |
-
b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
|
| 974 |
-
|
| 975 |
-
score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
|
| 976 |
-
|
| 977 |
-
b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
|
| 978 |
-
| (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
|
| 979 |
-
|
| 980 |
-
score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
|
| 981 |
-
}
|
| 982 |
-
|
| 983 |
-
if constexpr (T)
|
| 984 |
-
Trace::add(THREAT, Us, score);
|
| 985 |
-
|
| 986 |
-
return score;
|
| 987 |
-
}
|
| 988 |
-
|
| 989 |
-
// Evaluation::passed() evaluates the passed pawns and candidate passed
|
| 990 |
-
// pawns of the given color.
|
| 991 |
-
|
| 992 |
-
template<Tracing T> template<Color Us>
|
| 993 |
-
Score Evaluation<T>::passed() const {
|
| 994 |
-
|
| 995 |
-
constexpr Color Them = ~Us;
|
| 996 |
-
constexpr Direction Up = pawn_push(Us);
|
| 997 |
-
constexpr Direction Down = -Up;
|
| 998 |
-
|
| 999 |
-
auto king_proximity = [&](Color c, Square s) {
|
| 1000 |
-
return pos.extinction_value() == VALUE_MATE ? 0 : pos.count<KING>(c) ? std::min(distance(pos.square<KING>(c), s), 5) : 5;
|
| 1001 |
-
};
|
| 1002 |
-
|
| 1003 |
-
Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
|
| 1004 |
-
Score score = SCORE_ZERO;
|
| 1005 |
-
|
| 1006 |
-
b = pe->passed_pawns(Us);
|
| 1007 |
-
|
| 1008 |
-
blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
|
| 1009 |
-
if (blockedPassers)
|
| 1010 |
-
{
|
| 1011 |
-
helpers = shift<Up>(pos.pieces(Us, PAWN))
|
| 1012 |
-
& ~pos.pieces(Them)
|
| 1013 |
-
& (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
|
| 1014 |
-
|
| 1015 |
-
// Remove blocked candidate passers that don't have help to pass
|
| 1016 |
-
b &= ~blockedPassers
|
| 1017 |
-
| shift<WEST>(helpers)
|
| 1018 |
-
| shift<EAST>(helpers);
|
| 1019 |
-
}
|
| 1020 |
-
|
| 1021 |
-
while (b)
|
| 1022 |
-
{
|
| 1023 |
-
Square s = pop_lsb(b);
|
| 1024 |
-
|
| 1025 |
-
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
|
| 1026 |
-
|
| 1027 |
-
int r = std::max(RANK_8 - std::max(relative_rank(Us, pos.promotion_square(Us, s), pos.max_rank()) - relative_rank(Us, s, pos.max_rank()), 0), 0);
|
| 1028 |
-
|
| 1029 |
-
Score bonus = PassedRank[r];
|
| 1030 |
-
|
| 1031 |
-
if (r > RANK_3)
|
| 1032 |
-
{
|
| 1033 |
-
int w = 5 * r - 13;
|
| 1034 |
-
Square blockSq = s + Up;
|
| 1035 |
-
|
| 1036 |
-
// Adjust bonus based on the king's proximity
|
| 1037 |
-
bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
|
| 1038 |
-
- king_proximity(Us, blockSq) * 2) * w);
|
| 1039 |
-
|
| 1040 |
-
// If blockSq is not the queening square then consider also a second push
|
| 1041 |
-
if (r != RANK_7)
|
| 1042 |
-
bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
|
| 1043 |
-
|
| 1044 |
-
// If the pawn is free to advance, then increase the bonus
|
| 1045 |
-
if (pos.empty(blockSq))
|
| 1046 |
-
{
|
| 1047 |
-
squaresToQueen = forward_file_bb(Us, s);
|
| 1048 |
-
unsafeSquares = passed_pawn_span(Us, s);
|
| 1049 |
-
|
| 1050 |
-
bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
|
| 1051 |
-
|
| 1052 |
-
if (!(pos.pieces(Them) & bb))
|
| 1053 |
-
unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
|
| 1054 |
-
|
| 1055 |
-
// If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
|
| 1056 |
-
// Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
|
| 1057 |
-
// Otherwise assign a smaller bonus if the path to queen is not attacked
|
| 1058 |
-
// and even smaller bonus if it is attacked but block square is not.
|
| 1059 |
-
int k = !unsafeSquares ? 36 :
|
| 1060 |
-
!(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
|
| 1061 |
-
!(unsafeSquares & squaresToQueen) ? 17 :
|
| 1062 |
-
!(unsafeSquares & blockSq) ? 7 :
|
| 1063 |
-
0 ;
|
| 1064 |
-
|
| 1065 |
-
// Assign a larger bonus if the block square is defended
|
| 1066 |
-
if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
|
| 1067 |
-
k += 5;
|
| 1068 |
-
|
| 1069 |
-
bonus += make_score(k * w, k * w);
|
| 1070 |
-
}
|
| 1071 |
-
} // r > RANK_3
|
| 1072 |
-
|
| 1073 |
-
score += bonus - PassedFile * edge_distance(file_of(s), pos.max_file());
|
| 1074 |
-
}
|
| 1075 |
-
|
| 1076 |
-
// Passed custom pawns
|
| 1077 |
-
for (PieceSet ps = (pos.promotion_pawn_types(Us) & ~piece_set(PAWN)); ps;)
|
| 1078 |
-
{
|
| 1079 |
-
PieceType pt = pop_lsb(ps);
|
| 1080 |
-
Bitboard b2 = pos.pieces(Us, pt);
|
| 1081 |
-
while (b2)
|
| 1082 |
-
{
|
| 1083 |
-
Square s = pop_lsb(b2);
|
| 1084 |
-
if (pos.promotion_square(Us, s) == SQ_NONE || (pos.pieces(Them, pt) & forward_file_bb(Us, s)))
|
| 1085 |
-
continue;
|
| 1086 |
-
int r = std::max(RANK_8 - std::max(relative_rank(Us, pos.promotion_square(Us, s), pos.max_rank()) - relative_rank(Us, s, pos.max_rank()), 0), 0);
|
| 1087 |
-
score += PassedRank[r];
|
| 1088 |
-
}
|
| 1089 |
-
}
|
| 1090 |
-
|
| 1091 |
-
// Scale by maximum promotion piece value
|
| 1092 |
-
Value maxMg = VALUE_ZERO, maxEg = VALUE_ZERO;
|
| 1093 |
-
for (PieceSet ps = pos.promotion_piece_types(Us); ps;)
|
| 1094 |
-
{
|
| 1095 |
-
PieceType pt = pop_lsb(ps);
|
| 1096 |
-
maxMg = std::max(maxMg, PieceValue[MG][pt]);
|
| 1097 |
-
maxEg = std::max(maxEg, PieceValue[EG][pt]);
|
| 1098 |
-
}
|
| 1099 |
-
score = make_score(mg_value(score) * int(maxMg - PawnValueMg) / (QueenValueMg - PawnValueMg),
|
| 1100 |
-
eg_value(score) * int(maxEg - PawnValueEg) / (QueenValueEg - PawnValueEg));
|
| 1101 |
-
|
| 1102 |
-
// Score passed shogi pawns
|
| 1103 |
-
PieceType pt = pos.promoted_piece_type(SHOGI_PAWN);
|
| 1104 |
-
if (pt != NO_PIECE_TYPE)
|
| 1105 |
-
{
|
| 1106 |
-
b = pos.pieces(Us, SHOGI_PAWN);
|
| 1107 |
-
while (b)
|
| 1108 |
-
{
|
| 1109 |
-
Square s = pop_lsb(b);
|
| 1110 |
-
if ((pos.pieces(Them, SHOGI_PAWN) & forward_file_bb(Us, s)) || pos.promotion_square(Us, s) == SQ_NONE)
|
| 1111 |
-
continue;
|
| 1112 |
-
|
| 1113 |
-
Square blockSq = s + Up;
|
| 1114 |
-
int d = 2 * std::max(relative_rank(Us, pos.promotion_square(Us, s), pos.max_rank()) - relative_rank(Us, s, pos.max_rank()), 1);
|
| 1115 |
-
d += !!(attackedBy[Them][ALL_PIECES] & ~attackedBy2[Us] & blockSq);
|
| 1116 |
-
score += make_score(PieceValue[MG][pt], PieceValue[EG][pt]) / (d * d);
|
| 1117 |
-
}
|
| 1118 |
-
}
|
| 1119 |
-
|
| 1120 |
-
if constexpr (T)
|
| 1121 |
-
Trace::add(PASSED, Us, score);
|
| 1122 |
-
|
| 1123 |
-
return score;
|
| 1124 |
-
}
|
| 1125 |
-
|
| 1126 |
-
|
| 1127 |
-
// Evaluation::space() computes a space evaluation for a given side, aiming to improve game
|
| 1128 |
-
// play in the opening. It is based on the number of safe squares on the four central files
|
| 1129 |
-
// on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
|
| 1130 |
-
// Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
|
| 1131 |
-
|
| 1132 |
-
template<Tracing T> template<Color Us>
|
| 1133 |
-
Score Evaluation<T>::space() const {
|
| 1134 |
-
|
| 1135 |
-
bool pawnsOnly = !(pos.pieces(Us) ^ pos.pieces(Us, PAWN));
|
| 1136 |
-
|
| 1137 |
-
// Early exit if, for example, both queens or 6 minor pieces have been exchanged
|
| 1138 |
-
if (pos.non_pawn_material() < SpaceThreshold && !pawnsOnly && pos.double_step_region(Us))
|
| 1139 |
-
return SCORE_ZERO;
|
| 1140 |
-
|
| 1141 |
-
constexpr Color Them = ~Us;
|
| 1142 |
-
constexpr Direction Down = -pawn_push(Us);
|
| 1143 |
-
constexpr Bitboard SpaceMask =
|
| 1144 |
-
Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
|
| 1145 |
-
: CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
|
| 1146 |
-
|
| 1147 |
-
// Find the available squares for our pieces inside the area defined by SpaceMask
|
| 1148 |
-
Bitboard safe = SpaceMask
|
| 1149 |
-
& ~pos.pieces(Us, PAWN)
|
| 1150 |
-
& ~attackedBy[Them][PAWN];
|
| 1151 |
-
|
| 1152 |
-
// Find all squares which are at most three squares behind some friendly pawn
|
| 1153 |
-
Bitboard behind = pos.pieces(Us, PAWN);
|
| 1154 |
-
behind |= shift<Down>(behind);
|
| 1155 |
-
behind |= shift<Down+Down>(behind);
|
| 1156 |
-
|
| 1157 |
-
if (pawnsOnly)
|
| 1158 |
-
{
|
| 1159 |
-
safe = pos.board_bb() & ((attackedBy2[Us] & ~attackedBy2[Them]) | (attackedBy[Us][PAWN] & ~pos.pieces(Us, PAWN)));
|
| 1160 |
-
behind = 0;
|
| 1161 |
-
}
|
| 1162 |
-
|
| 1163 |
-
// Compute space score based on the number of safe squares and number of our pieces
|
| 1164 |
-
// increased with number of total blocked pawns in position.
|
| 1165 |
-
int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
|
| 1166 |
-
int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
|
| 1167 |
-
Score score = make_score(bonus * weight * weight / 16, 0);
|
| 1168 |
-
|
| 1169 |
-
if (pos.flag_region(Us))
|
| 1170 |
-
score += make_score(200, 200) * popcount(behind & safe & pos.flag_region(Us));
|
| 1171 |
-
|
| 1172 |
-
if constexpr (T)
|
| 1173 |
-
Trace::add(SPACE, Us, score);
|
| 1174 |
-
|
| 1175 |
-
return score;
|
| 1176 |
-
}
|
| 1177 |
-
|
| 1178 |
-
|
| 1179 |
-
// Evaluation::variant() computes variant-specific evaluation bonuses for a given side.
|
| 1180 |
-
|
| 1181 |
-
template<Tracing T> template<Color Us>
|
| 1182 |
-
Score Evaluation<T>::variant() const {
|
| 1183 |
-
|
| 1184 |
-
constexpr Color Them = ~Us;
|
| 1185 |
-
constexpr Direction Down = pawn_push(Them);
|
| 1186 |
-
|
| 1187 |
-
Score score = SCORE_ZERO;
|
| 1188 |
-
|
| 1189 |
-
// Capture the flag
|
| 1190 |
-
if (pos.flag_region(Us))
|
| 1191 |
-
{
|
| 1192 |
-
Bitboard ctfPieces = pos.pieces(Us, pos.flag_piece(Us));
|
| 1193 |
-
Bitboard ctfTargets = pos.flag_region(Us) & pos.board_bb();
|
| 1194 |
-
Bitboard onHold = 0;
|
| 1195 |
-
Bitboard onHold2 = 0;
|
| 1196 |
-
Bitboard processed = 0;
|
| 1197 |
-
Bitboard blocked = pos.pieces(Us, PAWN) | attackedBy[Them][ALL_PIECES];
|
| 1198 |
-
Bitboard doubleBlocked = attackedBy2[Them]
|
| 1199 |
-
| (pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | attackedBy[Them][ALL_PIECES]))
|
| 1200 |
-
| (pos.pieces(Them) & pe->pawn_attacks(Them))
|
| 1201 |
-
| (pawn_attacks_bb<Them>(pos.pieces(Them, PAWN) & pe->pawn_attacks(Them)));
|
| 1202 |
-
Bitboard inaccessible = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces(Them, PAWN));
|
| 1203 |
-
// Traverse all paths of the CTF pieces to the CTF targets.
|
| 1204 |
-
// Put squares that are attacked or occupied on hold for one iteration.
|
| 1205 |
-
// This reflects that likely a move will be needed to block or capture the attack.
|
| 1206 |
-
// If all piece types are eligible, use the king path as a proxy for distance.
|
| 1207 |
-
PieceType ptCtf = pos.flag_piece(Us) == ALL_PIECES ? KING : pos.flag_piece(Us);
|
| 1208 |
-
for (int dist = 0; (ctfPieces || onHold || onHold2) && (ctfTargets & ~processed); dist++)
|
| 1209 |
-
{
|
| 1210 |
-
int wins = popcount(ctfTargets & ctfPieces);
|
| 1211 |
-
if (wins)
|
| 1212 |
-
score += make_score(4000, 4000) * wins / (wins + dist * dist);
|
| 1213 |
-
Bitboard current = ctfPieces & ~ctfTargets;
|
| 1214 |
-
processed |= ctfPieces;
|
| 1215 |
-
ctfPieces = onHold & ~processed;
|
| 1216 |
-
onHold = onHold2 & ~processed;
|
| 1217 |
-
onHold2 = 0;
|
| 1218 |
-
while (current)
|
| 1219 |
-
{
|
| 1220 |
-
Square s = pop_lsb(current);
|
| 1221 |
-
Bitboard attacks = ( (PseudoAttacks[Us][ptCtf][s] & pos.pieces())
|
| 1222 |
-
| (PseudoMoves[0][Us][ptCtf][s] & ~pos.pieces())) & ~processed & pos.board_bb();
|
| 1223 |
-
ctfPieces |= attacks & ~blocked;
|
| 1224 |
-
onHold |= attacks & ~doubleBlocked;
|
| 1225 |
-
onHold2 |= attacks & ~inaccessible;
|
| 1226 |
-
}
|
| 1227 |
-
}
|
| 1228 |
-
}
|
| 1229 |
-
|
| 1230 |
-
// nCheck
|
| 1231 |
-
if (pos.check_counting())
|
| 1232 |
-
{
|
| 1233 |
-
int remainingChecks = pos.checks_remaining(Us);
|
| 1234 |
-
assert(remainingChecks > 0);
|
| 1235 |
-
score += make_score(3600, 1000) / (remainingChecks * remainingChecks);
|
| 1236 |
-
}
|
| 1237 |
-
|
| 1238 |
-
// Extinction
|
| 1239 |
-
if (pos.extinction_value() != VALUE_NONE)
|
| 1240 |
-
{
|
| 1241 |
-
for (PieceSet ps = pos.extinction_piece_types(); ps;)
|
| 1242 |
-
{
|
| 1243 |
-
PieceType pt = pop_lsb(ps);
|
| 1244 |
-
if (pt != ALL_PIECES)
|
| 1245 |
-
{
|
| 1246 |
-
// Single piece type extinction bonus
|
| 1247 |
-
int denom = std::max(pos.count(Us, pt) - pos.extinction_piece_count(), 1);
|
| 1248 |
-
if (pos.count(Them, pt) >= pos.extinction_opponent_piece_count() || pos.two_boards())
|
| 1249 |
-
score += make_score(1000000 / (500 + PieceValue[MG][pt]),
|
| 1250 |
-
1000000 / (500 + PieceValue[EG][pt])) / (denom * denom)
|
| 1251 |
-
* (pos.extinction_value() / VALUE_MATE);
|
| 1252 |
-
}
|
| 1253 |
-
else if (pos.extinction_value() == VALUE_MATE)
|
| 1254 |
-
{
|
| 1255 |
-
// Losing chess variant bonus
|
| 1256 |
-
score += make_score(pos.non_pawn_material(Us), pos.non_pawn_material(Us)) / std::max(pos.count<ALL_PIECES>(Us), 1);
|
| 1257 |
-
}
|
| 1258 |
-
else if (pos.count<PAWN>(Us) == pos.count<ALL_PIECES>(Us))
|
| 1259 |
-
{
|
| 1260 |
-
// Pawns easy to stop/capture
|
| 1261 |
-
int l = 0, m = 0, r = popcount(pos.pieces(Us, PAWN) & file_bb(FILE_A));
|
| 1262 |
-
for (File f = FILE_A; f <= pos.max_file(); ++f)
|
| 1263 |
-
{
|
| 1264 |
-
l = m; m = r; r = popcount(pos.pieces(Us, PAWN) & shift<EAST>(file_bb(f)));
|
| 1265 |
-
score -= make_score(80 - 10 * (edge_distance(f, pos.max_file()) % 2),
|
| 1266 |
-
80 - 15 * (edge_distance(f, pos.max_file()) % 2)) * m / (1 + l * r);
|
| 1267 |
-
}
|
| 1268 |
-
}
|
| 1269 |
-
else if (pos.count<PAWN>(Them) == pos.count<ALL_PIECES>(Them))
|
| 1270 |
-
{
|
| 1271 |
-
// Add a bonus according to how close we are to breaking through the pawn wall
|
| 1272 |
-
int dist = 8;
|
| 1273 |
-
Bitboard breakthroughs = attackedBy[Us][ALL_PIECES] & rank_bb(relative_rank(Us, pos.max_rank(), pos.max_rank()));
|
| 1274 |
-
if (breakthroughs)
|
| 1275 |
-
dist = attackedBy[Us][QUEEN] & breakthroughs ? 0 : 1;
|
| 1276 |
-
else for (File f = FILE_A; f <= pos.max_file(); ++f)
|
| 1277 |
-
dist = std::min(dist, popcount(pos.pieces(PAWN) & file_bb(f)));
|
| 1278 |
-
score += make_score(70, 70) * pos.count<PAWN>(Them) / (1 + dist * dist) / (pos.pieces(Us, QUEEN) ? 2 : 4);
|
| 1279 |
-
}
|
| 1280 |
-
}
|
| 1281 |
-
}
|
| 1282 |
-
|
| 1283 |
-
// Connect-n
|
| 1284 |
-
if (pos.connect_n() > 0)
|
| 1285 |
-
{
|
| 1286 |
-
//Calculate eligible pieces for connection once.
|
| 1287 |
-
//Still consider all opponent pieces as blocking.
|
| 1288 |
-
Bitboard connectPiecesUs = 0;
|
| 1289 |
-
for (PieceSet ps = pos.connect_piece_types(); ps;){
|
| 1290 |
-
PieceType pt = pop_lsb(ps);
|
| 1291 |
-
connectPiecesUs |= pos.pieces(pt);
|
| 1292 |
-
};
|
| 1293 |
-
connectPiecesUs &= pos.pieces(Us);
|
| 1294 |
-
|
| 1295 |
-
for (const Direction& d : pos.getConnectDirections())
|
| 1296 |
-
|
| 1297 |
-
{
|
| 1298 |
-
// Find sufficiently large gaps
|
| 1299 |
-
Bitboard b = pos.board_bb() & ~pos.pieces(Them);
|
| 1300 |
-
for (int i = 1; i < pos.connect_n(); i++)
|
| 1301 |
-
b &= shift(d, b);
|
| 1302 |
-
// Count number of pieces per gap
|
| 1303 |
-
while (b)
|
| 1304 |
-
{
|
| 1305 |
-
Square s = pop_lsb(b);
|
| 1306 |
-
int c = 0;
|
| 1307 |
-
for (int j = 0; j < pos.connect_n(); j++)
|
| 1308 |
-
if (connectPiecesUs & (s - j * d))
|
| 1309 |
-
c++;
|
| 1310 |
-
score += make_score(200, 200) * c / (pos.connect_n() - c) / (pos.connect_n() - c);
|
| 1311 |
-
}
|
| 1312 |
-
}
|
| 1313 |
-
}
|
| 1314 |
-
|
| 1315 |
-
// Potential piece flips (Reversi)
|
| 1316 |
-
if (pos.flip_enclosed_pieces())
|
| 1317 |
-
{
|
| 1318 |
-
// Stable pieces
|
| 1319 |
-
if (pos.flip_enclosed_pieces() == REVERSI)
|
| 1320 |
-
{
|
| 1321 |
-
Bitboard edges = (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) & pos.board_bb();
|
| 1322 |
-
Bitboard edgePieces = pos.pieces(Us) & edges;
|
| 1323 |
-
while (edgePieces)
|
| 1324 |
-
{
|
| 1325 |
-
Bitboard connectedEdge = attacks_bb(Us, ROOK, pop_lsb(edgePieces), ~(pos.pieces(Us) & edges)) & edges;
|
| 1326 |
-
if (!more_than_one(connectedEdge & ~pos.pieces(Us)))
|
| 1327 |
-
score += make_score(300, 300);
|
| 1328 |
-
else if (!(connectedEdge & ~pos.pieces()))
|
| 1329 |
-
score += make_score(200, 200);
|
| 1330 |
-
}
|
| 1331 |
-
}
|
| 1332 |
-
|
| 1333 |
-
// Unstable
|
| 1334 |
-
Bitboard unstable = 0;
|
| 1335 |
-
Bitboard drops = pos.drop_region(Them, IMMOBILE_PIECE);
|
| 1336 |
-
while (drops)
|
| 1337 |
-
{
|
| 1338 |
-
Square s = pop_lsb(drops);
|
| 1339 |
-
if (pos.flip_enclosed_pieces() == REVERSI)
|
| 1340 |
-
{
|
| 1341 |
-
Bitboard b = attacks_bb(Them, QUEEN, s, ~pos.pieces(Us)) & ~PseudoAttacks[Them][KING][s] & pos.pieces(Them);
|
| 1342 |
-
while(b)
|
| 1343 |
-
unstable |= between_bb(s, pop_lsb(b));
|
| 1344 |
-
}
|
| 1345 |
-
else
|
| 1346 |
-
unstable |= PseudoAttacks[Them][KING][s] & pos.pieces(Us);
|
| 1347 |
-
}
|
| 1348 |
-
score -= make_score(200, 200) * popcount(unstable);
|
| 1349 |
-
}
|
| 1350 |
-
|
| 1351 |
-
if (T)
|
| 1352 |
-
Trace::add(VARIANT, Us, score);
|
| 1353 |
-
|
| 1354 |
-
return score;
|
| 1355 |
-
}
|
| 1356 |
-
|
| 1357 |
-
|
| 1358 |
-
// Evaluation::winnable() adjusts the midgame and endgame score components, based on
|
| 1359 |
-
// the known attacking/defending status of the players. The final value is derived
|
| 1360 |
-
// by interpolation from the midgame and endgame values.
|
| 1361 |
-
|
| 1362 |
-
template<Tracing T>
|
| 1363 |
-
Value Evaluation<T>::winnable(Score score) const {
|
| 1364 |
-
|
| 1365 |
-
// No initiative bonus for variants that do not require sufficient mating material, e.g., extinction variants.
|
| 1366 |
-
// This protects them from misidentification as drawish.
|
| 1367 |
-
int complexity = 0;
|
| 1368 |
-
bool pawnsOnBothFlanks = true;
|
| 1369 |
-
if ( pos.extinction_value() == VALUE_NONE
|
| 1370 |
-
&& !pos.captures_to_hand()
|
| 1371 |
-
&& !pos.connect_n()
|
| 1372 |
-
&& !pos.material_counting()
|
| 1373 |
-
&& !(pos.flag_region(WHITE) || pos.flag_region(BLACK)))
|
| 1374 |
-
{
|
| 1375 |
-
int outflanking = !pos.count<KING>(WHITE) || !pos.count<KING>(BLACK) ? 0
|
| 1376 |
-
: distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
|
| 1377 |
-
+ int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
|
| 1378 |
-
|
| 1379 |
-
pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
|
| 1380 |
-
&& (pos.pieces(PAWN) & KingSide);
|
| 1381 |
-
|
| 1382 |
-
bool almostUnwinnable = outflanking < 0
|
| 1383 |
-
&& pos.stalemate_value() == VALUE_DRAW
|
| 1384 |
-
&& !pawnsOnBothFlanks;
|
| 1385 |
-
|
| 1386 |
-
bool infiltration = (pos.count<KING>(WHITE) && rank_of(pos.square<KING>(WHITE)) > RANK_4)
|
| 1387 |
-
|| (pos.count<KING>(BLACK) && rank_of(pos.square<KING>(BLACK)) < RANK_5);
|
| 1388 |
-
|
| 1389 |
-
// Compute the initiative bonus for the attacking side
|
| 1390 |
-
complexity = 9 * pe->passed_count()
|
| 1391 |
-
+ 12 * pos.count(WHITE, pos.main_promotion_pawn_type(WHITE)) * bool(pos.main_promotion_pawn_type(WHITE))
|
| 1392 |
-
+ 12 * pos.count(BLACK, pos.main_promotion_pawn_type(BLACK)) * bool(pos.main_promotion_pawn_type(BLACK))
|
| 1393 |
-
+ 15 * pos.count<SOLDIER>()
|
| 1394 |
-
+ 9 * outflanking
|
| 1395 |
-
+ 21 * pawnsOnBothFlanks
|
| 1396 |
-
+ 24 * infiltration
|
| 1397 |
-
+ 51 * !pos.non_pawn_material()
|
| 1398 |
-
- 43 * almostUnwinnable
|
| 1399 |
-
-110 ;
|
| 1400 |
-
}
|
| 1401 |
-
|
| 1402 |
-
Value mg = mg_value(score);
|
| 1403 |
-
Value eg = eg_value(score);
|
| 1404 |
-
|
| 1405 |
-
// Now apply the bonus: note that we find the attacking side by extracting the
|
| 1406 |
-
// sign of the midgame or endgame values, and that we carefully cap the bonus
|
| 1407 |
-
// so that the midgame and endgame scores do not change sign after the bonus.
|
| 1408 |
-
int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
|
| 1409 |
-
int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
|
| 1410 |
-
|
| 1411 |
-
mg += u;
|
| 1412 |
-
eg += v;
|
| 1413 |
-
|
| 1414 |
-
// Compute the scale factor for the winning side
|
| 1415 |
-
Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
|
| 1416 |
-
int sf = me->scale_factor(pos, strongSide);
|
| 1417 |
-
|
| 1418 |
-
// If scale factor is not already specific, scale up/down via general heuristics
|
| 1419 |
-
if (sf == SCALE_FACTOR_NORMAL && !pos.captures_to_hand() && !pos.material_counting())
|
| 1420 |
-
{
|
| 1421 |
-
if (pos.opposite_bishops())
|
| 1422 |
-
{
|
| 1423 |
-
// For pure opposite colored bishops endgames use scale factor
|
| 1424 |
-
// based on the number of passed pawns of the strong side.
|
| 1425 |
-
if ( pos.non_pawn_material(WHITE) == BishopValueMg
|
| 1426 |
-
&& pos.non_pawn_material(BLACK) == BishopValueMg)
|
| 1427 |
-
sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
|
| 1428 |
-
// For every other opposite colored bishops endgames use scale factor
|
| 1429 |
-
// based on the number of all pieces of the strong side.
|
| 1430 |
-
else
|
| 1431 |
-
sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
|
| 1432 |
-
}
|
| 1433 |
-
// For rook endgames with strong side not having overwhelming pawn number advantage
|
| 1434 |
-
// and its pawns being on one flank and weak side protecting its pieces with a king
|
| 1435 |
-
// use lower scale factor.
|
| 1436 |
-
else if ( pos.non_pawn_material(WHITE) == RookValueMg
|
| 1437 |
-
&& pos.non_pawn_material(BLACK) == RookValueMg
|
| 1438 |
-
&& pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
|
| 1439 |
-
&& bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
|
| 1440 |
-
&& pos.count<KING>(~strongSide)
|
| 1441 |
-
&& (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
|
| 1442 |
-
sf = 36;
|
| 1443 |
-
// For queen vs no queen endgames use scale factor
|
| 1444 |
-
// based on number of minors of side that doesn't have queen.
|
| 1445 |
-
else if (pos.count<QUEEN>() == 1)
|
| 1446 |
-
sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
|
| 1447 |
-
: pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
|
| 1448 |
-
// In every other case use scale factor based on
|
| 1449 |
-
// the number of pawns of the strong side reduced if pawns are on a single flank.
|
| 1450 |
-
else
|
| 1451 |
-
sf = std::min(sf, 36 + 7 * (pos.count<PAWN>(strongSide) + pos.count<SOLDIER>(strongSide))) - 4 * !pawnsOnBothFlanks;
|
| 1452 |
-
|
| 1453 |
-
// Reduce scale factor in case of pawns being on a single flank
|
| 1454 |
-
sf -= 4 * !pawnsOnBothFlanks;
|
| 1455 |
-
}
|
| 1456 |
-
|
| 1457 |
-
// Interpolate between the middlegame and (scaled by 'sf') endgame score
|
| 1458 |
-
v = mg * int(me->game_phase())
|
| 1459 |
-
+ eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
|
| 1460 |
-
v /= PHASE_MIDGAME;
|
| 1461 |
-
|
| 1462 |
-
if constexpr (T)
|
| 1463 |
-
{
|
| 1464 |
-
Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
|
| 1465 |
-
Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
|
| 1466 |
-
}
|
| 1467 |
-
|
| 1468 |
-
return Value(v);
|
| 1469 |
-
}
|
| 1470 |
-
|
| 1471 |
-
|
| 1472 |
-
// Evaluation::value() is the main function of the class. It computes the various
|
| 1473 |
-
// parts of the evaluation and returns the value of the position from the point
|
| 1474 |
-
// of view of the side to move.
|
| 1475 |
-
|
| 1476 |
-
template<Tracing T>
|
| 1477 |
-
Value Evaluation<T>::value() {
|
| 1478 |
-
|
| 1479 |
-
assert(!pos.checkers());
|
| 1480 |
-
assert(!pos.is_immediate_game_end());
|
| 1481 |
-
|
| 1482 |
-
// Probe the material hash table
|
| 1483 |
-
me = Material::probe(pos);
|
| 1484 |
-
|
| 1485 |
-
// If we have a specialized evaluation function for the current material
|
| 1486 |
-
// configuration, call it and return.
|
| 1487 |
-
if (me->specialized_eval_exists())
|
| 1488 |
-
return me->evaluate(pos);
|
| 1489 |
-
|
| 1490 |
-
// Initialize score by reading the incrementally updated scores included in
|
| 1491 |
-
// the position object (material + piece square tables) and the material
|
| 1492 |
-
// imbalance. Score is computed internally from the white point of view.
|
| 1493 |
-
Score score = pos.psq_score();
|
| 1494 |
-
if (T)
|
| 1495 |
-
Trace::add(MATERIAL, score);
|
| 1496 |
-
score += me->imbalance() + pos.this_thread()->trend;
|
| 1497 |
-
|
| 1498 |
-
// Probe the pawn hash table
|
| 1499 |
-
pe = Pawns::probe(pos);
|
| 1500 |
-
score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
|
| 1501 |
-
|
| 1502 |
-
// Early exit if score is high
|
| 1503 |
-
auto lazy_skip = [&](Value lazyThreshold) {
|
| 1504 |
-
return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
|
| 1505 |
-
};
|
| 1506 |
-
|
| 1507 |
-
if (lazy_skip(LazyThreshold1) && Options["UCI_Variant"] == "chess")
|
| 1508 |
-
goto make_v;
|
| 1509 |
-
|
| 1510 |
-
// Main evaluation begins here
|
| 1511 |
-
std::memset(attackedBy, 0, sizeof(attackedBy));
|
| 1512 |
-
initialize<WHITE>();
|
| 1513 |
-
initialize<BLACK>();
|
| 1514 |
-
|
| 1515 |
-
// Pieces evaluated first (also populates attackedBy, attackedBy2).
|
| 1516 |
-
// For unused piece types, we still need to set attack bitboard to zero.
|
| 1517 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 1518 |
-
{
|
| 1519 |
-
PieceType pt = pop_lsb(ps);
|
| 1520 |
-
if (pt != SHOGI_PAWN && pt != PAWN && pt != KING)
|
| 1521 |
-
score += pieces<WHITE>(pt) - pieces<BLACK>(pt);
|
| 1522 |
-
}
|
| 1523 |
-
|
| 1524 |
-
// Evaluate pieces in hand once attack tables are complete
|
| 1525 |
-
if (pos.piece_drops() || pos.seirawan_gating())
|
| 1526 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 1527 |
-
{
|
| 1528 |
-
PieceType pt = pop_lsb(ps);
|
| 1529 |
-
score += hand<WHITE>(pt) - hand<BLACK>(pt);
|
| 1530 |
-
}
|
| 1531 |
-
|
| 1532 |
-
score += (mobility[WHITE] - mobility[BLACK]) * (1 + pos.captures_to_hand() + pos.must_capture() + pos.check_counting());
|
| 1533 |
-
|
| 1534 |
-
// More complex interactions that require fully populated attack bitboards
|
| 1535 |
-
score += king< WHITE>() - king< BLACK>()
|
| 1536 |
-
+ passed< WHITE>() - passed< BLACK>()
|
| 1537 |
-
+ variant<WHITE>() - variant<BLACK>();
|
| 1538 |
-
|
| 1539 |
-
if (lazy_skip(LazyThreshold2) && Options["UCI_Variant"] == "chess")
|
| 1540 |
-
goto make_v;
|
| 1541 |
-
|
| 1542 |
-
score += threats<WHITE>() - threats<BLACK>()
|
| 1543 |
-
+ space< WHITE>() - space< BLACK>();
|
| 1544 |
-
|
| 1545 |
-
make_v:
|
| 1546 |
-
// Derive single value from mg and eg parts of score
|
| 1547 |
-
Value v = winnable(score);
|
| 1548 |
-
|
| 1549 |
-
// In case of tracing add all remaining individual evaluation terms
|
| 1550 |
-
if constexpr (T)
|
| 1551 |
-
{
|
| 1552 |
-
Trace::add(IMBALANCE, me->imbalance());
|
| 1553 |
-
Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
|
| 1554 |
-
Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
|
| 1555 |
-
}
|
| 1556 |
-
|
| 1557 |
-
// Evaluation grain
|
| 1558 |
-
v = (v / 16) * 16;
|
| 1559 |
-
|
| 1560 |
-
// Side to move point of view
|
| 1561 |
-
v = (pos.side_to_move() == WHITE ? v : -v) + 80 * pos.captures_to_hand();
|
| 1562 |
-
|
| 1563 |
-
return v;
|
| 1564 |
-
}
|
| 1565 |
-
|
| 1566 |
-
|
| 1567 |
-
/// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
|
| 1568 |
-
|
| 1569 |
-
Value fix_FRC(const Position& pos) {
|
| 1570 |
-
|
| 1571 |
-
constexpr Bitboard Corners = Bitboard(1ULL) << SQ_A1 | Bitboard(1ULL) << SQ_H1 | Bitboard(1ULL) << SQ_A8 | Bitboard(1ULL) << SQ_H8;
|
| 1572 |
-
|
| 1573 |
-
if (!(pos.pieces(BISHOP) & Corners))
|
| 1574 |
-
return VALUE_ZERO;
|
| 1575 |
-
|
| 1576 |
-
int correction = 0;
|
| 1577 |
-
|
| 1578 |
-
if ( pos.piece_on(SQ_A1) == W_BISHOP
|
| 1579 |
-
&& pos.piece_on(SQ_B2) == W_PAWN)
|
| 1580 |
-
correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
|
| 1581 |
-
: -CorneredBishop * 3;
|
| 1582 |
-
|
| 1583 |
-
if ( pos.piece_on(SQ_H1) == W_BISHOP
|
| 1584 |
-
&& pos.piece_on(SQ_G2) == W_PAWN)
|
| 1585 |
-
correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
|
| 1586 |
-
: -CorneredBishop * 3;
|
| 1587 |
-
|
| 1588 |
-
if ( pos.piece_on(SQ_A8) == B_BISHOP
|
| 1589 |
-
&& pos.piece_on(SQ_B7) == B_PAWN)
|
| 1590 |
-
correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
|
| 1591 |
-
: CorneredBishop * 3;
|
| 1592 |
-
|
| 1593 |
-
if ( pos.piece_on(SQ_H8) == B_BISHOP
|
| 1594 |
-
&& pos.piece_on(SQ_G7) == B_PAWN)
|
| 1595 |
-
correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
|
| 1596 |
-
: CorneredBishop * 3;
|
| 1597 |
-
|
| 1598 |
-
return pos.side_to_move() == WHITE ? Value(correction)
|
| 1599 |
-
: -Value(correction);
|
| 1600 |
-
}
|
| 1601 |
-
|
| 1602 |
-
} // namespace Eval
|
| 1603 |
-
|
| 1604 |
-
|
| 1605 |
-
/// evaluate() is the evaluator for the outer world. It returns a static
|
| 1606 |
-
/// evaluation of the position from the point of view of the side to move.
|
| 1607 |
-
|
| 1608 |
-
Value Eval::evaluate(const Position& pos) {
|
| 1609 |
-
|
| 1610 |
-
Value v;
|
| 1611 |
-
|
| 1612 |
-
if (!Eval::useNNUE || !pos.nnue_applicable())
|
| 1613 |
-
v = Evaluation<NO_TRACE>(pos).value();
|
| 1614 |
-
else
|
| 1615 |
-
{
|
| 1616 |
-
// Scale and shift NNUE for compatibility with search and classical evaluation
|
| 1617 |
-
auto adjusted_NNUE = [&]()
|
| 1618 |
-
{
|
| 1619 |
-
int scale = 903
|
| 1620 |
-
+ 32 * pos.count<PAWN>()
|
| 1621 |
-
+ 32 * pos.non_pawn_material() / 1024;
|
| 1622 |
-
|
| 1623 |
-
Value nnue = NNUE::evaluate(pos, true) * scale / 1024;
|
| 1624 |
-
|
| 1625 |
-
if (pos.is_chess960())
|
| 1626 |
-
nnue += fix_FRC(pos);
|
| 1627 |
-
|
| 1628 |
-
if (pos.check_counting())
|
| 1629 |
-
{
|
| 1630 |
-
Color us = pos.side_to_move();
|
| 1631 |
-
nnue += 6 * scale / (5 * pos.checks_remaining( us))
|
| 1632 |
-
- 6 * scale / (5 * pos.checks_remaining(~us));
|
| 1633 |
-
}
|
| 1634 |
-
|
| 1635 |
-
return nnue;
|
| 1636 |
-
};
|
| 1637 |
-
|
| 1638 |
-
// If there is PSQ imbalance we use the classical eval, but we switch to
|
| 1639 |
-
// NNUE eval faster when shuffling or if the material on the board is high.
|
| 1640 |
-
int r50 = pos.rule50_count();
|
| 1641 |
-
Value psq = Value(abs(eg_value(pos.psq_score())));
|
| 1642 |
-
bool pure = !pos.check_counting();
|
| 1643 |
-
bool classical = psq * 5 > (750 + pos.non_pawn_material() / 64) * (5 + r50) && !pure;
|
| 1644 |
-
|
| 1645 |
-
v = classical ? Evaluation<NO_TRACE>(pos).value() // classical
|
| 1646 |
-
: adjusted_NNUE(); // NNUE
|
| 1647 |
-
}
|
| 1648 |
-
|
| 1649 |
-
// Damp down the evaluation linearly when shuffling
|
| 1650 |
-
if (pos.n_move_rule())
|
| 1651 |
-
{
|
| 1652 |
-
v = v * (2 * pos.n_move_rule() - pos.rule50_count()) / (2 * pos.n_move_rule());
|
| 1653 |
-
if (pos.material_counting())
|
| 1654 |
-
v += pos.material_counting_result() / (10 * std::max(2 * pos.n_move_rule() - pos.rule50_count(), 1));
|
| 1655 |
-
}
|
| 1656 |
-
|
| 1657 |
-
// Guarantee evaluation does not hit the virtual win/loss range
|
| 1658 |
-
if (pos.two_boards() && std::abs(v) >= VALUE_VIRTUAL_MATE_IN_MAX_PLY)
|
| 1659 |
-
v += v > VALUE_ZERO ? MAX_PLY + 1 : -MAX_PLY - 1;
|
| 1660 |
-
|
| 1661 |
-
// Guarantee evaluation does not hit the tablebase range
|
| 1662 |
-
v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
| 1663 |
-
|
| 1664 |
-
return v;
|
| 1665 |
-
}
|
| 1666 |
-
|
| 1667 |
-
/// trace() is like evaluate(), but instead of returning a value, it returns
|
| 1668 |
-
/// a string (suitable for outputting to stdout) that contains the detailed
|
| 1669 |
-
/// descriptions and values of each evaluation term. Useful for debugging.
|
| 1670 |
-
/// Trace scores are from white's point of view
|
| 1671 |
-
|
| 1672 |
-
std::string Eval::trace(Position& pos) {
|
| 1673 |
-
|
| 1674 |
-
if (pos.checkers())
|
| 1675 |
-
return "Final evaluation: none (in check)";
|
| 1676 |
-
|
| 1677 |
-
std::stringstream ss;
|
| 1678 |
-
ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
|
| 1679 |
-
|
| 1680 |
-
Value v;
|
| 1681 |
-
|
| 1682 |
-
std::memset(scores, 0, sizeof(scores));
|
| 1683 |
-
|
| 1684 |
-
pos.this_thread()->trend = SCORE_ZERO; // Reset any dynamic contempt
|
| 1685 |
-
|
| 1686 |
-
v = Evaluation<TRACE>(pos).value();
|
| 1687 |
-
|
| 1688 |
-
ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
|
| 1689 |
-
<< " Contributing terms for the classical eval:\n"
|
| 1690 |
-
<< "+------------+-------------+-------------+-------------+\n"
|
| 1691 |
-
<< "| Term | White | Black | Total |\n"
|
| 1692 |
-
<< "| | MG EG | MG EG | MG EG |\n"
|
| 1693 |
-
<< "+------------+-------------+-------------+-------------+\n"
|
| 1694 |
-
<< "| Material | " << Term(MATERIAL)
|
| 1695 |
-
<< "| Imbalance | " << Term(IMBALANCE)
|
| 1696 |
-
<< "| Pawns | " << Term(PAWN)
|
| 1697 |
-
<< "| Knights | " << Term(KNIGHT)
|
| 1698 |
-
<< "| Bishops | " << Term(BISHOP)
|
| 1699 |
-
<< "| Rooks | " << Term(ROOK)
|
| 1700 |
-
<< "| Queens | " << Term(QUEEN)
|
| 1701 |
-
<< "| Mobility | " << Term(MOBILITY)
|
| 1702 |
-
<< "|King safety | " << Term(KING)
|
| 1703 |
-
<< "| Threats | " << Term(THREAT)
|
| 1704 |
-
<< "| Passed | " << Term(PASSED)
|
| 1705 |
-
<< "| Space | " << Term(SPACE)
|
| 1706 |
-
<< "| Variant | " << Term(VARIANT)
|
| 1707 |
-
<< "| Winnable | " << Term(WINNABLE)
|
| 1708 |
-
<< "+------------+-------------+-------------+-------------+\n"
|
| 1709 |
-
<< "| Total | " << Term(TOTAL)
|
| 1710 |
-
<< "+------------+-------------+-------------+-------------+\n";
|
| 1711 |
-
|
| 1712 |
-
if (Eval::useNNUE && pos.nnue_applicable())
|
| 1713 |
-
ss << '\n' << NNUE::trace(pos) << '\n';
|
| 1714 |
-
|
| 1715 |
-
ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
|
| 1716 |
-
|
| 1717 |
-
v = pos.side_to_move() == WHITE ? v : -v;
|
| 1718 |
-
ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
|
| 1719 |
-
if (Eval::useNNUE && pos.nnue_applicable())
|
| 1720 |
-
{
|
| 1721 |
-
v = NNUE::evaluate(pos, false);
|
| 1722 |
-
v = pos.side_to_move() == WHITE ? v : -v;
|
| 1723 |
-
ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
|
| 1724 |
-
}
|
| 1725 |
-
|
| 1726 |
-
v = evaluate(pos);
|
| 1727 |
-
v = pos.side_to_move() == WHITE ? v : -v;
|
| 1728 |
-
ss << "Final evaluation " << to_cp(v) << " (white side)";
|
| 1729 |
-
if (Eval::useNNUE && pos.nnue_applicable())
|
| 1730 |
-
ss << " [with scaled NNUE, hybrid, ...]";
|
| 1731 |
-
ss << "\n";
|
| 1732 |
-
|
| 1733 |
-
return ss.str();
|
| 1734 |
-
}
|
| 1735 |
-
|
| 1736 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/evaluate.h
DELETED
|
@@ -1,66 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef EVALUATE_H_INCLUDED
|
| 20 |
-
#define EVALUATE_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <string>
|
| 23 |
-
#include <optional>
|
| 24 |
-
|
| 25 |
-
#include "types.h"
|
| 26 |
-
|
| 27 |
-
#include "variant.h"
|
| 28 |
-
|
| 29 |
-
namespace Stockfish {
|
| 30 |
-
|
| 31 |
-
class Position;
|
| 32 |
-
|
| 33 |
-
namespace Eval {
|
| 34 |
-
|
| 35 |
-
std::string trace(Position& pos);
|
| 36 |
-
Value evaluate(const Position& pos);
|
| 37 |
-
|
| 38 |
-
extern bool useNNUE;
|
| 39 |
-
extern std::string eval_file_loaded;
|
| 40 |
-
|
| 41 |
-
// The default net name MUST follow the format nn-[SHA256 first 12 digits].nnue
|
| 42 |
-
// for the build process (profile-build and fishtest) to work. Do not change the
|
| 43 |
-
// name of the macro, as it is used in the Makefile.
|
| 44 |
-
#define EvalFileDefaultName "nn-3475407dc199.nnue"
|
| 45 |
-
|
| 46 |
-
namespace NNUE {
|
| 47 |
-
|
| 48 |
-
std::string trace(Position& pos);
|
| 49 |
-
Value evaluate(const Position& pos, bool adjusted = false);
|
| 50 |
-
|
| 51 |
-
void init();
|
| 52 |
-
void verify();
|
| 53 |
-
|
| 54 |
-
bool load_eval(std::string name, std::istream& stream);
|
| 55 |
-
bool save_eval(std::ostream& stream);
|
| 56 |
-
bool save_eval(const std::optional<std::string>& filename);
|
| 57 |
-
|
| 58 |
-
} // namespace NNUE
|
| 59 |
-
|
| 60 |
-
} // namespace Eval
|
| 61 |
-
|
| 62 |
-
extern const Variant* currentNnueVariant;
|
| 63 |
-
|
| 64 |
-
} // namespace Stockfish
|
| 65 |
-
|
| 66 |
-
#endif // #ifndef EVALUATE_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/ffishjs.cpp
DELETED
|
@@ -1,767 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
ffish.js, a JavaScript chess variant library derived from Fairy-Stockfish
|
| 3 |
-
Copyright (C) 2022 Fabian Fichter, Johannes Czech
|
| 4 |
-
|
| 5 |
-
ffish.js is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
ffish.js is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <emscripten.h>
|
| 20 |
-
#include <emscripten/bind.h>
|
| 21 |
-
#include <vector>
|
| 22 |
-
#include <string>
|
| 23 |
-
#include <sstream>
|
| 24 |
-
#include<iostream>
|
| 25 |
-
|
| 26 |
-
#include "misc.h"
|
| 27 |
-
#include "types.h"
|
| 28 |
-
#include "bitboard.h"
|
| 29 |
-
#include "evaluate.h"
|
| 30 |
-
#include "position.h"
|
| 31 |
-
#include "search.h"
|
| 32 |
-
#include "syzygy/tbprobe.h"
|
| 33 |
-
#include "thread.h"
|
| 34 |
-
#include "tt.h"
|
| 35 |
-
#include "uci.h"
|
| 36 |
-
#include "piece.h"
|
| 37 |
-
#include "variant.h"
|
| 38 |
-
#include "movegen.h"
|
| 39 |
-
#include "apiutil.h"
|
| 40 |
-
|
| 41 |
-
using namespace emscripten;
|
| 42 |
-
|
| 43 |
-
using namespace Stockfish;
|
| 44 |
-
|
| 45 |
-
void initialize_stockfish() {
|
| 46 |
-
pieceMap.init();
|
| 47 |
-
variants.init();
|
| 48 |
-
UCI::init(Options);
|
| 49 |
-
Bitboards::init();
|
| 50 |
-
Position::init();
|
| 51 |
-
Bitbases::init();
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
#define DELIM " "
|
| 55 |
-
|
| 56 |
-
inline void save_pop_back(std::string& s) {
|
| 57 |
-
if (s.size() != 0) {
|
| 58 |
-
s.pop_back();
|
| 59 |
-
}
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
const Variant* get_variant(const std::string& uciVariant) {
|
| 63 |
-
if (uciVariant.size() == 0 || uciVariant == "Standard" || uciVariant == "standard")
|
| 64 |
-
return variants.find("chess")->second;
|
| 65 |
-
return variants.find(uciVariant)->second;
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
template <bool isUCI>
|
| 69 |
-
inline bool is_move_none(Move move, const std::string& strMove, const Position& pos) {
|
| 70 |
-
if (move == MOVE_NONE) {
|
| 71 |
-
std::cerr << "The given ";
|
| 72 |
-
isUCI ? std::cerr << "uciMove" : std::cerr << "sanMove";
|
| 73 |
-
std::cerr << " '" << strMove << "' for position '" << pos.fen() << "' is invalid." << std::endl;
|
| 74 |
-
return true;
|
| 75 |
-
}
|
| 76 |
-
return false;
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
class Board {
|
| 80 |
-
// note: we can't use references for strings here due to conversion to JavaScript
|
| 81 |
-
private:
|
| 82 |
-
const Variant* v;
|
| 83 |
-
StateListPtr states;
|
| 84 |
-
Position pos;
|
| 85 |
-
Thread* thread;
|
| 86 |
-
std::vector<Move> moveStack;
|
| 87 |
-
bool is960;
|
| 88 |
-
|
| 89 |
-
public:
|
| 90 |
-
static bool sfInitialized;
|
| 91 |
-
|
| 92 |
-
Board():
|
| 93 |
-
Board("chess", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" , false) {
|
| 94 |
-
}
|
| 95 |
-
|
| 96 |
-
Board(std::string uciVariant):
|
| 97 |
-
Board(uciVariant, "", false) {
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
Board(std::string uciVariant, std::string fen):
|
| 101 |
-
Board(uciVariant, fen, false) {
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
Board(std::string uciVariant, std::string fen, bool is960) {
|
| 105 |
-
init(uciVariant, fen, is960);
|
| 106 |
-
}
|
| 107 |
-
|
| 108 |
-
std::string legal_moves() {
|
| 109 |
-
std::string moves;
|
| 110 |
-
for (const ExtMove& move : MoveList<LEGAL>(this->pos)) {
|
| 111 |
-
moves += UCI::move(this->pos, move);
|
| 112 |
-
moves += DELIM;
|
| 113 |
-
}
|
| 114 |
-
save_pop_back(moves);
|
| 115 |
-
return moves;
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
std::string legal_moves_san() {
|
| 119 |
-
std::string movesSan;
|
| 120 |
-
for (const ExtMove& move : MoveList<LEGAL>(this->pos)) {
|
| 121 |
-
movesSan += SAN::move_to_san(this->pos, move, NOTATION_SAN);
|
| 122 |
-
movesSan += DELIM;
|
| 123 |
-
}
|
| 124 |
-
save_pop_back(movesSan);
|
| 125 |
-
return movesSan;
|
| 126 |
-
}
|
| 127 |
-
|
| 128 |
-
int number_legal_moves() const {
|
| 129 |
-
return MoveList<LEGAL>(pos).size();
|
| 130 |
-
}
|
| 131 |
-
|
| 132 |
-
bool push(std::string uciMove) {
|
| 133 |
-
const Move move = UCI::to_move(this->pos, uciMove);
|
| 134 |
-
if (is_move_none<true>(move, uciMove, pos))
|
| 135 |
-
return false;
|
| 136 |
-
do_move(move);
|
| 137 |
-
return true;
|
| 138 |
-
}
|
| 139 |
-
|
| 140 |
-
bool push_san(std::string sanMove) {
|
| 141 |
-
return push_san(sanMove, NOTATION_SAN);
|
| 142 |
-
}
|
| 143 |
-
|
| 144 |
-
// TODO: This is a naive implementation which compares all legal SAN moves with the requested string.
|
| 145 |
-
// If the SAN move wasn't found the position remains unchanged. Alternatively, implement a direct conversion.
|
| 146 |
-
bool push_san(std::string sanMove, Notation notation) {
|
| 147 |
-
Move foundMove = MOVE_NONE;
|
| 148 |
-
for (const ExtMove& move : MoveList<LEGAL>(pos)) {
|
| 149 |
-
if (sanMove == SAN::move_to_san(this->pos, move, notation)) {
|
| 150 |
-
foundMove = move;
|
| 151 |
-
break;
|
| 152 |
-
}
|
| 153 |
-
}
|
| 154 |
-
if (is_move_none<false>(foundMove, sanMove, pos))
|
| 155 |
-
return false;
|
| 156 |
-
do_move(foundMove);
|
| 157 |
-
return true;
|
| 158 |
-
}
|
| 159 |
-
|
| 160 |
-
void pop() {
|
| 161 |
-
pos.undo_move(this->moveStack.back());
|
| 162 |
-
moveStack.pop_back();
|
| 163 |
-
states->pop_back();
|
| 164 |
-
}
|
| 165 |
-
|
| 166 |
-
void reset() {
|
| 167 |
-
set_fen(v->startFen);
|
| 168 |
-
}
|
| 169 |
-
|
| 170 |
-
bool is_960() const {
|
| 171 |
-
return is960;
|
| 172 |
-
}
|
| 173 |
-
|
| 174 |
-
std::string fen() const {
|
| 175 |
-
return this->pos.fen();
|
| 176 |
-
}
|
| 177 |
-
|
| 178 |
-
std::string fen(bool showPromoted) const {
|
| 179 |
-
return this->pos.fen(false, showPromoted);
|
| 180 |
-
}
|
| 181 |
-
|
| 182 |
-
std::string fen(bool showPromoted, int countStarted) const {
|
| 183 |
-
return this->pos.fen(false, showPromoted, countStarted);
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
void set_fen(std::string fen) {
|
| 187 |
-
resetStates();
|
| 188 |
-
moveStack.clear();
|
| 189 |
-
pos.set(v, fen, is960, &states->back(), thread);
|
| 190 |
-
}
|
| 191 |
-
|
| 192 |
-
// note: const identifier for pos not possible due to SAN::move_to_san()
|
| 193 |
-
std::string san_move(std::string uciMove) {
|
| 194 |
-
return san_move(uciMove, NOTATION_SAN);
|
| 195 |
-
}
|
| 196 |
-
|
| 197 |
-
std::string san_move(std::string uciMove, Notation notation) {
|
| 198 |
-
const Move move = UCI::to_move(this->pos, uciMove);
|
| 199 |
-
if (is_move_none<true>(move, uciMove, pos))
|
| 200 |
-
return "";
|
| 201 |
-
return SAN::move_to_san(this->pos, UCI::to_move(this->pos, uciMove), notation);
|
| 202 |
-
}
|
| 203 |
-
|
| 204 |
-
std::string variation_san(std::string uciMoves) {
|
| 205 |
-
return variation_san(uciMoves, NOTATION_SAN, true);
|
| 206 |
-
}
|
| 207 |
-
|
| 208 |
-
std::string variation_san(std::string uciMoves, Notation notation) {
|
| 209 |
-
return variation_san(uciMoves, notation, true);
|
| 210 |
-
}
|
| 211 |
-
|
| 212 |
-
std::string variation_san(std::string uciMoves, Notation notation, bool moveNumbers) {
|
| 213 |
-
std::stringstream ss(uciMoves);
|
| 214 |
-
StateListPtr tempStates;
|
| 215 |
-
std::vector<Move> moves;
|
| 216 |
-
std::string variationSan = "";
|
| 217 |
-
std::string uciMove;
|
| 218 |
-
bool first = true;
|
| 219 |
-
|
| 220 |
-
while (std::getline(ss, uciMove, ' ')) {
|
| 221 |
-
const Move move = UCI::to_move(this->pos, uciMove);
|
| 222 |
-
if (is_move_none<true>(move, uciMove, pos))
|
| 223 |
-
return "";
|
| 224 |
-
moves.emplace_back(UCI::to_move(this->pos, uciMove));
|
| 225 |
-
if (first) {
|
| 226 |
-
first = false;
|
| 227 |
-
if (moveNumbers) {
|
| 228 |
-
variationSan = std::to_string(fullmove_number());
|
| 229 |
-
if (pos.side_to_move() == WHITE)
|
| 230 |
-
variationSan += ". ";
|
| 231 |
-
else
|
| 232 |
-
variationSan += "...";
|
| 233 |
-
}
|
| 234 |
-
variationSan += SAN::move_to_san(this->pos, moves.back(), Notation(notation));
|
| 235 |
-
}
|
| 236 |
-
else {
|
| 237 |
-
if (moveNumbers && pos.side_to_move() == WHITE) {
|
| 238 |
-
variationSan += DELIM;
|
| 239 |
-
variationSan += std::to_string(fullmove_number());
|
| 240 |
-
variationSan += ".";
|
| 241 |
-
}
|
| 242 |
-
variationSan += DELIM;
|
| 243 |
-
variationSan += SAN::move_to_san(this->pos, moves.back(), Notation(notation));
|
| 244 |
-
}
|
| 245 |
-
states->emplace_back();
|
| 246 |
-
pos.do_move(moves.back(), states->back());
|
| 247 |
-
}
|
| 248 |
-
|
| 249 |
-
// recover initial state
|
| 250 |
-
for(auto rIt = std::rbegin(moves); rIt != std::rend(moves); ++rIt) {
|
| 251 |
-
pos.undo_move(*rIt);
|
| 252 |
-
}
|
| 253 |
-
|
| 254 |
-
return variationSan;
|
| 255 |
-
}
|
| 256 |
-
|
| 257 |
-
// returns true for WHITE and false for BLACK
|
| 258 |
-
bool turn() const {
|
| 259 |
-
return !pos.side_to_move();
|
| 260 |
-
}
|
| 261 |
-
|
| 262 |
-
int fullmove_number() const {
|
| 263 |
-
return pos.game_ply() / 2 + 1;
|
| 264 |
-
}
|
| 265 |
-
|
| 266 |
-
int halfmove_clock() const {
|
| 267 |
-
return pos.rule50_count();
|
| 268 |
-
}
|
| 269 |
-
|
| 270 |
-
int game_ply() const {
|
| 271 |
-
return pos.game_ply();
|
| 272 |
-
}
|
| 273 |
-
|
| 274 |
-
bool has_insufficient_material(bool turn) const {
|
| 275 |
-
return Stockfish::has_insufficient_material(turn ? WHITE : BLACK, pos);
|
| 276 |
-
}
|
| 277 |
-
|
| 278 |
-
bool is_insufficient_material() const {
|
| 279 |
-
return Stockfish::has_insufficient_material(WHITE, pos) && Stockfish::has_insufficient_material(BLACK, pos);
|
| 280 |
-
}
|
| 281 |
-
|
| 282 |
-
bool is_game_over() const {
|
| 283 |
-
return is_game_over(false);
|
| 284 |
-
}
|
| 285 |
-
|
| 286 |
-
bool is_game_over(bool claim_draw) const {
|
| 287 |
-
if (is_insufficient_material())
|
| 288 |
-
return true;
|
| 289 |
-
if (claim_draw && pos.is_optional_game_end())
|
| 290 |
-
return true;
|
| 291 |
-
return MoveList<LEGAL>(pos).size() == 0;
|
| 292 |
-
}
|
| 293 |
-
|
| 294 |
-
std::string result() const {
|
| 295 |
-
return result(false);
|
| 296 |
-
}
|
| 297 |
-
|
| 298 |
-
std::string result(bool claim_draw) const {
|
| 299 |
-
Value result;
|
| 300 |
-
bool gameEnd = pos.is_immediate_game_end(result);
|
| 301 |
-
if (!gameEnd) {
|
| 302 |
-
if (is_insufficient_material()) {
|
| 303 |
-
gameEnd = true;
|
| 304 |
-
result = VALUE_DRAW;
|
| 305 |
-
}
|
| 306 |
-
}
|
| 307 |
-
if (!gameEnd && MoveList<LEGAL>(pos).size() == 0) {
|
| 308 |
-
gameEnd = true;
|
| 309 |
-
result = pos.checkers() ? pos.checkmate_value() : pos.stalemate_value();
|
| 310 |
-
}
|
| 311 |
-
if (!gameEnd && claim_draw)
|
| 312 |
-
gameEnd = pos.is_optional_game_end(result);
|
| 313 |
-
|
| 314 |
-
if (!gameEnd)
|
| 315 |
-
return "*";
|
| 316 |
-
if (result == 0)
|
| 317 |
-
return "1/2-1/2";
|
| 318 |
-
if (pos.side_to_move() == BLACK)
|
| 319 |
-
result = -result;
|
| 320 |
-
if (result > 0)
|
| 321 |
-
return "1-0";
|
| 322 |
-
else
|
| 323 |
-
return "0-1";
|
| 324 |
-
}
|
| 325 |
-
|
| 326 |
-
std::string checked_pieces() const {
|
| 327 |
-
Bitboard checked = Stockfish::checked(pos);
|
| 328 |
-
std::string squares;
|
| 329 |
-
while (checked) {
|
| 330 |
-
Square sr = pop_lsb(checked);
|
| 331 |
-
squares += UCI::square(pos, sr);
|
| 332 |
-
squares += DELIM;
|
| 333 |
-
}
|
| 334 |
-
save_pop_back(squares);
|
| 335 |
-
return squares;
|
| 336 |
-
}
|
| 337 |
-
|
| 338 |
-
bool is_check() const {
|
| 339 |
-
return Stockfish::checked(pos);
|
| 340 |
-
}
|
| 341 |
-
|
| 342 |
-
bool is_bikjang() const {
|
| 343 |
-
return pos.bikjang();
|
| 344 |
-
}
|
| 345 |
-
|
| 346 |
-
bool is_capture(std::string uciMove) const {
|
| 347 |
-
return pos.capture(UCI::to_move(pos, uciMove));
|
| 348 |
-
}
|
| 349 |
-
|
| 350 |
-
std::string move_stack() const {
|
| 351 |
-
std::string moves;
|
| 352 |
-
for(auto it = std::begin(moveStack); it != std::end(moveStack); ++it) {
|
| 353 |
-
moves += UCI::move(pos, *it);
|
| 354 |
-
moves += DELIM;
|
| 355 |
-
}
|
| 356 |
-
save_pop_back(moves);
|
| 357 |
-
return moves;
|
| 358 |
-
}
|
| 359 |
-
|
| 360 |
-
void push_moves(std::string uciMoves) {
|
| 361 |
-
std::stringstream ss(uciMoves);
|
| 362 |
-
std::string uciMove;
|
| 363 |
-
while (std::getline(ss, uciMove, ' ')) {
|
| 364 |
-
push(uciMove);
|
| 365 |
-
}
|
| 366 |
-
}
|
| 367 |
-
|
| 368 |
-
void push_san_moves(std::string sanMoves) {
|
| 369 |
-
return push_san_moves(sanMoves, NOTATION_SAN);
|
| 370 |
-
}
|
| 371 |
-
|
| 372 |
-
void push_san_moves(std::string sanMoves, Notation notation) {
|
| 373 |
-
std::stringstream ss(sanMoves);
|
| 374 |
-
std::string sanMove;
|
| 375 |
-
while (std::getline(ss, sanMove, ' '))
|
| 376 |
-
push_san(sanMove, notation);
|
| 377 |
-
}
|
| 378 |
-
|
| 379 |
-
std::string pocket(bool color) {
|
| 380 |
-
const Color c = Color(!color);
|
| 381 |
-
std::string pocket;
|
| 382 |
-
for (PieceType pt = KING; pt >= PAWN; --pt) {
|
| 383 |
-
for (int i = 0; i < pos.count_in_hand(c, pt); ++i) {
|
| 384 |
-
// only create BLACK pieces in order to convert to lower case
|
| 385 |
-
pocket += std::string(1, pos.piece_to_char()[make_piece(BLACK, pt)]);
|
| 386 |
-
}
|
| 387 |
-
}
|
| 388 |
-
return pocket;
|
| 389 |
-
}
|
| 390 |
-
|
| 391 |
-
std::string to_string() {
|
| 392 |
-
std::string stringBoard;
|
| 393 |
-
for (Rank r = pos.max_rank(); r >= RANK_1; --r) {
|
| 394 |
-
for (File f = FILE_A; f <= pos.max_file(); ++f) {
|
| 395 |
-
if (f != FILE_A)
|
| 396 |
-
stringBoard += " ";
|
| 397 |
-
const Piece p = pos.piece_on(make_square(f, r));
|
| 398 |
-
switch(p) {
|
| 399 |
-
case NO_PIECE:
|
| 400 |
-
stringBoard += '.';
|
| 401 |
-
break;
|
| 402 |
-
default:
|
| 403 |
-
stringBoard += pos.piece_to_char()[p];
|
| 404 |
-
}
|
| 405 |
-
}
|
| 406 |
-
if (r != RANK_1)
|
| 407 |
-
stringBoard += "\n";
|
| 408 |
-
}
|
| 409 |
-
return stringBoard;
|
| 410 |
-
}
|
| 411 |
-
|
| 412 |
-
std::string to_verbose_string() {
|
| 413 |
-
std::stringstream ss;
|
| 414 |
-
operator<<(ss, pos);
|
| 415 |
-
return ss.str();
|
| 416 |
-
}
|
| 417 |
-
|
| 418 |
-
std::string variant() {
|
| 419 |
-
// Iterate through the variants map
|
| 420 |
-
for (auto it = variants.begin(); it != variants.end(); ++it)
|
| 421 |
-
if (it->second == v)
|
| 422 |
-
return it->first;
|
| 423 |
-
|
| 424 |
-
std::cerr << "Current variant is not registered." << std::endl;
|
| 425 |
-
return "unknown";
|
| 426 |
-
}
|
| 427 |
-
|
| 428 |
-
private:
|
| 429 |
-
void resetStates() {
|
| 430 |
-
this->states = StateListPtr(new std::deque<StateInfo>(1));
|
| 431 |
-
}
|
| 432 |
-
|
| 433 |
-
void do_move(Move move) {
|
| 434 |
-
states->emplace_back();
|
| 435 |
-
this->pos.do_move(move, states->back());
|
| 436 |
-
this->moveStack.emplace_back(move);
|
| 437 |
-
}
|
| 438 |
-
|
| 439 |
-
void init(std::string uciVariant, std::string fen, bool is960) {
|
| 440 |
-
if (!Board::sfInitialized) {
|
| 441 |
-
initialize_stockfish();
|
| 442 |
-
Board::sfInitialized = true;
|
| 443 |
-
}
|
| 444 |
-
v = get_variant(uciVariant);
|
| 445 |
-
UCI::init_variant(v);
|
| 446 |
-
this->resetStates();
|
| 447 |
-
if (fen == "")
|
| 448 |
-
fen = v->startFen;
|
| 449 |
-
this->pos.set(this->v, fen, is960, &this->states->back(), this->thread);
|
| 450 |
-
this->is960 = is960;
|
| 451 |
-
}
|
| 452 |
-
};
|
| 453 |
-
|
| 454 |
-
bool Board::sfInitialized = false;
|
| 455 |
-
|
| 456 |
-
namespace ffish {
|
| 457 |
-
// returns the version of the Fairy-Stockfish binary
|
| 458 |
-
std::string info() {
|
| 459 |
-
return engine_info();
|
| 460 |
-
}
|
| 461 |
-
|
| 462 |
-
template <typename T>
|
| 463 |
-
void set_option(std::string name, T value) {
|
| 464 |
-
Options[name] = value;
|
| 465 |
-
Board::sfInitialized = false;
|
| 466 |
-
}
|
| 467 |
-
|
| 468 |
-
std::string available_variants() {
|
| 469 |
-
std::string availableVariants;
|
| 470 |
-
for (std::string variant : variants.get_keys()) {
|
| 471 |
-
availableVariants += variant;
|
| 472 |
-
availableVariants += DELIM;
|
| 473 |
-
}
|
| 474 |
-
save_pop_back(availableVariants);
|
| 475 |
-
return availableVariants;
|
| 476 |
-
}
|
| 477 |
-
|
| 478 |
-
void load_variant_config(std::string variantInitContent) {
|
| 479 |
-
std::stringstream ss(variantInitContent);
|
| 480 |
-
if (!Board::sfInitialized)
|
| 481 |
-
initialize_stockfish();
|
| 482 |
-
variants.parse_istream<false>(ss);
|
| 483 |
-
Options["UCI_Variant"].set_combo(variants.get_keys());
|
| 484 |
-
Board::sfInitialized = true;
|
| 485 |
-
}
|
| 486 |
-
|
| 487 |
-
bool captures_to_hand(std::string uciVariant) {
|
| 488 |
-
const Variant* v = get_variant(uciVariant);
|
| 489 |
-
return v->capturesToHand;
|
| 490 |
-
}
|
| 491 |
-
|
| 492 |
-
std::string starting_fen(std::string uciVariant) {
|
| 493 |
-
const Variant* v = get_variant(uciVariant);
|
| 494 |
-
return v->startFen;
|
| 495 |
-
}
|
| 496 |
-
|
| 497 |
-
int validate_fen(std::string fen, std::string uciVariant, bool chess960) {
|
| 498 |
-
const Variant* v = get_variant(uciVariant);
|
| 499 |
-
return FEN::validate_fen(fen, v, chess960);
|
| 500 |
-
}
|
| 501 |
-
|
| 502 |
-
int validate_fen(std::string fen, std::string uciVariant) {
|
| 503 |
-
return validate_fen(fen, uciVariant, false);
|
| 504 |
-
}
|
| 505 |
-
|
| 506 |
-
int validate_fen(std::string fen) {
|
| 507 |
-
return validate_fen(fen, "chess");
|
| 508 |
-
}
|
| 509 |
-
}
|
| 510 |
-
|
| 511 |
-
class Game {
|
| 512 |
-
private:
|
| 513 |
-
std::unordered_map<std::string, std::string> header;
|
| 514 |
-
std::unique_ptr<Board> board;
|
| 515 |
-
std::string variant = "chess";
|
| 516 |
-
std::string fen = ""; // start pos
|
| 517 |
-
bool is960 = false;
|
| 518 |
-
bool parsedGame = false;
|
| 519 |
-
public:
|
| 520 |
-
std::string header_keys() {
|
| 521 |
-
std::string keys;
|
| 522 |
-
for (auto it = header.begin(); it != header.end(); ++it) {
|
| 523 |
-
keys += it->first;
|
| 524 |
-
keys += DELIM;
|
| 525 |
-
}
|
| 526 |
-
save_pop_back(keys);
|
| 527 |
-
return keys;
|
| 528 |
-
}
|
| 529 |
-
|
| 530 |
-
std::string headers(std::string item) {
|
| 531 |
-
auto it = header.find(item);
|
| 532 |
-
if (it == header.end())
|
| 533 |
-
return "";
|
| 534 |
-
return it->second;
|
| 535 |
-
}
|
| 536 |
-
|
| 537 |
-
std::string mainline_moves() {
|
| 538 |
-
if (!parsedGame)
|
| 539 |
-
return "";
|
| 540 |
-
return board->move_stack();
|
| 541 |
-
}
|
| 542 |
-
|
| 543 |
-
friend Game read_game_pgn(std::string);
|
| 544 |
-
};
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
bool skip_comment(const std::string& pgn, size_t& curIdx, size_t& lineEnd) {
|
| 548 |
-
curIdx = pgn.find('}', curIdx);
|
| 549 |
-
if (curIdx == std::string::npos) {
|
| 550 |
-
std::cerr << "Missing '}' for move comment while reading pgn." << std::endl;
|
| 551 |
-
return false;
|
| 552 |
-
}
|
| 553 |
-
if (curIdx > lineEnd)
|
| 554 |
-
lineEnd = pgn.find('\n', curIdx);
|
| 555 |
-
return true;
|
| 556 |
-
}
|
| 557 |
-
|
| 558 |
-
Game read_game_pgn(std::string pgn) {
|
| 559 |
-
Game game;
|
| 560 |
-
size_t lineStart = 0;
|
| 561 |
-
bool headersParsed = false;
|
| 562 |
-
|
| 563 |
-
while(true) {
|
| 564 |
-
size_t lineEnd = pgn.find('\n', lineStart);
|
| 565 |
-
|
| 566 |
-
if (lineEnd == std::string::npos)
|
| 567 |
-
lineEnd = pgn.size();
|
| 568 |
-
|
| 569 |
-
if (!headersParsed && pgn[lineStart] == '[') {
|
| 570 |
-
// parse header
|
| 571 |
-
// look for item
|
| 572 |
-
size_t headerKeyStart = lineStart+1;
|
| 573 |
-
size_t headerKeyEnd = pgn.find(' ', lineStart);
|
| 574 |
-
size_t headerItemStart = pgn.find('"', headerKeyEnd)+1;
|
| 575 |
-
size_t headerItemEnd = pgn.find('"', headerItemStart);
|
| 576 |
-
|
| 577 |
-
// put item into list
|
| 578 |
-
game.header[pgn.substr(headerKeyStart, headerKeyEnd-headerKeyStart)] = pgn.substr(headerItemStart, headerItemEnd-headerItemStart);
|
| 579 |
-
}
|
| 580 |
-
else {
|
| 581 |
-
if (!headersParsed) {
|
| 582 |
-
headersParsed = true;
|
| 583 |
-
auto it = game.header.find("Variant");
|
| 584 |
-
if (it != game.header.end()) {
|
| 585 |
-
game.is960 = it->second.find("960", it->second.size() - 3) != std::string::npos;
|
| 586 |
-
if (game.is960) {
|
| 587 |
-
game.variant = it->second.substr(0, it->second.size() - 3);
|
| 588 |
-
} else {
|
| 589 |
-
game.variant = it->second;
|
| 590 |
-
}
|
| 591 |
-
std::transform(game.variant.begin(), game.variant.end(), game.variant.begin(),
|
| 592 |
-
[](unsigned char c){ return std::tolower(c); });
|
| 593 |
-
}
|
| 594 |
-
|
| 595 |
-
it = game.header.find("FEN");
|
| 596 |
-
if (it != game.header.end())
|
| 597 |
-
game.fen = it->second;
|
| 598 |
-
|
| 599 |
-
game.board = std::make_unique<Board>(game.variant, game.fen, game.is960);
|
| 600 |
-
game.parsedGame = true;
|
| 601 |
-
}
|
| 602 |
-
|
| 603 |
-
// game line
|
| 604 |
-
size_t curIdx = lineStart;
|
| 605 |
-
while (curIdx <= lineEnd) {
|
| 606 |
-
if (pgn[curIdx] == '*')
|
| 607 |
-
return game;
|
| 608 |
-
|
| 609 |
-
if (pgn[curIdx] == '{') {
|
| 610 |
-
if (!skip_comment(pgn, curIdx, lineEnd))
|
| 611 |
-
return game;
|
| 612 |
-
++curIdx;
|
| 613 |
-
}
|
| 614 |
-
|
| 615 |
-
// Movetext RAV (Recursive Annotation Variation)
|
| 616 |
-
size_t openedRAV = 0;
|
| 617 |
-
if (pgn[curIdx] == '(') {
|
| 618 |
-
openedRAV = 1;
|
| 619 |
-
++curIdx;
|
| 620 |
-
}
|
| 621 |
-
while (openedRAV != 0) {
|
| 622 |
-
switch (pgn[curIdx]) {
|
| 623 |
-
case '(':
|
| 624 |
-
++openedRAV;
|
| 625 |
-
break;
|
| 626 |
-
case ')':
|
| 627 |
-
--openedRAV;
|
| 628 |
-
break;
|
| 629 |
-
case '{':
|
| 630 |
-
if (!skip_comment(pgn, curIdx, lineEnd))
|
| 631 |
-
return game;
|
| 632 |
-
default: ; // pass
|
| 633 |
-
}
|
| 634 |
-
++curIdx;
|
| 635 |
-
if (curIdx > lineEnd)
|
| 636 |
-
lineEnd = pgn.find('\n', curIdx);
|
| 637 |
-
}
|
| 638 |
-
|
| 639 |
-
if (pgn[curIdx] == '$') {
|
| 640 |
-
// we are at a glyph
|
| 641 |
-
curIdx = pgn.find(' ', curIdx);
|
| 642 |
-
}
|
| 643 |
-
|
| 644 |
-
if (pgn[curIdx] >= '0' && pgn[curIdx] <= '9') {
|
| 645 |
-
// we are at a move number -> look for next point
|
| 646 |
-
curIdx = pgn.find('.', curIdx);
|
| 647 |
-
if (curIdx == std::string::npos)
|
| 648 |
-
break;
|
| 649 |
-
++curIdx;
|
| 650 |
-
// increment if we're at a space
|
| 651 |
-
while (curIdx < pgn.size() && pgn[curIdx] == ' ')
|
| 652 |
-
++curIdx;
|
| 653 |
-
// increment if we're at a point
|
| 654 |
-
while (curIdx < pgn.size() && pgn[curIdx] == '.')
|
| 655 |
-
++curIdx;
|
| 656 |
-
}
|
| 657 |
-
// extract sanMove
|
| 658 |
-
size_t sanMoveEnd = std::min(pgn.find(' ', curIdx), lineEnd);
|
| 659 |
-
if (sanMoveEnd > curIdx) {
|
| 660 |
-
std::string sanMove = pgn.substr(curIdx, sanMoveEnd-curIdx);
|
| 661 |
-
// clean possible ? and ! from string
|
| 662 |
-
size_t annotationChar1 = sanMove.find('?');
|
| 663 |
-
size_t annotationChar2 = sanMove.find('!');
|
| 664 |
-
if (annotationChar1 != std::string::npos || annotationChar2 != std::string::npos)
|
| 665 |
-
sanMove = sanMove.substr(0, std::min(annotationChar1, annotationChar2));
|
| 666 |
-
std::cout << sanMove << " ";
|
| 667 |
-
game.board->push_san(sanMove);
|
| 668 |
-
}
|
| 669 |
-
curIdx = sanMoveEnd+1;
|
| 670 |
-
}
|
| 671 |
-
}
|
| 672 |
-
lineStart = lineEnd+1;
|
| 673 |
-
|
| 674 |
-
if (lineStart >= pgn.size())
|
| 675 |
-
return game;
|
| 676 |
-
}
|
| 677 |
-
return game;
|
| 678 |
-
}
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
// binding code
|
| 682 |
-
EMSCRIPTEN_BINDINGS(ffish_js) {
|
| 683 |
-
class_<Board>("Board")
|
| 684 |
-
.constructor<>()
|
| 685 |
-
.constructor<std::string>()
|
| 686 |
-
.constructor<std::string, std::string>()
|
| 687 |
-
.constructor<std::string, std::string, bool>()
|
| 688 |
-
.function("legalMoves", &Board::legal_moves)
|
| 689 |
-
.function("legalMovesSan", &Board::legal_moves_san)
|
| 690 |
-
.function("numberLegalMoves", &Board::number_legal_moves)
|
| 691 |
-
.function("push", &Board::push)
|
| 692 |
-
.function("pushSan", select_overload<bool(std::string)>(&Board::push_san))
|
| 693 |
-
.function("pushSan", select_overload<bool(std::string, Notation)>(&Board::push_san))
|
| 694 |
-
.function("pop", &Board::pop)
|
| 695 |
-
.function("reset", &Board::reset)
|
| 696 |
-
.function("is960", &Board::is_960)
|
| 697 |
-
.function("fen", select_overload<std::string()const>(&Board::fen))
|
| 698 |
-
.function("fen", select_overload<std::string(bool)const>(&Board::fen))
|
| 699 |
-
.function("fen", select_overload<std::string(bool, int)const>(&Board::fen))
|
| 700 |
-
.function("setFen", &Board::set_fen)
|
| 701 |
-
.function("sanMove", select_overload<std::string(std::string)>(&Board::san_move))
|
| 702 |
-
.function("sanMove", select_overload<std::string(std::string, Notation)>(&Board::san_move))
|
| 703 |
-
.function("variationSan", select_overload<std::string(std::string)>(&Board::variation_san))
|
| 704 |
-
.function("variationSan", select_overload<std::string(std::string, Notation)>(&Board::variation_san))
|
| 705 |
-
.function("variationSan", select_overload<std::string(std::string, Notation, bool)>(&Board::variation_san))
|
| 706 |
-
.function("turn", &Board::turn)
|
| 707 |
-
.function("fullmoveNumber", &Board::fullmove_number)
|
| 708 |
-
.function("halfmoveClock", &Board::halfmove_clock)
|
| 709 |
-
.function("gamePly", &Board::game_ply)
|
| 710 |
-
.function("hasInsufficientMaterial", &Board::has_insufficient_material)
|
| 711 |
-
.function("isInsufficientMaterial", &Board::is_insufficient_material)
|
| 712 |
-
.function("isGameOver", select_overload<bool() const>(&Board::is_game_over))
|
| 713 |
-
.function("isGameOver", select_overload<bool(bool) const>(&Board::is_game_over))
|
| 714 |
-
.function("result", select_overload<std::string() const>(&Board::result))
|
| 715 |
-
.function("result", select_overload<std::string(bool) const>(&Board::result))
|
| 716 |
-
.function("checkedPieces", &Board::checked_pieces)
|
| 717 |
-
.function("isCheck", &Board::is_check)
|
| 718 |
-
.function("isBikjang", &Board::is_bikjang)
|
| 719 |
-
.function("isCapture", &Board::is_capture)
|
| 720 |
-
.function("moveStack", &Board::move_stack)
|
| 721 |
-
.function("pushMoves", &Board::push_moves)
|
| 722 |
-
.function("pushSanMoves", select_overload<void(std::string)>(&Board::push_san_moves))
|
| 723 |
-
.function("pushSanMoves", select_overload<void(std::string, Notation)>(&Board::push_san_moves))
|
| 724 |
-
.function("pocket", &Board::pocket)
|
| 725 |
-
.function("toString", &Board::to_string)
|
| 726 |
-
.function("toVerboseString", &Board::to_verbose_string)
|
| 727 |
-
.function("variant", &Board::variant);
|
| 728 |
-
class_<Game>("Game")
|
| 729 |
-
.function("headerKeys", &Game::header_keys)
|
| 730 |
-
.function("headers", &Game::headers)
|
| 731 |
-
.function("mainlineMoves", &Game::mainline_moves);
|
| 732 |
-
// usage: e.g. ffish.Notation.DEFAULT
|
| 733 |
-
enum_<Notation>("Notation")
|
| 734 |
-
.value("DEFAULT", NOTATION_DEFAULT)
|
| 735 |
-
.value("SAN", NOTATION_SAN)
|
| 736 |
-
.value("LAN", NOTATION_LAN)
|
| 737 |
-
.value("SHOGI_HOSKING", NOTATION_SHOGI_HOSKING)
|
| 738 |
-
.value("SHOGI_HODGES", NOTATION_SHOGI_HODGES)
|
| 739 |
-
.value("SHOGI_HODGES_NUMBER", NOTATION_SHOGI_HODGES_NUMBER)
|
| 740 |
-
.value("JANGGI", NOTATION_JANGGI)
|
| 741 |
-
.value("XIANGQI_WXF", NOTATION_XIANGQI_WXF)
|
| 742 |
-
.value("THAI_SAN", NOTATION_THAI_SAN)
|
| 743 |
-
.value("THAI_LAN", NOTATION_THAI_LAN);
|
| 744 |
-
// usage: e.g. ffish.Termination.CHECKMATE
|
| 745 |
-
enum_<Termination>("Termination")
|
| 746 |
-
.value("ONGOING", ONGOING)
|
| 747 |
-
.value("CHECKMATE", CHECKMATE)
|
| 748 |
-
.value("STALEMATE", STALEMATE)
|
| 749 |
-
.value("INSUFFICIENT_MATERIAL", INSUFFICIENT_MATERIAL)
|
| 750 |
-
.value("N_MOVE_RULE", N_MOVE_RULE)
|
| 751 |
-
.value("N_FOLD_REPETITION", N_FOLD_REPETITION)
|
| 752 |
-
.value("VARIANT_END", VARIANT_END);
|
| 753 |
-
function("info", &ffish::info);
|
| 754 |
-
function("setOption", &ffish::set_option<std::string>);
|
| 755 |
-
function("setOptionInt", &ffish::set_option<int>);
|
| 756 |
-
function("setOptionBool", &ffish::set_option<bool>);
|
| 757 |
-
function("readGamePGN", &read_game_pgn);
|
| 758 |
-
function("variants", &ffish::available_variants);
|
| 759 |
-
function("loadVariantConfig", &ffish::load_variant_config);
|
| 760 |
-
function("capturesToHand", &ffish::captures_to_hand);
|
| 761 |
-
function("startingFen", &ffish::starting_fen);
|
| 762 |
-
function("validateFen", select_overload<int(std::string)>(&ffish::validate_fen));
|
| 763 |
-
function("validateFen", select_overload<int(std::string, std::string)>(&ffish::validate_fen));
|
| 764 |
-
function("validateFen", select_overload<int(std::string, std::string, bool)>(&ffish::validate_fen));
|
| 765 |
-
// TODO: enable to string conversion method
|
| 766 |
-
// .class_function("getStringFromInstance", &Board::get_string_from_instance);
|
| 767 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/incbin/UNLICENCE
DELETED
|
@@ -1,26 +0,0 @@
|
|
| 1 |
-
The file "incbin.h" is free and unencumbered software released into
|
| 2 |
-
the public domain by Dale Weiler, see:
|
| 3 |
-
<https://github.com/graphitemaster/incbin>
|
| 4 |
-
|
| 5 |
-
Anyone is free to copy, modify, publish, use, compile, sell, or
|
| 6 |
-
distribute this software, either in source code form or as a compiled
|
| 7 |
-
binary, for any purpose, commercial or non-commercial, and by any
|
| 8 |
-
means.
|
| 9 |
-
|
| 10 |
-
In jurisdictions that recognize copyright laws, the author or authors
|
| 11 |
-
of this software dedicate any and all copyright interest in the
|
| 12 |
-
software to the public domain. We make this dedication for the benefit
|
| 13 |
-
of the public at large and to the detriment of our heirs and
|
| 14 |
-
successors. We intend this dedication to be an overt act of
|
| 15 |
-
relinquishment in perpetuity of all present and future rights to this
|
| 16 |
-
software under copyright law.
|
| 17 |
-
|
| 18 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 20 |
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
| 21 |
-
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 22 |
-
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
| 23 |
-
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 24 |
-
OTHER DEALINGS IN THE SOFTWARE.
|
| 25 |
-
|
| 26 |
-
For more information, please refer to <http://unlicense.org/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/incbin/incbin.h
DELETED
|
@@ -1,368 +0,0 @@
|
|
| 1 |
-
/**
|
| 2 |
-
* @file incbin.h
|
| 3 |
-
* @author Dale Weiler
|
| 4 |
-
* @brief Utility for including binary files
|
| 5 |
-
*
|
| 6 |
-
* Facilities for including binary files into the current translation unit and
|
| 7 |
-
* making use from them externally in other translation units.
|
| 8 |
-
*/
|
| 9 |
-
#ifndef INCBIN_HDR
|
| 10 |
-
#define INCBIN_HDR
|
| 11 |
-
#include <limits.h>
|
| 12 |
-
#if defined(__AVX512BW__) || \
|
| 13 |
-
defined(__AVX512CD__) || \
|
| 14 |
-
defined(__AVX512DQ__) || \
|
| 15 |
-
defined(__AVX512ER__) || \
|
| 16 |
-
defined(__AVX512PF__) || \
|
| 17 |
-
defined(__AVX512VL__) || \
|
| 18 |
-
defined(__AVX512F__)
|
| 19 |
-
# define INCBIN_ALIGNMENT_INDEX 6
|
| 20 |
-
#elif defined(__AVX__) || \
|
| 21 |
-
defined(__AVX2__)
|
| 22 |
-
# define INCBIN_ALIGNMENT_INDEX 5
|
| 23 |
-
#elif defined(__SSE__) || \
|
| 24 |
-
defined(__SSE2__) || \
|
| 25 |
-
defined(__SSE3__) || \
|
| 26 |
-
defined(__SSSE3__) || \
|
| 27 |
-
defined(__SSE4_1__) || \
|
| 28 |
-
defined(__SSE4_2__) || \
|
| 29 |
-
defined(__neon__)
|
| 30 |
-
# define INCBIN_ALIGNMENT_INDEX 4
|
| 31 |
-
#elif ULONG_MAX != 0xffffffffu
|
| 32 |
-
# define INCBIN_ALIGNMENT_INDEX 3
|
| 33 |
-
# else
|
| 34 |
-
# define INCBIN_ALIGNMENT_INDEX 2
|
| 35 |
-
#endif
|
| 36 |
-
|
| 37 |
-
/* Lookup table of (1 << n) where `n' is `INCBIN_ALIGNMENT_INDEX' */
|
| 38 |
-
#define INCBIN_ALIGN_SHIFT_0 1
|
| 39 |
-
#define INCBIN_ALIGN_SHIFT_1 2
|
| 40 |
-
#define INCBIN_ALIGN_SHIFT_2 4
|
| 41 |
-
#define INCBIN_ALIGN_SHIFT_3 8
|
| 42 |
-
#define INCBIN_ALIGN_SHIFT_4 16
|
| 43 |
-
#define INCBIN_ALIGN_SHIFT_5 32
|
| 44 |
-
#define INCBIN_ALIGN_SHIFT_6 64
|
| 45 |
-
|
| 46 |
-
/* Actual alignment value */
|
| 47 |
-
#define INCBIN_ALIGNMENT \
|
| 48 |
-
INCBIN_CONCATENATE( \
|
| 49 |
-
INCBIN_CONCATENATE(INCBIN_ALIGN_SHIFT, _), \
|
| 50 |
-
INCBIN_ALIGNMENT_INDEX)
|
| 51 |
-
|
| 52 |
-
/* Stringize */
|
| 53 |
-
#define INCBIN_STR(X) \
|
| 54 |
-
#X
|
| 55 |
-
#define INCBIN_STRINGIZE(X) \
|
| 56 |
-
INCBIN_STR(X)
|
| 57 |
-
/* Concatenate */
|
| 58 |
-
#define INCBIN_CAT(X, Y) \
|
| 59 |
-
X ## Y
|
| 60 |
-
#define INCBIN_CONCATENATE(X, Y) \
|
| 61 |
-
INCBIN_CAT(X, Y)
|
| 62 |
-
/* Deferred macro expansion */
|
| 63 |
-
#define INCBIN_EVAL(X) \
|
| 64 |
-
X
|
| 65 |
-
#define INCBIN_INVOKE(N, ...) \
|
| 66 |
-
INCBIN_EVAL(N(__VA_ARGS__))
|
| 67 |
-
|
| 68 |
-
/* Green Hills uses a different directive for including binary data */
|
| 69 |
-
#if defined(__ghs__)
|
| 70 |
-
# if (__ghs_asm == 2)
|
| 71 |
-
# define INCBIN_MACRO ".file"
|
| 72 |
-
/* Or consider the ".myrawdata" entry in the ld file */
|
| 73 |
-
# else
|
| 74 |
-
# define INCBIN_MACRO "\tINCBIN"
|
| 75 |
-
# endif
|
| 76 |
-
#else
|
| 77 |
-
# define INCBIN_MACRO ".incbin"
|
| 78 |
-
#endif
|
| 79 |
-
|
| 80 |
-
#ifndef _MSC_VER
|
| 81 |
-
# define INCBIN_ALIGN \
|
| 82 |
-
__attribute__((aligned(INCBIN_ALIGNMENT)))
|
| 83 |
-
#else
|
| 84 |
-
# define INCBIN_ALIGN __declspec(align(INCBIN_ALIGNMENT))
|
| 85 |
-
#endif
|
| 86 |
-
|
| 87 |
-
#if defined(__arm__) || /* GNU C and RealView */ \
|
| 88 |
-
defined(__arm) || /* Diab */ \
|
| 89 |
-
defined(_ARM) /* ImageCraft */
|
| 90 |
-
# define INCBIN_ARM
|
| 91 |
-
#endif
|
| 92 |
-
|
| 93 |
-
#ifdef __GNUC__
|
| 94 |
-
/* Utilize .balign where supported */
|
| 95 |
-
# define INCBIN_ALIGN_HOST ".balign " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
| 96 |
-
# define INCBIN_ALIGN_BYTE ".balign 1\n"
|
| 97 |
-
#elif defined(INCBIN_ARM)
|
| 98 |
-
/*
|
| 99 |
-
* On arm assemblers, the alignment value is calculated as (1 << n) where `n' is
|
| 100 |
-
* the shift count. This is the value passed to `.align'
|
| 101 |
-
*/
|
| 102 |
-
# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT_INDEX) "\n"
|
| 103 |
-
# define INCBIN_ALIGN_BYTE ".align 0\n"
|
| 104 |
-
#else
|
| 105 |
-
/* We assume other inline assembler's treat `.align' as `.balign' */
|
| 106 |
-
# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
| 107 |
-
# define INCBIN_ALIGN_BYTE ".align 1\n"
|
| 108 |
-
#endif
|
| 109 |
-
|
| 110 |
-
/* INCBIN_CONST is used by incbin.c generated files */
|
| 111 |
-
#if defined(__cplusplus)
|
| 112 |
-
# define INCBIN_EXTERNAL extern "C"
|
| 113 |
-
# define INCBIN_CONST extern const
|
| 114 |
-
#else
|
| 115 |
-
# define INCBIN_EXTERNAL extern
|
| 116 |
-
# define INCBIN_CONST const
|
| 117 |
-
#endif
|
| 118 |
-
|
| 119 |
-
/**
|
| 120 |
-
* @brief Optionally override the linker section into which data is emitted.
|
| 121 |
-
*
|
| 122 |
-
* @warning If you use this facility, you'll have to deal with platform-specific linker output
|
| 123 |
-
* section naming on your own
|
| 124 |
-
*
|
| 125 |
-
* Overriding the default linker output section, e.g for esp8266/Arduino:
|
| 126 |
-
* @code
|
| 127 |
-
* #define INCBIN_OUTPUT_SECTION ".irom.text"
|
| 128 |
-
* #include "incbin.h"
|
| 129 |
-
* INCBIN(Foo, "foo.txt");
|
| 130 |
-
* // Data is emitted into program memory that never gets copied to RAM
|
| 131 |
-
* @endcode
|
| 132 |
-
*/
|
| 133 |
-
#if !defined(INCBIN_OUTPUT_SECTION)
|
| 134 |
-
# if defined(__APPLE__)
|
| 135 |
-
# define INCBIN_OUTPUT_SECTION ".const_data"
|
| 136 |
-
# else
|
| 137 |
-
# define INCBIN_OUTPUT_SECTION ".rodata"
|
| 138 |
-
# endif
|
| 139 |
-
#endif
|
| 140 |
-
|
| 141 |
-
#if defined(__APPLE__)
|
| 142 |
-
/* The directives are different for Apple branded compilers */
|
| 143 |
-
# define INCBIN_SECTION INCBIN_OUTPUT_SECTION "\n"
|
| 144 |
-
# define INCBIN_GLOBAL(NAME) ".globl " INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
| 145 |
-
# define INCBIN_INT ".long "
|
| 146 |
-
# define INCBIN_MANGLE "_"
|
| 147 |
-
# define INCBIN_BYTE ".byte "
|
| 148 |
-
# define INCBIN_TYPE(...)
|
| 149 |
-
#else
|
| 150 |
-
# define INCBIN_SECTION ".section " INCBIN_OUTPUT_SECTION "\n"
|
| 151 |
-
# define INCBIN_GLOBAL(NAME) ".global " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
| 152 |
-
# if defined(__ghs__)
|
| 153 |
-
# define INCBIN_INT ".word "
|
| 154 |
-
# else
|
| 155 |
-
# define INCBIN_INT ".int "
|
| 156 |
-
# endif
|
| 157 |
-
# if defined(__USER_LABEL_PREFIX__)
|
| 158 |
-
# define INCBIN_MANGLE INCBIN_STRINGIZE(__USER_LABEL_PREFIX__)
|
| 159 |
-
# else
|
| 160 |
-
# define INCBIN_MANGLE ""
|
| 161 |
-
# endif
|
| 162 |
-
# if defined(INCBIN_ARM)
|
| 163 |
-
/* On arm assemblers, `@' is used as a line comment token */
|
| 164 |
-
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", %object\n"
|
| 165 |
-
# elif defined(__MINGW32__) || defined(__MINGW64__)
|
| 166 |
-
/* Mingw doesn't support this directive either */
|
| 167 |
-
# define INCBIN_TYPE(NAME)
|
| 168 |
-
# else
|
| 169 |
-
/* It's safe to use `@' on other architectures */
|
| 170 |
-
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", @object\n"
|
| 171 |
-
# endif
|
| 172 |
-
# define INCBIN_BYTE ".byte "
|
| 173 |
-
#endif
|
| 174 |
-
|
| 175 |
-
/* List of style types used for symbol names */
|
| 176 |
-
#define INCBIN_STYLE_CAMEL 0
|
| 177 |
-
#define INCBIN_STYLE_SNAKE 1
|
| 178 |
-
|
| 179 |
-
/**
|
| 180 |
-
* @brief Specify the prefix to use for symbol names.
|
| 181 |
-
*
|
| 182 |
-
* By default this is `g', producing symbols of the form:
|
| 183 |
-
* @code
|
| 184 |
-
* #include "incbin.h"
|
| 185 |
-
* INCBIN(Foo, "foo.txt");
|
| 186 |
-
*
|
| 187 |
-
* // Now you have the following symbols:
|
| 188 |
-
* // const unsigned char gFooData[];
|
| 189 |
-
* // const unsigned char *const gFooEnd;
|
| 190 |
-
* // const unsigned int gFooSize;
|
| 191 |
-
* @endcode
|
| 192 |
-
*
|
| 193 |
-
* If however you specify a prefix before including: e.g:
|
| 194 |
-
* @code
|
| 195 |
-
* #define INCBIN_PREFIX incbin
|
| 196 |
-
* #include "incbin.h"
|
| 197 |
-
* INCBIN(Foo, "foo.txt");
|
| 198 |
-
*
|
| 199 |
-
* // Now you have the following symbols instead:
|
| 200 |
-
* // const unsigned char incbinFooData[];
|
| 201 |
-
* // const unsigned char *const incbinFooEnd;
|
| 202 |
-
* // const unsigned int incbinFooSize;
|
| 203 |
-
* @endcode
|
| 204 |
-
*/
|
| 205 |
-
#if !defined(INCBIN_PREFIX)
|
| 206 |
-
# define INCBIN_PREFIX g
|
| 207 |
-
#endif
|
| 208 |
-
|
| 209 |
-
/**
|
| 210 |
-
* @brief Specify the style used for symbol names.
|
| 211 |
-
*
|
| 212 |
-
* Possible options are
|
| 213 |
-
* - INCBIN_STYLE_CAMEL "CamelCase"
|
| 214 |
-
* - INCBIN_STYLE_SNAKE "snake_case"
|
| 215 |
-
*
|
| 216 |
-
* Default option is *INCBIN_STYLE_CAMEL* producing symbols of the form:
|
| 217 |
-
* @code
|
| 218 |
-
* #include "incbin.h"
|
| 219 |
-
* INCBIN(Foo, "foo.txt");
|
| 220 |
-
*
|
| 221 |
-
* // Now you have the following symbols:
|
| 222 |
-
* // const unsigned char <prefix>FooData[];
|
| 223 |
-
* // const unsigned char *const <prefix>FooEnd;
|
| 224 |
-
* // const unsigned int <prefix>FooSize;
|
| 225 |
-
* @endcode
|
| 226 |
-
*
|
| 227 |
-
* If however you specify a style before including: e.g:
|
| 228 |
-
* @code
|
| 229 |
-
* #define INCBIN_STYLE INCBIN_STYLE_SNAKE
|
| 230 |
-
* #include "incbin.h"
|
| 231 |
-
* INCBIN(foo, "foo.txt");
|
| 232 |
-
*
|
| 233 |
-
* // Now you have the following symbols:
|
| 234 |
-
* // const unsigned char <prefix>foo_data[];
|
| 235 |
-
* // const unsigned char *const <prefix>foo_end;
|
| 236 |
-
* // const unsigned int <prefix>foo_size;
|
| 237 |
-
* @endcode
|
| 238 |
-
*/
|
| 239 |
-
#if !defined(INCBIN_STYLE)
|
| 240 |
-
# define INCBIN_STYLE INCBIN_STYLE_CAMEL
|
| 241 |
-
#endif
|
| 242 |
-
|
| 243 |
-
/* Style lookup tables */
|
| 244 |
-
#define INCBIN_STYLE_0_DATA Data
|
| 245 |
-
#define INCBIN_STYLE_0_END End
|
| 246 |
-
#define INCBIN_STYLE_0_SIZE Size
|
| 247 |
-
#define INCBIN_STYLE_1_DATA _data
|
| 248 |
-
#define INCBIN_STYLE_1_END _end
|
| 249 |
-
#define INCBIN_STYLE_1_SIZE _size
|
| 250 |
-
|
| 251 |
-
/* Style lookup: returning identifier */
|
| 252 |
-
#define INCBIN_STYLE_IDENT(TYPE) \
|
| 253 |
-
INCBIN_CONCATENATE( \
|
| 254 |
-
INCBIN_STYLE_, \
|
| 255 |
-
INCBIN_CONCATENATE( \
|
| 256 |
-
INCBIN_EVAL(INCBIN_STYLE), \
|
| 257 |
-
INCBIN_CONCATENATE(_, TYPE)))
|
| 258 |
-
|
| 259 |
-
/* Style lookup: returning string literal */
|
| 260 |
-
#define INCBIN_STYLE_STRING(TYPE) \
|
| 261 |
-
INCBIN_STRINGIZE( \
|
| 262 |
-
INCBIN_STYLE_IDENT(TYPE)) \
|
| 263 |
-
|
| 264 |
-
/* Generate the global labels by indirectly invoking the macro with our style
|
| 265 |
-
* type and concatenating the name against them. */
|
| 266 |
-
#define INCBIN_GLOBAL_LABELS(NAME, TYPE) \
|
| 267 |
-
INCBIN_INVOKE( \
|
| 268 |
-
INCBIN_GLOBAL, \
|
| 269 |
-
INCBIN_CONCATENATE( \
|
| 270 |
-
NAME, \
|
| 271 |
-
INCBIN_INVOKE( \
|
| 272 |
-
INCBIN_STYLE_IDENT, \
|
| 273 |
-
TYPE))) \
|
| 274 |
-
INCBIN_INVOKE( \
|
| 275 |
-
INCBIN_TYPE, \
|
| 276 |
-
INCBIN_CONCATENATE( \
|
| 277 |
-
NAME, \
|
| 278 |
-
INCBIN_INVOKE( \
|
| 279 |
-
INCBIN_STYLE_IDENT, \
|
| 280 |
-
TYPE)))
|
| 281 |
-
|
| 282 |
-
/**
|
| 283 |
-
* @brief Externally reference binary data included in another translation unit.
|
| 284 |
-
*
|
| 285 |
-
* Produces three external symbols that reference the binary data included in
|
| 286 |
-
* another translation unit.
|
| 287 |
-
*
|
| 288 |
-
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
| 289 |
-
* "Data", as well as "End" and "Size" after. An example is provided below.
|
| 290 |
-
*
|
| 291 |
-
* @param NAME The name given for the binary data
|
| 292 |
-
*
|
| 293 |
-
* @code
|
| 294 |
-
* INCBIN_EXTERN(Foo);
|
| 295 |
-
*
|
| 296 |
-
* // Now you have the following symbols:
|
| 297 |
-
* // extern const unsigned char <prefix>FooData[];
|
| 298 |
-
* // extern const unsigned char *const <prefix>FooEnd;
|
| 299 |
-
* // extern const unsigned int <prefix>FooSize;
|
| 300 |
-
* @endcode
|
| 301 |
-
*/
|
| 302 |
-
#define INCBIN_EXTERN(NAME) \
|
| 303 |
-
INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char \
|
| 304 |
-
INCBIN_CONCATENATE( \
|
| 305 |
-
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
| 306 |
-
INCBIN_STYLE_IDENT(DATA))[]; \
|
| 307 |
-
INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char *const \
|
| 308 |
-
INCBIN_CONCATENATE( \
|
| 309 |
-
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
| 310 |
-
INCBIN_STYLE_IDENT(END)); \
|
| 311 |
-
INCBIN_EXTERNAL const unsigned int \
|
| 312 |
-
INCBIN_CONCATENATE( \
|
| 313 |
-
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
| 314 |
-
INCBIN_STYLE_IDENT(SIZE))
|
| 315 |
-
|
| 316 |
-
/**
|
| 317 |
-
* @brief Include a binary file into the current translation unit.
|
| 318 |
-
*
|
| 319 |
-
* Includes a binary file into the current translation unit, producing three symbols
|
| 320 |
-
* for objects that encode the data and size respectively.
|
| 321 |
-
*
|
| 322 |
-
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
| 323 |
-
* "Data", as well as "End" and "Size" after. An example is provided below.
|
| 324 |
-
*
|
| 325 |
-
* @param NAME The name to associate with this binary data (as an identifier.)
|
| 326 |
-
* @param FILENAME The file to include (as a string literal.)
|
| 327 |
-
*
|
| 328 |
-
* @code
|
| 329 |
-
* INCBIN(Icon, "icon.png");
|
| 330 |
-
*
|
| 331 |
-
* // Now you have the following symbols:
|
| 332 |
-
* // const unsigned char <prefix>IconData[];
|
| 333 |
-
* // const unsigned char *const <prefix>IconEnd;
|
| 334 |
-
* // const unsigned int <prefix>IconSize;
|
| 335 |
-
* @endcode
|
| 336 |
-
*
|
| 337 |
-
* @warning This must be used in global scope
|
| 338 |
-
* @warning The identifiers may be different if INCBIN_STYLE is not default
|
| 339 |
-
*
|
| 340 |
-
* To externally reference the data included by this in another translation unit
|
| 341 |
-
* please @see INCBIN_EXTERN.
|
| 342 |
-
*/
|
| 343 |
-
#ifdef _MSC_VER
|
| 344 |
-
#define INCBIN(NAME, FILENAME) \
|
| 345 |
-
INCBIN_EXTERN(NAME)
|
| 346 |
-
#else
|
| 347 |
-
#define INCBIN(NAME, FILENAME) \
|
| 348 |
-
__asm__(INCBIN_SECTION \
|
| 349 |
-
INCBIN_GLOBAL_LABELS(NAME, DATA) \
|
| 350 |
-
INCBIN_ALIGN_HOST \
|
| 351 |
-
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) ":\n" \
|
| 352 |
-
INCBIN_MACRO " \"" FILENAME "\"\n" \
|
| 353 |
-
INCBIN_GLOBAL_LABELS(NAME, END) \
|
| 354 |
-
INCBIN_ALIGN_BYTE \
|
| 355 |
-
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) ":\n" \
|
| 356 |
-
INCBIN_BYTE "1\n" \
|
| 357 |
-
INCBIN_GLOBAL_LABELS(NAME, SIZE) \
|
| 358 |
-
INCBIN_ALIGN_HOST \
|
| 359 |
-
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(SIZE) ":\n" \
|
| 360 |
-
INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) " - " \
|
| 361 |
-
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) "\n" \
|
| 362 |
-
INCBIN_ALIGN_HOST \
|
| 363 |
-
".text\n" \
|
| 364 |
-
); \
|
| 365 |
-
INCBIN_EXTERN(NAME)
|
| 366 |
-
|
| 367 |
-
#endif
|
| 368 |
-
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/magic.h
DELETED
|
@@ -1,1741 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Fairy-Stockfish, a UCI chess variant playing engine derived from Stockfish
|
| 3 |
-
Copyright (C) 2018-2022 Fabian Fichter
|
| 4 |
-
|
| 5 |
-
Fairy-Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Fairy-Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef MAGIC_H_INCLUDED
|
| 20 |
-
#define MAGIC_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
namespace Stockfish {
|
| 23 |
-
|
| 24 |
-
#ifdef PRECOMPUTED_MAGICS
|
| 25 |
-
#define B(a, b) (Bitboard(a) << 64) ^ Bitboard(b)
|
| 26 |
-
// Use precomputed magics if pext is not available,
|
| 27 |
-
// since the magics generation is very slow.
|
| 28 |
-
constexpr Bitboard RookMagicHInit[SQUARE_NB] = {
|
| 29 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 30 |
-
B(0x24200C080840A052, 0x2004004000010008),
|
| 31 |
-
B(0xC030024000228800, 0x4000010400000020),
|
| 32 |
-
B(0x1A0020802008802, 0x206010208000),
|
| 33 |
-
B(0x12002000D001024, 0x80100800090138),
|
| 34 |
-
B(0x4220010000241010, 0x3098000602001500),
|
| 35 |
-
B(0x401010004801040, 0x8000280480100000),
|
| 36 |
-
B(0x820082024921836, 0x220028000),
|
| 37 |
-
B(0x100400502411400, 0x220402120240D14),
|
| 38 |
-
B(0x880202020010404, 0xA80202510000),
|
| 39 |
-
B(0x140002801000018, 0x1000346490040),
|
| 40 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 41 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 42 |
-
B(0x8420060100020000, 0x800280400000120),
|
| 43 |
-
B(0x4010020018010, 0x40A00001100000),
|
| 44 |
-
B(0x40006A0004000200, 0x40000000110),
|
| 45 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 46 |
-
B(0x8908A20028110011, 0x800080000001A114),
|
| 47 |
-
B(0x200042000080F009, 0x20001000004000),
|
| 48 |
-
B(0x2820008820100, 0x10002400058000B9),
|
| 49 |
-
B(0x6083100420008050, 0x4040012600280080),
|
| 50 |
-
B(0x216020000000446, 0x4080204000000211),
|
| 51 |
-
B(0x340140003002089, 0x2402008000000911),
|
| 52 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 53 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 54 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 55 |
-
B(0x1010000060050000, 0x4000004050002602),
|
| 56 |
-
B(0x4022983A0060000, 0x80000040010400),
|
| 57 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 58 |
-
B(0x6020101802002840, 0x31000003000004),
|
| 59 |
-
B(0x9000420008840, 0x4881300000000210),
|
| 60 |
-
B(0xA200808865, 0x41C0048023000128),
|
| 61 |
-
B(0x31801100400000, 0x8802DC001221240),
|
| 62 |
-
B(0x884000080200920, 0x1004002410401001),
|
| 63 |
-
B(0x2400040000884, 0x421006208040C0),
|
| 64 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 65 |
-
B(0x24100400060009, 0x112008025042410),
|
| 66 |
-
B(0x1800040009040200, 0x180000A1004E408A),
|
| 67 |
-
B(0x24100400060009, 0x112008025042410),
|
| 68 |
-
B(0x4060402008080, 0xC240080000110000),
|
| 69 |
-
B(0x20080100920020, 0x2002248010242052),
|
| 70 |
-
B(0x10001010802050, 0x880000001C98420),
|
| 71 |
-
B(0x4000800100420022, 0x502022010A00D0),
|
| 72 |
-
B(0x4C18104500200885, 0x400880800),
|
| 73 |
-
B(0x8080810081020090, 0x8000000000000),
|
| 74 |
-
B(0x8000062812080201, 0x8004C8300800),
|
| 75 |
-
B(0xC010220920198, 0x85000A08000),
|
| 76 |
-
B(0x24100400060009, 0x112008025042410),
|
| 77 |
-
B(0x80102204040, 0x1000000900000000),
|
| 78 |
-
B(0x2080000004202804, 0x120880003461),
|
| 79 |
-
B(0x102004090A4030, 0x801020589240),
|
| 80 |
-
B(0x20001100814000A0, 0x420202000820004),
|
| 81 |
-
B(0x100800000A000120, 0x208000800010000),
|
| 82 |
-
B(0x1008205000040802, 0x80002000400040),
|
| 83 |
-
B(0x1480000098008401, 0xA0010000581010),
|
| 84 |
-
B(0x30C0008200100820, 0x102800080904834),
|
| 85 |
-
B(0x4810821884000500, 0x4400000200000212),
|
| 86 |
-
B(0x1811D00128A0180, 0x2500848803000000),
|
| 87 |
-
B(0x41618A0300040040, 0x21200200A421801),
|
| 88 |
-
B(0x80102204040, 0x1000000900000000),
|
| 89 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 90 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 91 |
-
B(0x40006002210044, 0x600008000408000),
|
| 92 |
-
B(0x1200447220090042, 0x80001000160012),
|
| 93 |
-
B(0x48410010AB000000, 0x9200600000000100),
|
| 94 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 95 |
-
B(0x9080000088848088, 0x4010210500000041),
|
| 96 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 97 |
-
B(0x480100400024, 0x1004800018200000),
|
| 98 |
-
B(0x808403080080200, 0x802601000000500),
|
| 99 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 100 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 101 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 102 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 103 |
-
B(0x400014006000000, 0x10006000810001F5),
|
| 104 |
-
B(0xC410062001414, 0x820080041B01044),
|
| 105 |
-
B(0x20000800310, 0x430040000201000),
|
| 106 |
-
B(0xA40010008000008, 0x4002200028000040),
|
| 107 |
-
B(0xC00102000008021C, 0x10C2000A010E024),
|
| 108 |
-
B(0x80004200104008, 0x50A00800C400020),
|
| 109 |
-
B(0x20200080012542, 0x910F0040000402C0),
|
| 110 |
-
B(0xB040100504000300, 0x24802002000040),
|
| 111 |
-
B(0x800001000014008, 0x400031004000),
|
| 112 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 113 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 114 |
-
B(0x440090001012001, 0x4020004010),
|
| 115 |
-
B(0x100A0028088020, 0x80040E00010020),
|
| 116 |
-
B(0x2180808000810, 0xB018040A00040000),
|
| 117 |
-
B(0x40C80920304C4001, 0x42800B200800000),
|
| 118 |
-
B(0x85000425001000, 0x4810048020001100),
|
| 119 |
-
B(0x600C000801000004, 0x8015084010200020),
|
| 120 |
-
B(0x20020050000240C0, 0x100202008600800),
|
| 121 |
-
B(0x38000050001220, 0x9200010200145900),
|
| 122 |
-
B(0x1042108040005, 0x1402A0802201001),
|
| 123 |
-
B(0x824240000C20400, 0x1000000400080010),
|
| 124 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 125 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 126 |
-
B(0x8000402308483, 0x20006020100100),
|
| 127 |
-
B(0x80880120000080, 0x8000240100084),
|
| 128 |
-
B(0x5840020004882001, 0x1004528000A00010),
|
| 129 |
-
B(0x8001018800300002, 0x84010040804),
|
| 130 |
-
B(0x180D10004000A008, 0xA001080008020004),
|
| 131 |
-
B(0x400080B, 0x10A0000004010000),
|
| 132 |
-
B(0x8080000200000, 0x2001000082004E0),
|
| 133 |
-
B(0x40040001000C2000, 0x2024800001004008),
|
| 134 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 135 |
-
B(0x8000402308483, 0x20006020100100),
|
| 136 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 137 |
-
B(0x2000200000, 0x1201011000802),
|
| 138 |
-
B(0x100100000000C4, 0x208004084048201),
|
| 139 |
-
B(0x400084000044, 0x100810140300),
|
| 140 |
-
B(0x29040C0C01010, 0x300204010820080),
|
| 141 |
-
B(0x1A808000020200, 0x1000000005210040),
|
| 142 |
-
B(0x20000400150000, 0x85008020),
|
| 143 |
-
B(0x40C040008184014, 0x8002AA00024010),
|
| 144 |
-
B(0x202000081B00804, 0x10001002008),
|
| 145 |
-
B(0x40011000210060, 0x6080C40000021004),
|
| 146 |
-
B(0x2000200000, 0x1201011000802),
|
| 147 |
-
B(0x4100480203840, 0x300080100804),
|
| 148 |
-
B(0x2000200000, 0x1201011000802),
|
| 149 |
-
};
|
| 150 |
-
constexpr Bitboard RookMagicVInit[SQUARE_NB] = {
|
| 151 |
-
B(0x202000812104400, 0x24800B01C0000303),
|
| 152 |
-
B(0x340020400010D, 0x88060150C00400),
|
| 153 |
-
B(0x400802040609, 0x49010200501A0002),
|
| 154 |
-
B(0x8002680301000208, 0x628006C0C020200),
|
| 155 |
-
B(0x20400209001C0804, 0xA044000800143110),
|
| 156 |
-
B(0xC400082060010202, 0x4000480401014000),
|
| 157 |
-
B(0x22500200144040, 0x8204820084704C00),
|
| 158 |
-
B(0x8C1204009030020, 0x328400805000000),
|
| 159 |
-
B(0x84800800D0001640, 0x200080040060108),
|
| 160 |
-
B(0x804810208020040, 0x140010108020000),
|
| 161 |
-
B(0x1102010B008004, 0x300208006220020),
|
| 162 |
-
B(0x140080404A0A2428, 0x6308010100080),
|
| 163 |
-
B(0x20444002120408, 0xA080010508010001),
|
| 164 |
-
B(0x82011044000D02, 0x4112028620110809),
|
| 165 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 166 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 167 |
-
B(0x920008920600040, 0x8053801004000028),
|
| 168 |
-
B(0x81140283208300, 0x10040C004200420),
|
| 169 |
-
B(0x103080022201, 0xC01000081312620),
|
| 170 |
-
B(0x2200221100008, 0x1000408104000A4),
|
| 171 |
-
B(0x4402088080042008, 0x210401501040340),
|
| 172 |
-
B(0x898400202170001, 0x80040404208000),
|
| 173 |
-
B(0x20080004051012, 0x5100048200081800),
|
| 174 |
-
B(0x2320020000401018, 0x108501021040210),
|
| 175 |
-
B(0x21080410A422021, 0x83040180008800),
|
| 176 |
-
B(0x44E8100000408224, 0x20010008040400),
|
| 177 |
-
B(0x1800240002810405, 0x23004820000020),
|
| 178 |
-
B(0x80A0100400110, 0x80104020100C4028),
|
| 179 |
-
B(0x1002050001222C0, 0x5100818004024020),
|
| 180 |
-
B(0x104000200040, 0xC010A09800102000),
|
| 181 |
-
B(0x1020003A058120, 0x450900809000302),
|
| 182 |
-
B(0x40040045008B1, 0x202800400383010),
|
| 183 |
-
B(0x4640200220034, 0x8800485420304000),
|
| 184 |
-
B(0x5001042100084288, 0x110820001240080A),
|
| 185 |
-
B(0x2002C04004010120, 0xA15008020880001),
|
| 186 |
-
B(0x2800004080C4190, 0x890808280020080),
|
| 187 |
-
B(0x40C0401000104000, 0x2020880008002580),
|
| 188 |
-
B(0x40020C002400802, 0x801104010000000),
|
| 189 |
-
B(0x44842000040080, 0x2050011084000400),
|
| 190 |
-
B(0x4110040800000401, 0x2023810029008000),
|
| 191 |
-
B(0x20884000840, 0x8017102004008000),
|
| 192 |
-
B(0x10411104000480, 0x1414042000201001),
|
| 193 |
-
B(0x220040000008, 0x800306021000000),
|
| 194 |
-
B(0x41400A0008080, 0x501000298ACAD10),
|
| 195 |
-
B(0x800240012831810, 0x80120004468050E),
|
| 196 |
-
B(0x800005020801008, 0x20102400240000),
|
| 197 |
-
B(0x20C00040C114C010, 0x88080820200C00),
|
| 198 |
-
B(0x1044010100820081, 0x20080841004000),
|
| 199 |
-
B(0x8041048400022, 0x8020836040005002),
|
| 200 |
-
B(0x2001004010205, 0x8001002884042009),
|
| 201 |
-
B(0x128088400087, 0x20008002201002),
|
| 202 |
-
B(0x8084108040402000, 0x80809000A080400),
|
| 203 |
-
B(0x408081840880, 0x201002088000040),
|
| 204 |
-
B(0xA40180010280, 0x241004006000010),
|
| 205 |
-
B(0x4204100080048140, 0x2002C4F104202020),
|
| 206 |
-
B(0x100140A10204, 0x980200800840060),
|
| 207 |
-
B(0x1005140010202048, 0x1442280800202815),
|
| 208 |
-
B(0x2000082025008600, 0x1108400040600003),
|
| 209 |
-
B(0x1005050648000, 0x200020240008002),
|
| 210 |
-
B(0x202010208044000, 0x8210404060008),
|
| 211 |
-
B(0x8011040402000210, 0xC840180408016004),
|
| 212 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 213 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 214 |
-
B(0x80101002180140, 0x40C2080820000C0),
|
| 215 |
-
B(0x208202081260800, 0x14090E4C04000050),
|
| 216 |
-
B(0x4221201084004C2, 0x110480A011060),
|
| 217 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 218 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 219 |
-
B(0x200180C840088A0, 0x401100400820000),
|
| 220 |
-
B(0x10084043A021070, 0x202041600080200),
|
| 221 |
-
B(0x210E6202001040C, 0x10100800080B0),
|
| 222 |
-
B(0x848008021204002, 0x801004308100BAD),
|
| 223 |
-
B(0xC082C0390A000601, 0x4040080189008),
|
| 224 |
-
B(0x431200240210402D, 0x58102820000),
|
| 225 |
-
B(0x202020100A0019B0, 0x4010C0D018000000),
|
| 226 |
-
B(0x800800908402203, 0x102948C84C184),
|
| 227 |
-
B(0x26801100080845, 0x4009702022A00820),
|
| 228 |
-
B(0x8880520010401040, 0x1060084832052000),
|
| 229 |
-
B(0x100100022042081, 0x10000600008C121),
|
| 230 |
-
B(0x46020384100040, 0x800200320882021),
|
| 231 |
-
B(0xC0002010148, 0x4200800800040003),
|
| 232 |
-
B(0x2002208020090040, 0x40820210021410),
|
| 233 |
-
B(0x9000A41160002004, 0x2A09000100080043),
|
| 234 |
-
B(0x800004010008001, 0x1108002020104600),
|
| 235 |
-
B(0x800540C000A4E041, 0x18021180000401),
|
| 236 |
-
B(0x808200900A900202, 0x8364202140012005),
|
| 237 |
-
B(0x1DBA52000081010, 0x4008000023000010),
|
| 238 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 239 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 240 |
-
B(0x4101100020400482, 0x2000402302100120),
|
| 241 |
-
B(0x100408000A020212, 0xA000400111000020),
|
| 242 |
-
B(0x2000010488080104, 0x3000404410208100),
|
| 243 |
-
B(0x2684220180008DD0, 0x422040200004000A),
|
| 244 |
-
B(0x2021200C0424, 0x1010100000080200),
|
| 245 |
-
B(0x8908020020801006, 0x3010800020C2000),
|
| 246 |
-
B(0x4000030008062044, 0x244010202688000),
|
| 247 |
-
B(0x242101200408009, 0x8150040000200015),
|
| 248 |
-
B(0x42004C02180204, 0x210208014241040),
|
| 249 |
-
B(0x4E1A01C208410804, 0x8890041000012004),
|
| 250 |
-
B(0x2080200401000080, 0x8001098429008004),
|
| 251 |
-
B(0xA01400121804104, 0x280200C400000500),
|
| 252 |
-
B(0xD0080408040420, 0x1006040100224000),
|
| 253 |
-
B(0x28400205000800C9, 0x6021101401040075),
|
| 254 |
-
B(0x4000900040020104, 0x88129801100D0C),
|
| 255 |
-
B(0x8000004002180410, 0x400380200400204),
|
| 256 |
-
B(0x4002A430043008, 0x400200340100020),
|
| 257 |
-
B(0x401960004140A42, 0x100880710000464),
|
| 258 |
-
B(0x58014090102, 0xB8D30004010080),
|
| 259 |
-
B(0xA004C08000244000, 0x11280100E0000040),
|
| 260 |
-
B(0x2102008089208804, 0x110001004080040),
|
| 261 |
-
B(0x700010084E003004, 0x8080864112000D40),
|
| 262 |
-
B(0x4080881000200C20, 0x30324040880E0600),
|
| 263 |
-
B(0x2024A40401810820, 0x3000888002000000),
|
| 264 |
-
B(0x8200100400014, 0x4400340800252844),
|
| 265 |
-
B(0x24A00804288281, 0x410103002201140),
|
| 266 |
-
B(0x4080005022A08, 0x1000402200100264),
|
| 267 |
-
B(0x200080032244040, 0x200502189010001),
|
| 268 |
-
B(0x28108110404001, 0x400600120008412),
|
| 269 |
-
B(0xA00002102810020, 0xB1080240015408),
|
| 270 |
-
B(0x810080200806, 0x410440804080046)
|
| 271 |
-
};
|
| 272 |
-
constexpr Bitboard BishopMagicInit[SQUARE_NB] = {
|
| 273 |
-
B(0x2001040305000010, 0x830200040400082),
|
| 274 |
-
B(0x1042400080E01200, 0x2004904010811400),
|
| 275 |
-
B(0x400010120200, 0x880080D080018000),
|
| 276 |
-
B(0x240190C00100040, 0x100A020140044404),
|
| 277 |
-
B(0x1018010404010004, 0x1001010018081E0),
|
| 278 |
-
B(0x41200A804C0904, 0x40000322000008),
|
| 279 |
-
B(0x4001180A004, 0x8000001106000000),
|
| 280 |
-
B(0x6006020020030600, 0x1840002100004841),
|
| 281 |
-
B(0x4200200100, 0x4001041808002000),
|
| 282 |
-
B(0x4100020050124600, 0x1001802902400CA0),
|
| 283 |
-
B(0x448C0081440161, 0x200206010008000),
|
| 284 |
-
B(0x400008008008408, 0x1000080210100080),
|
| 285 |
-
B(0x200280C01008200, 0x210200813000080),
|
| 286 |
-
B(0x1A000204400, 0x222200401023000),
|
| 287 |
-
B(0x10081040640A00, 0x8410021881400000),
|
| 288 |
-
B(0x1840400318080008, 0x800800840080000),
|
| 289 |
-
B(0x4204050C040, 0x6500600200140000),
|
| 290 |
-
B(0x1012100040204, 0x402404444400000),
|
| 291 |
-
B(0x6000012680008240, 0x410140000004220),
|
| 292 |
-
B(0x1000020810040008, 0x2D0011000060000),
|
| 293 |
-
B(0x1020020400, 0x400108059001001),
|
| 294 |
-
B(0x400020001100808, 0x480204800200000B),
|
| 295 |
-
B(0x10000010030084, 0x2042000848900022),
|
| 296 |
-
B(0x10000010030084, 0x2042000848900022),
|
| 297 |
-
B(0x100D801402400, 0x1512404009000400),
|
| 298 |
-
B(0x8000208005112400, 0xA02040401000000),
|
| 299 |
-
B(0x1000420002800200, 0x4CA000183020000),
|
| 300 |
-
B(0x800811480020, 0x408801010224001),
|
| 301 |
-
B(0xC805200810900100, 0x9000084204004020),
|
| 302 |
-
B(0x8200160204100004, 0x8040004004002022),
|
| 303 |
-
B(0x104514013080080, 0x146410040001000),
|
| 304 |
-
B(0x140844000080002, 0x1008102020040001),
|
| 305 |
-
B(0x4040400041A2002, 0x8040000A8802510),
|
| 306 |
-
B(0x801014041008002, 0x80068008025200),
|
| 307 |
-
B(0xA00540A414040, 0x4101040010A0000),
|
| 308 |
-
B(0x6484008010810002, 0x1100506884024000),
|
| 309 |
-
B(0x2800401008006000, 0x1005420884029020),
|
| 310 |
-
B(0x6822091010004421, 0x2000458080480),
|
| 311 |
-
B(0x40101000200101, 0x10020100001C4E0),
|
| 312 |
-
B(0x100400008C42, 0x4000100009008000),
|
| 313 |
-
B(0x851220018800400, 0x1681800040080080),
|
| 314 |
-
B(0x64200002010, 0x900020200040002),
|
| 315 |
-
B(0x20800080000022, 0x80040810002010),
|
| 316 |
-
B(0xA88408000802080, 0x20808001000000),
|
| 317 |
-
B(0x200000400C005040, 0x100140020290108),
|
| 318 |
-
B(0x224100000800408, 0x4204802004400020),
|
| 319 |
-
B(0x80080620010210, 0x91080088804040),
|
| 320 |
-
B(0x4008002100010, 0x80AC201001000001),
|
| 321 |
-
B(0x10008200902C046, 0x8080D03004000010),
|
| 322 |
-
B(0x3002100081000180, 0x2210002121528408),
|
| 323 |
-
B(0x8C101800804420, 0x1019880200043008),
|
| 324 |
-
B(0x200022000920D0, 0x8000800081300020),
|
| 325 |
-
B(0x1D40800880000, 0x400040001400050),
|
| 326 |
-
B(0x2020004100040, 0x200008040008008),
|
| 327 |
-
B(0x4840800040100001, 0x100100040203040),
|
| 328 |
-
B(0x40084001105, 0x8800080088000089),
|
| 329 |
-
B(0x4000128008020008, 0x4004200200440020),
|
| 330 |
-
B(0x210040008520000, 0x820219001080022),
|
| 331 |
-
B(0x1494040018002116, 0x400101047020008),
|
| 332 |
-
B(0x510008001910C224, 0x80200148118000),
|
| 333 |
-
B(0xC0301002301000, 0x4211A08004801),
|
| 334 |
-
B(0x50008E0C01001080, 0x100C004102845100),
|
| 335 |
-
B(0x400600020060400, 0x88024100250050),
|
| 336 |
-
B(0x8202920002002040, 0x810012000003),
|
| 337 |
-
B(0x800004208800200, 0x18AA00201000048),
|
| 338 |
-
B(0x402100800100002, 0x411000081000400),
|
| 339 |
-
B(0x101000022004044, 0x9000100040000),
|
| 340 |
-
B(0x41068001001, 0xC00400010001),
|
| 341 |
-
B(0x310210001040, 0x1A1200020010000),
|
| 342 |
-
B(0xA082409200004048, 0x490040800124101),
|
| 343 |
-
B(0x18844820E0040212, 0x1000404420D10000),
|
| 344 |
-
B(0x802908A40003348, 0x20200040104140),
|
| 345 |
-
B(0x1800404028205003, 0xC020010401089020),
|
| 346 |
-
B(0x802100044D01000, 0x8C41888000800040),
|
| 347 |
-
B(0x1D0161011410081, 0x10008000100200),
|
| 348 |
-
B(0x401000480040100, 0x286800404002212),
|
| 349 |
-
B(0x821030000100009, 0x2000090200A00000),
|
| 350 |
-
B(0x200020800200800, 0x2000480900841012),
|
| 351 |
-
B(0x80A000048030080, 0x200000120200008),
|
| 352 |
-
B(0x40B1400008020020, 0x148000200008004),
|
| 353 |
-
B(0xA021700002002010, 0x3040E400040100),
|
| 354 |
-
B(0x400242C200200640, 0x20440210200281),
|
| 355 |
-
B(0x80AC140040206240, 0x120000102801401),
|
| 356 |
-
B(0x2020340040832040, 0x10402100A44000),
|
| 357 |
-
B(0x420100400040220, 0x80014C8004000106),
|
| 358 |
-
B(0x504300822421120, 0x8004004008400100),
|
| 359 |
-
B(0x2001100008040, 0x2020104302000000),
|
| 360 |
-
B(0xA500802000A, 0x2008008000114100),
|
| 361 |
-
B(0x8A0020000200, 0x9C00101001002408),
|
| 362 |
-
B(0x104000001001008, 0x9001000204040060),
|
| 363 |
-
B(0x1000820080108200, 0xA401000008100001),
|
| 364 |
-
B(0x2008600009000480, 0x9008020001400000),
|
| 365 |
-
B(0x4000800200040200, 0xA00030400308082),
|
| 366 |
-
B(0x4004300202004709, 0x1000100180010020),
|
| 367 |
-
B(0xC014800100440010, 0x402020280002C010),
|
| 368 |
-
B(0x220208010884680, 0x1040280000042110),
|
| 369 |
-
B(0x40B0018019202801, 0x1008408000100040),
|
| 370 |
-
B(0x8269010206080044, 0x8001810000000040),
|
| 371 |
-
B(0x4000020880081040, 0x208A44000028000),
|
| 372 |
-
B(0x4004004E9004220A, 0x2104004001400024),
|
| 373 |
-
B(0x8035006008C0904, 0x402002001080120),
|
| 374 |
-
B(0x1800884002, 0x404400820000000),
|
| 375 |
-
B(0x8088000004008910, 0x8024100401000000),
|
| 376 |
-
B(0x142200086000100, 0x28021040020002E),
|
| 377 |
-
B(0x1000409141004018, 0x100410820080040A),
|
| 378 |
-
B(0x1800801800140, 0x810801060C0801),
|
| 379 |
-
B(0x1000C00100402220, 0x808023420000000),
|
| 380 |
-
B(0x8A0A202414305008, 0x100040200000021),
|
| 381 |
-
B(0xC0208024050, 0x8003088008020401),
|
| 382 |
-
B(0x8044004201440101, 0x400820080C024022),
|
| 383 |
-
B(0x406018884120099, 0xB00088018002000),
|
| 384 |
-
B(0x2000800010403010, 0xC5A002002010010),
|
| 385 |
-
B(0x800020040840, 0x201800202800200),
|
| 386 |
-
B(0x201280120020008D, 0x258809001000040),
|
| 387 |
-
B(0x9100002020181, 0x80400082204000),
|
| 388 |
-
B(0x104010080201001, 0x40080080181080),
|
| 389 |
-
B(0x8440248092000430, 0xA200804900100000),
|
| 390 |
-
B(0x2031010C01000C20, 0x200310A560082008),
|
| 391 |
-
B(0x400202081811400, 0x40081802050000C),
|
| 392 |
-
B(0x1011002100821300, 0x2400825040804100)
|
| 393 |
-
};
|
| 394 |
-
constexpr Bitboard CannonMagicHInit[SQUARE_NB] = {
|
| 395 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 396 |
-
B(0x24200C080840A052, 0x2004004000010008),
|
| 397 |
-
B(0xC030024000228800, 0x4000010400000020),
|
| 398 |
-
B(0x1A0020802008802, 0x206010208000),
|
| 399 |
-
B(0x12002000D001024, 0x80100800090138),
|
| 400 |
-
B(0x4220010000241010, 0x3098000602001500),
|
| 401 |
-
B(0x401010004801040, 0x8000280480100000),
|
| 402 |
-
B(0x820082024921836, 0x220028000),
|
| 403 |
-
B(0x100400502411400, 0x220402120240D14),
|
| 404 |
-
B(0x880202020010404, 0xA80202510000),
|
| 405 |
-
B(0x140002801000018, 0x1000346490040),
|
| 406 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 407 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 408 |
-
B(0x8420060100020000, 0x800280400000120),
|
| 409 |
-
B(0x4010020018010, 0x40A00001100000),
|
| 410 |
-
B(0x40006A0004000200, 0x40000000110),
|
| 411 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 412 |
-
B(0x8908A20028110011, 0x800080000001A114),
|
| 413 |
-
B(0x200042000080F009, 0x20001000004000),
|
| 414 |
-
B(0x2820008820100, 0x10002400058000B9),
|
| 415 |
-
B(0x6083100420008050, 0x4040012600280080),
|
| 416 |
-
B(0x216020000000446, 0x4080204000000211),
|
| 417 |
-
B(0x340140003002089, 0x2402008000000911),
|
| 418 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 419 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 420 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 421 |
-
B(0x1010000060050000, 0x4000004050002602),
|
| 422 |
-
B(0x4022983A0060000, 0x80000040010400),
|
| 423 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 424 |
-
B(0x6020101802002840, 0x31000003000004),
|
| 425 |
-
B(0x9000420008840, 0x4881300000000210),
|
| 426 |
-
B(0xA200808865, 0x41C0048023000128),
|
| 427 |
-
B(0x31801100400000, 0x8802DC001221240),
|
| 428 |
-
B(0x884000080200920, 0x1004002410401001),
|
| 429 |
-
B(0x2400040000884, 0x421006208040C0),
|
| 430 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 431 |
-
B(0x24100400060009, 0x112008025042410),
|
| 432 |
-
B(0x1800040009040200, 0x180000A1004E408A),
|
| 433 |
-
B(0x24100400060009, 0x112008025042410),
|
| 434 |
-
B(0x4060402008080, 0xC240080000110000),
|
| 435 |
-
B(0x20080100920020, 0x2002248010242052),
|
| 436 |
-
B(0x10001010802050, 0x880000001C98420),
|
| 437 |
-
B(0x4000800100420022, 0x502022010A00D0),
|
| 438 |
-
B(0x4C18104500200885, 0x400880800),
|
| 439 |
-
B(0x8080810081020090, 0x8000000000000),
|
| 440 |
-
B(0x8000062812080201, 0x8004C8300800),
|
| 441 |
-
B(0x1800040009040200, 0x180000A1004E408A),
|
| 442 |
-
B(0x24100400060009, 0x112008025042410),
|
| 443 |
-
B(0x80102204040, 0x1000000900000000),
|
| 444 |
-
B(0x2080000004202804, 0x120880003461),
|
| 445 |
-
B(0x102004090A4030, 0x801020589240),
|
| 446 |
-
B(0x20001100814000A0, 0x420202000820004),
|
| 447 |
-
B(0x100800000A000120, 0x208000800010000),
|
| 448 |
-
B(0x1008205000040802, 0x80002000400040),
|
| 449 |
-
B(0x1480000098008401, 0xA0010000581010),
|
| 450 |
-
B(0x30C0008200100820, 0x102800080904834),
|
| 451 |
-
B(0x4810821884000500, 0x4400000200000212),
|
| 452 |
-
B(0x1811D00128A0180, 0x2500848803000000),
|
| 453 |
-
B(0x41618A0300040040, 0x21200200A421801),
|
| 454 |
-
B(0x80102204040, 0x1000000900000000),
|
| 455 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 456 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 457 |
-
B(0x40006002210044, 0x600008000408000),
|
| 458 |
-
B(0x1200447220090042, 0x80001000160012),
|
| 459 |
-
B(0x48410010AB000000, 0x9200600000000100),
|
| 460 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 461 |
-
B(0x9080000088848088, 0x4010210500000041),
|
| 462 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 463 |
-
B(0x480100400024, 0x1004800018200000),
|
| 464 |
-
B(0x808403080080200, 0x802601000000500),
|
| 465 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 466 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 467 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 468 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 469 |
-
B(0x400014006000000, 0x10006000810001F5),
|
| 470 |
-
B(0xC410062001414, 0x820080041B01044),
|
| 471 |
-
B(0x20000800310, 0x430040000201000),
|
| 472 |
-
B(0xA40010008000008, 0x4002200028000040),
|
| 473 |
-
B(0xC00102000008021C, 0x10C2000A010E024),
|
| 474 |
-
B(0x80004200104008, 0x50A00800C400020),
|
| 475 |
-
B(0x20200080012542, 0x910F0040000402C0),
|
| 476 |
-
B(0xB040100504000300, 0x24802002000040),
|
| 477 |
-
B(0x800001000014008, 0x400031004000),
|
| 478 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 479 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 480 |
-
B(0x440090001012001, 0x4020004010),
|
| 481 |
-
B(0x100A0028088020, 0x80040E00010020),
|
| 482 |
-
B(0x2180808000810, 0xB018040A00040000),
|
| 483 |
-
B(0x40C80920304C4001, 0x42800B200800000),
|
| 484 |
-
B(0x85000425001000, 0x4810048020001100),
|
| 485 |
-
B(0x600C000801000004, 0x8015084010200020),
|
| 486 |
-
B(0x20020050000240C0, 0x100202008600800),
|
| 487 |
-
B(0x38000050001220, 0x9200010200145900),
|
| 488 |
-
B(0x1042108040005, 0x1402A0802201001),
|
| 489 |
-
B(0x824240000C20400, 0x1000000400080010),
|
| 490 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 491 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 492 |
-
B(0x8000402308483, 0x20006020100100),
|
| 493 |
-
B(0x80880120000080, 0x8000240100084),
|
| 494 |
-
B(0x5840020004882001, 0x1004528000A00010),
|
| 495 |
-
B(0x8001018800300002, 0x84010040804),
|
| 496 |
-
B(0x180D10004000A008, 0xA001080008020004),
|
| 497 |
-
B(0x400080B, 0x10A0000004010000),
|
| 498 |
-
B(0x8080000200000, 0x2001000082004E0),
|
| 499 |
-
B(0x40040001000C2000, 0x2024800001004008),
|
| 500 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 501 |
-
B(0x8000402308483, 0x20006020100100),
|
| 502 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 503 |
-
B(0x2000200000, 0x1201011000802),
|
| 504 |
-
B(0x100100000000C4, 0x208004084048201),
|
| 505 |
-
B(0x400084000044, 0x100810140300),
|
| 506 |
-
B(0x29040C0C01010, 0x300204010820080),
|
| 507 |
-
B(0x1A808000020200, 0x1000000005210040),
|
| 508 |
-
B(0x20000400150000, 0x85008020),
|
| 509 |
-
B(0x40C040008184014, 0x8002AA00024010),
|
| 510 |
-
B(0x202000081B00804, 0x10001002008),
|
| 511 |
-
B(0x40011000210060, 0x6080C40000021004),
|
| 512 |
-
B(0x2000200000, 0x1201011000802),
|
| 513 |
-
B(0x4100480203840, 0x300080100804),
|
| 514 |
-
B(0x2000200000, 0x1201011000802),
|
| 515 |
-
};
|
| 516 |
-
constexpr Bitboard CannonMagicVInit[SQUARE_NB] = {
|
| 517 |
-
B(0x202000812104400, 0x24800B01C0000303),
|
| 518 |
-
B(0x340020400010D, 0x88060150C00400),
|
| 519 |
-
B(0x400802040609, 0x49010200501A0002),
|
| 520 |
-
B(0x8002680301000208, 0x628006C0C020200),
|
| 521 |
-
B(0x20400209001C0804, 0xA044000800143110),
|
| 522 |
-
B(0xC400082060010202, 0x4000480401014000),
|
| 523 |
-
B(0x22500200144040, 0x8204820084704C00),
|
| 524 |
-
B(0x8C1204009030020, 0x328400805000000),
|
| 525 |
-
B(0x84800800D0001640, 0x200080040060108),
|
| 526 |
-
B(0x804810208020040, 0x140010108020000),
|
| 527 |
-
B(0x1102010B008004, 0x300208006220020),
|
| 528 |
-
B(0x140080404A0A2428, 0x6308010100080),
|
| 529 |
-
B(0x20444002120408, 0xA080010508010001),
|
| 530 |
-
B(0x82011044000D02, 0x4112028620110809),
|
| 531 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 532 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 533 |
-
B(0x920008920600040, 0x8053801004000028),
|
| 534 |
-
B(0x81140283208300, 0x10040C004200420),
|
| 535 |
-
B(0x103080022201, 0xC01000081312620),
|
| 536 |
-
B(0x2200221100008, 0x1000408104000A4),
|
| 537 |
-
B(0x4402088080042008, 0x210401501040340),
|
| 538 |
-
B(0x898400202170001, 0x80040404208000),
|
| 539 |
-
B(0x20080004051012, 0x5100048200081800),
|
| 540 |
-
B(0x2320020000401018, 0x108501021040210),
|
| 541 |
-
B(0x21080410A422021, 0x83040180008800),
|
| 542 |
-
B(0x44E8100000408224, 0x20010008040400),
|
| 543 |
-
B(0x1800240002810405, 0x23004820000020),
|
| 544 |
-
B(0x80A0100400110, 0x80104020100C4028),
|
| 545 |
-
B(0x1002050001222C0, 0x5100818004024020),
|
| 546 |
-
B(0x104000200040, 0xC010A09800102000),
|
| 547 |
-
B(0x1020003A058120, 0x450900809000302),
|
| 548 |
-
B(0x40040045008B1, 0x202800400383010),
|
| 549 |
-
B(0x4640200220034, 0x8800485420304000),
|
| 550 |
-
B(0x5001042100084288, 0x110820001240080A),
|
| 551 |
-
B(0x2002C04004010120, 0xA15008020880001),
|
| 552 |
-
B(0x2800004080C4190, 0x890808280020080),
|
| 553 |
-
B(0x40C0401000104000, 0x2020880008002580),
|
| 554 |
-
B(0x40020C002400802, 0x801104010000000),
|
| 555 |
-
B(0x44842000040080, 0x2050011084000400),
|
| 556 |
-
B(0x4110040800000401, 0x2023810029008000),
|
| 557 |
-
B(0x20884000840, 0x8017102004008000),
|
| 558 |
-
B(0x10411104000480, 0x1414042000201001),
|
| 559 |
-
B(0x220040000008, 0x800306021000000),
|
| 560 |
-
B(0x41400A0008080, 0x501000298ACAD10),
|
| 561 |
-
B(0x800240012831810, 0x80120004468050E),
|
| 562 |
-
B(0x800005020801008, 0x20102400240000),
|
| 563 |
-
B(0x20C00040C114C010, 0x88080820200C00),
|
| 564 |
-
B(0x1044010100820081, 0x20080841004000),
|
| 565 |
-
B(0x8041048400022, 0x8020836040005002),
|
| 566 |
-
B(0x2001004010205, 0x8001002884042009),
|
| 567 |
-
B(0x128088400087, 0x20008002201002),
|
| 568 |
-
B(0x8084108040402000, 0x80809000A080400),
|
| 569 |
-
B(0x408081840880, 0x201002088000040),
|
| 570 |
-
B(0xA40180010280, 0x241004006000010),
|
| 571 |
-
B(0x4204100080048140, 0x2002C4F104202020),
|
| 572 |
-
B(0x100140A10204, 0x980200800840060),
|
| 573 |
-
B(0x1005140010202048, 0x1442280800202815),
|
| 574 |
-
B(0x2000082025008600, 0x1108400040600003),
|
| 575 |
-
B(0x1005050648000, 0x200020240008002),
|
| 576 |
-
B(0x202010208044000, 0x8210404060008),
|
| 577 |
-
B(0x8011040402000210, 0xC840180408016004),
|
| 578 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 579 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 580 |
-
B(0x80101002180140, 0x40C2080820000C0),
|
| 581 |
-
B(0x208202081260800, 0x14090E4C04000050),
|
| 582 |
-
B(0x4221201084004C2, 0x110480A011060),
|
| 583 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 584 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 585 |
-
B(0x200180C840088A0, 0x401100400820000),
|
| 586 |
-
B(0x10084043A021070, 0x202041600080200),
|
| 587 |
-
B(0x210E6202001040C, 0x10100800080B0),
|
| 588 |
-
B(0x848008021204002, 0x801004308100BAD),
|
| 589 |
-
B(0xC082C0390A000601, 0x4040080189008),
|
| 590 |
-
B(0x431200240210402D, 0x58102820000),
|
| 591 |
-
B(0x202020100A0019B0, 0x4010C0D018000000),
|
| 592 |
-
B(0x800800908402203, 0x102948C84C184),
|
| 593 |
-
B(0x26801100080845, 0x4009702022A00820),
|
| 594 |
-
B(0x8880520010401040, 0x1060084832052000),
|
| 595 |
-
B(0x100100022042081, 0x10000600008C121),
|
| 596 |
-
B(0x46020384100040, 0x800200320882021),
|
| 597 |
-
B(0xC0002010148, 0x4200800800040003),
|
| 598 |
-
B(0x2002208020090040, 0x40820210021410),
|
| 599 |
-
B(0x9000A41160002004, 0x2A09000100080043),
|
| 600 |
-
B(0x800004010008001, 0x1108002020104600),
|
| 601 |
-
B(0x800540C000A4E041, 0x18021180000401),
|
| 602 |
-
B(0x808200900A900202, 0x8364202140012005),
|
| 603 |
-
B(0x1DBA52000081010, 0x4008000023000010),
|
| 604 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 605 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 606 |
-
B(0x4101100020400482, 0x2000402302100120),
|
| 607 |
-
B(0x100408000A020212, 0xA000400111000020),
|
| 608 |
-
B(0x2000010488080104, 0x3000404410208100),
|
| 609 |
-
B(0x2684220180008DD0, 0x422040200004000A),
|
| 610 |
-
B(0x2021200C0424, 0x1010100000080200),
|
| 611 |
-
B(0x8908020020801006, 0x3010800020C2000),
|
| 612 |
-
B(0x4000030008062044, 0x244010202688000),
|
| 613 |
-
B(0x242101200408009, 0x8150040000200015),
|
| 614 |
-
B(0x42004C02180204, 0x210208014241040),
|
| 615 |
-
B(0x4E1A01C208410804, 0x8890041000012004),
|
| 616 |
-
B(0x2080200401000080, 0x8001098429008004),
|
| 617 |
-
B(0xA01400121804104, 0x280200C400000500),
|
| 618 |
-
B(0xD0080408040420, 0x1006040100224000),
|
| 619 |
-
B(0x28400205000800C9, 0x6021101401040075),
|
| 620 |
-
B(0x4000900040020104, 0x88129801100D0C),
|
| 621 |
-
B(0x8000004002180410, 0x400380200400204),
|
| 622 |
-
B(0x4002A430043008, 0x400200340100020),
|
| 623 |
-
B(0x401960004140A42, 0x100880710000464),
|
| 624 |
-
B(0x58014090102, 0xB8D30004010080),
|
| 625 |
-
B(0xA004C08000244000, 0x11280100E0000040),
|
| 626 |
-
B(0x2102008089208804, 0x110001004080040),
|
| 627 |
-
B(0x700010084E003004, 0x8080864112000D40),
|
| 628 |
-
B(0x4080881000200C20, 0x30324040880E0600),
|
| 629 |
-
B(0x2024A40401810820, 0x3000888002000000),
|
| 630 |
-
B(0x8200100400014, 0x4400340800252844),
|
| 631 |
-
B(0x24A00804288281, 0x410103002201140),
|
| 632 |
-
B(0x4080005022A08, 0x1000402200100264),
|
| 633 |
-
B(0x200080032244040, 0x200502189010001),
|
| 634 |
-
B(0x28108110404001, 0x400600120008412),
|
| 635 |
-
B(0xA00002102810020, 0xB1080240015408),
|
| 636 |
-
B(0x810080200806, 0x410440804080046),
|
| 637 |
-
};
|
| 638 |
-
constexpr Bitboard LameDabbabaMagicInit[SQUARE_NB] = {
|
| 639 |
-
B(0x3C080482A592000C, 0x540104000020000),
|
| 640 |
-
B(0x2802C40008000420, 0x4A00000001818009),
|
| 641 |
-
B(0x1083040280804000, 0x120004C20100880),
|
| 642 |
-
B(0x6840940880000892, 0x2014A01080800C2),
|
| 643 |
-
B(0x8401489004000180, 0x2000800000400000),
|
| 644 |
-
B(0x820161C800000110, 0x8000100000204020),
|
| 645 |
-
B(0x610011A122000109, 0x1000004020008004),
|
| 646 |
-
B(0x83282004023000, 0xE000020004848446),
|
| 647 |
-
B(0x6840940880000892, 0x2014A01080800C2),
|
| 648 |
-
B(0x4020120800800002, 0x88008000010020),
|
| 649 |
-
B(0x30025B140A1000, 0x3141801401000040),
|
| 650 |
-
B(0x41104D1810100050, 0x8141002010910),
|
| 651 |
-
B(0x4200828A298400, 0x400340001040C000),
|
| 652 |
-
B(0x8016A4900110040, 0x844812001068020),
|
| 653 |
-
B(0x2250035820400A2, 0x8012010080900),
|
| 654 |
-
B(0x820080083A009000, 0x880404091080110),
|
| 655 |
-
B(0x80401500AF0020, 0x240000082201A04),
|
| 656 |
-
B(0x668020020C081005, 0x4008001004100021),
|
| 657 |
-
B(0x240100910000000, 0x82000A0030454000),
|
| 658 |
-
B(0xA24091400008, 0x200014880004A921),
|
| 659 |
-
B(0x840110042200410, 0x100080000A400000),
|
| 660 |
-
B(0x40024024102000, 0x1000000002180404),
|
| 661 |
-
B(0x92828423000530, 0x118800020110),
|
| 662 |
-
B(0x1122404A1C90A8, 0x822040280020D00),
|
| 663 |
-
B(0x41201A40900A000, 0x80C0480040605100),
|
| 664 |
-
B(0x2504A85005488280, 0x3028112120022800),
|
| 665 |
-
B(0x210180080626B048, 0x8000401000014000),
|
| 666 |
-
B(0x1000410401040200, 0x41014000050C0106),
|
| 667 |
-
B(0x1040650210802200, 0x80C0041000000),
|
| 668 |
-
B(0x4020C10110900002, 0x2140C2001050009),
|
| 669 |
-
B(0x191180092200022, 0x6010008400400800),
|
| 670 |
-
B(0x8010821088080202, 0xCA240011008208),
|
| 671 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 672 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 673 |
-
B(0x22080C8A0161401, 0x200C10004C002002),
|
| 674 |
-
B(0x8430818023034080, 0x210090800000801),
|
| 675 |
-
B(0x4845087008200, 0x40661480000),
|
| 676 |
-
B(0x1202804428812050, 0x100022038020000),
|
| 677 |
-
B(0x400016001201080, 0x24002200402060),
|
| 678 |
-
B(0x680E041300800800, 0xE00130080004000),
|
| 679 |
-
B(0x3409080200, 0x282840210000000),
|
| 680 |
-
B(0x803310108400, 0x85200000080100A0),
|
| 681 |
-
B(0xE180008A04162104, 0x9088240412404),
|
| 682 |
-
B(0x20080100920020, 0x2002248010242052),
|
| 683 |
-
B(0x8A000400C2410, 0x1000024086014300),
|
| 684 |
-
B(0x1821040024663, 0x100000100010009),
|
| 685 |
-
B(0x4000822310611, 0x120280406014008),
|
| 686 |
-
B(0x1004008010818D08, 0x800000141892000),
|
| 687 |
-
B(0x8010800004024042, 0x44B106008800896),
|
| 688 |
-
B(0xA0063423444, 0x41002C15811008),
|
| 689 |
-
B(0x2040012381001282, 0x4804080104A4000),
|
| 690 |
-
B(0x10840101820880, 0xA800008000020020),
|
| 691 |
-
B(0x10840101820880, 0xA800008000020020),
|
| 692 |
-
B(0x60201D8300408190, 0x2010020920200000),
|
| 693 |
-
B(0x4048100200090090, 0x2008090100000900),
|
| 694 |
-
B(0x24200000280210, 0xD440050008004000),
|
| 695 |
-
B(0x1280001000580020, 0x2200040089000A4),
|
| 696 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 697 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 698 |
-
B(0x4108000010209089, 0x913000000024840),
|
| 699 |
-
B(0x410C208008008E02, 0xE8000000000001),
|
| 700 |
-
B(0x802208004005, 0x94206000022080),
|
| 701 |
-
B(0xC00290018902002, 0x4204100000000000),
|
| 702 |
-
B(0x2102801400093816, 0x9810004001000202),
|
| 703 |
-
B(0x8008304000015800, 0x4A5C000000020000),
|
| 704 |
-
B(0x1020108380800514, 0x1144210000000080),
|
| 705 |
-
B(0xC0001000008090, 0x2812060000204000),
|
| 706 |
-
B(0x1001100200003100, 0x246240060A004004),
|
| 707 |
-
B(0xA00020A008002030, 0x2440C40000110B00),
|
| 708 |
-
B(0x80502104000C008, 0x8222200042100010),
|
| 709 |
-
B(0xC020200088014, 0x422094000000480),
|
| 710 |
-
B(0x1029002000001030, 0x8105841120000210),
|
| 711 |
-
B(0x49040D, 0x2310808A14042C0),
|
| 712 |
-
B(0x200040200080A02C, 0xB890290400080000),
|
| 713 |
-
B(0x2240180C0800002, 0x4151050280000100),
|
| 714 |
-
B(0x2240180C0800002, 0x4151050280000100),
|
| 715 |
-
B(0x8220224180420006, 0x4024501212011000),
|
| 716 |
-
B(0x1806810A0881000, 0x802002048400080),
|
| 717 |
-
B(0x400400A080842, 0x9305000401180000),
|
| 718 |
-
B(0x10008001444110, 0x4420401040041833),
|
| 719 |
-
B(0x2000002C02010E00, 0x400408D08009804),
|
| 720 |
-
B(0x69D008200020100, 0x100842240049021),
|
| 721 |
-
B(0x42C24450020000, 0xD38400880090884),
|
| 722 |
-
B(0x485800800100001, 0x2484086522018840),
|
| 723 |
-
B(0x900200020820042, 0x22302421400040C0),
|
| 724 |
-
B(0x50B0413001818000, 0x452014040800C40),
|
| 725 |
-
B(0x8004040021008, 0x20088A08000290),
|
| 726 |
-
B(0x600C000801000004, 0x8015084010200020),
|
| 727 |
-
B(0x208000C00, 0xE004804021100100),
|
| 728 |
-
B(0x20001000040204, 0x948110C0B2081),
|
| 729 |
-
B(0x268502400100021, 0x80A201840802080),
|
| 730 |
-
B(0x408C000008, 0x8822102408014),
|
| 731 |
-
B(0x1182080410100000, 0x608002046A0100),
|
| 732 |
-
B(0x100820A083C00002, 0x3100100410A00),
|
| 733 |
-
B(0x8401040000400124, 0x2000081288202200),
|
| 734 |
-
B(0xB014040003000800, 0x11960D1101210),
|
| 735 |
-
B(0x10040001900C000, 0x85603C1001280),
|
| 736 |
-
B(0x2000844000000100, 0x2000024C60800800),
|
| 737 |
-
B(0x120004234800900, 0x210010841040),
|
| 738 |
-
B(0x8010300040000002, 0x4200008222104100),
|
| 739 |
-
B(0x1000120402200100, 0x209080CC040108B4),
|
| 740 |
-
B(0x110049A00000800, 0x80000420022180A8),
|
| 741 |
-
B(0x80001C00080384, 0x1400101111081001),
|
| 742 |
-
B(0x8011200008100428, 0x2020000880800922),
|
| 743 |
-
B(0x10001000000204C8, 0x280C11104240),
|
| 744 |
-
B(0x50100C82C000500, 0x28000280618DD1),
|
| 745 |
-
B(0x8800498020000, 0x20500A0200320128),
|
| 746 |
-
B(0x20010104000860, 0x8021720186008),
|
| 747 |
-
B(0x4000000000100080, 0x35040084270C04),
|
| 748 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 749 |
-
B(0x10400000000000, 0x20080051100130C2),
|
| 750 |
-
B(0x10400000000000, 0x20080051100130C2),
|
| 751 |
-
B(0x2000002110202014, 0x121004004004681),
|
| 752 |
-
B(0x400202001006D40, 0x82240082202424),
|
| 753 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 754 |
-
B(0xC6000000D00804, 0x1050020C0081090C),
|
| 755 |
-
B(0x200080000000042, 0x10800661),
|
| 756 |
-
B(0x2000001011200200, 0x2A420000802A0222),
|
| 757 |
-
B(0x802020001202412, 0x2400404148426),
|
| 758 |
-
B(0x8000440801040002, 0x444002800010052A),
|
| 759 |
-
};
|
| 760 |
-
constexpr Bitboard HorseMagicInit[SQUARE_NB] = {
|
| 761 |
-
B(0x3C080482A592000C, 0x540104000020000),
|
| 762 |
-
B(0x2802C40008000420, 0x4A00000001818009),
|
| 763 |
-
B(0x1083040280804000, 0x120004C20100880),
|
| 764 |
-
B(0x6840940880000892, 0x2014A01080800C2),
|
| 765 |
-
B(0x8401489004000180, 0x2000800000400000),
|
| 766 |
-
B(0x820161C800000110, 0x8000100000204020),
|
| 767 |
-
B(0x610011A122000109, 0x1000004020008004),
|
| 768 |
-
B(0x83282004023000, 0xE000020004848446),
|
| 769 |
-
B(0x6840940880000892, 0x2014A01080800C2),
|
| 770 |
-
B(0x4020120800800002, 0x88008000010020),
|
| 771 |
-
B(0x30025B140A1000, 0x3141801401000040),
|
| 772 |
-
B(0x41104D1810100050, 0x8141002010910),
|
| 773 |
-
B(0x4200828A298400, 0x400340001040C000),
|
| 774 |
-
B(0x8016A4900110040, 0x844812001068020),
|
| 775 |
-
B(0x2250035820400A2, 0x8012010080900),
|
| 776 |
-
B(0x820080083A009000, 0x880404091080110),
|
| 777 |
-
B(0x80401500AF0020, 0x240000082201A04),
|
| 778 |
-
B(0x668020020C081005, 0x4008001004100021),
|
| 779 |
-
B(0x240100910000000, 0x82000A0030454000),
|
| 780 |
-
B(0xA24091400008, 0x200014880004A921),
|
| 781 |
-
B(0x840110042200410, 0x100080000A400000),
|
| 782 |
-
B(0x40024024102000, 0x1000000002180404),
|
| 783 |
-
B(0x92828423000530, 0x118800020110),
|
| 784 |
-
B(0x1122404A1C90A8, 0x822040280020D00),
|
| 785 |
-
B(0x41201A40900A000, 0x80C0480040605100),
|
| 786 |
-
B(0x2504A85005488280, 0x3028112120022800),
|
| 787 |
-
B(0x210180080626B048, 0x8000401000014000),
|
| 788 |
-
B(0x1000410401040200, 0x41014000050C0106),
|
| 789 |
-
B(0x1040650210802200, 0x80C0041000000),
|
| 790 |
-
B(0x4020C10110900002, 0x2140C2001050009),
|
| 791 |
-
B(0x191180092200022, 0x6010008400400800),
|
| 792 |
-
B(0x8010821088080202, 0xCA240011008208),
|
| 793 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 794 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 795 |
-
B(0x22080C8A0161401, 0x200C10004C002002),
|
| 796 |
-
B(0x8430818023034080, 0x210090800000801),
|
| 797 |
-
B(0x4845087008200, 0x40661480000),
|
| 798 |
-
B(0x1202804428812050, 0x100022038020000),
|
| 799 |
-
B(0x400016001201080, 0x24002200402060),
|
| 800 |
-
B(0x680E041300800800, 0xE00130080004000),
|
| 801 |
-
B(0x3409080200, 0x282840210000000),
|
| 802 |
-
B(0x803310108400, 0x85200000080100A0),
|
| 803 |
-
B(0xE180008A04162104, 0x9088240412404),
|
| 804 |
-
B(0x20080100920020, 0x2002248010242052),
|
| 805 |
-
B(0x8A000400C2410, 0x1000024086014300),
|
| 806 |
-
B(0x1821040024663, 0x100000100010009),
|
| 807 |
-
B(0x4000822310611, 0x120280406014008),
|
| 808 |
-
B(0x1004008010818D08, 0x800000141892000),
|
| 809 |
-
B(0x8010800004024042, 0x44B106008800896),
|
| 810 |
-
B(0xA0063423444, 0x41002C15811008),
|
| 811 |
-
B(0x2040012381001282, 0x4804080104A4000),
|
| 812 |
-
B(0x10840101820880, 0xA800008000020020),
|
| 813 |
-
B(0x10840101820880, 0xA800008000020020),
|
| 814 |
-
B(0x60201D8300408190, 0x2010020920200000),
|
| 815 |
-
B(0x4048100200090090, 0x2008090100000900),
|
| 816 |
-
B(0x24200000280210, 0xD440050008004000),
|
| 817 |
-
B(0x1280001000580020, 0x2200040089000A4),
|
| 818 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 819 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 820 |
-
B(0x4108000010209089, 0x913000000024840),
|
| 821 |
-
B(0x410C208008008E02, 0xE8000000000001),
|
| 822 |
-
B(0x802208004005, 0x94206000022080),
|
| 823 |
-
B(0xC00290018902002, 0x4204100000000000),
|
| 824 |
-
B(0x2102801400093816, 0x9810004001000202),
|
| 825 |
-
B(0x8008304000015800, 0x4A5C000000020000),
|
| 826 |
-
B(0x1020108380800514, 0x1144210000000080),
|
| 827 |
-
B(0xC0001000008090, 0x2812060000204000),
|
| 828 |
-
B(0x1001100200003100, 0x246240060A004004),
|
| 829 |
-
B(0xA00020A008002030, 0x2440C40000110B00),
|
| 830 |
-
B(0x80502104000C008, 0x8222200042100010),
|
| 831 |
-
B(0xC020200088014, 0x422094000000480),
|
| 832 |
-
B(0x1029002000001030, 0x8105841120000210),
|
| 833 |
-
B(0x49040D, 0x2310808A14042C0),
|
| 834 |
-
B(0x200040200080A02C, 0xB890290400080000),
|
| 835 |
-
B(0x2240180C0800002, 0x4151050280000100),
|
| 836 |
-
B(0x2240180C0800002, 0x4151050280000100),
|
| 837 |
-
B(0x8220224180420006, 0x4024501212011000),
|
| 838 |
-
B(0x1806810A0881000, 0x802002048400080),
|
| 839 |
-
B(0x400400A080842, 0x9305000401180000),
|
| 840 |
-
B(0x10008001444110, 0x4420401040041833),
|
| 841 |
-
B(0x2000002C02010E00, 0x400408D08009804),
|
| 842 |
-
B(0x69D008200020100, 0x100842240049021),
|
| 843 |
-
B(0x42C24450020000, 0xD38400880090884),
|
| 844 |
-
B(0x485800800100001, 0x2484086522018840),
|
| 845 |
-
B(0x900200020820042, 0x22302421400040C0),
|
| 846 |
-
B(0x50B0413001818000, 0x452014040800C40),
|
| 847 |
-
B(0x8004040021008, 0x20088A08000290),
|
| 848 |
-
B(0x600C000801000004, 0x8015084010200020),
|
| 849 |
-
B(0x208000C00, 0xE004804021100100),
|
| 850 |
-
B(0x20001000040204, 0x948110C0B2081),
|
| 851 |
-
B(0x268502400100021, 0x80A201840802080),
|
| 852 |
-
B(0x408C000008, 0x8822102408014),
|
| 853 |
-
B(0x1182080410100000, 0x608002046A0100),
|
| 854 |
-
B(0x100820A083C00002, 0x3100100410A00),
|
| 855 |
-
B(0x8401040000400124, 0x2000081288202200),
|
| 856 |
-
B(0xB014040003000800, 0x11960D1101210),
|
| 857 |
-
B(0x10040001900C000, 0x85603C1001280),
|
| 858 |
-
B(0x2000844000000100, 0x2000024C60800800),
|
| 859 |
-
B(0x120004234800900, 0x210010841040),
|
| 860 |
-
B(0x8010300040000002, 0x4200008222104100),
|
| 861 |
-
B(0x1000120402200100, 0x209080CC040108B4),
|
| 862 |
-
B(0x110049A00000800, 0x80000420022180A8),
|
| 863 |
-
B(0x80001C00080384, 0x1400101111081001),
|
| 864 |
-
B(0x8011200008100428, 0x2020000880800922),
|
| 865 |
-
B(0x10001000000204C8, 0x280C11104240),
|
| 866 |
-
B(0x50100C82C000500, 0x28000280618DD1),
|
| 867 |
-
B(0x8800498020000, 0x20500A0200320128),
|
| 868 |
-
B(0x20010104000860, 0x8021720186008),
|
| 869 |
-
B(0x4000000000100080, 0x35040084270C04),
|
| 870 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 871 |
-
B(0x10400000000000, 0x20080051100130C2),
|
| 872 |
-
B(0x10400000000000, 0x20080051100130C2),
|
| 873 |
-
B(0x2000002110202014, 0x121004004004681),
|
| 874 |
-
B(0x400202001006D40, 0x82240082202424),
|
| 875 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 876 |
-
B(0xC6000000D00804, 0x1050020C0081090C),
|
| 877 |
-
B(0x200080000000042, 0x10800661),
|
| 878 |
-
B(0x2000001011200200, 0x2A420000802A0222),
|
| 879 |
-
B(0x802020001202412, 0x2400404148426),
|
| 880 |
-
B(0x8000440801040002, 0x444002800010052A),
|
| 881 |
-
};
|
| 882 |
-
constexpr Bitboard ElephantMagicInit[SQUARE_NB] = {
|
| 883 |
-
B(0x64D2990200008, 0x4401880001C000),
|
| 884 |
-
B(0x29BAA00010020, 0x200000400800600),
|
| 885 |
-
B(0x3024240000000, 0x4100400010080),
|
| 886 |
-
B(0xA490A00480020, 0x20084001041010A4),
|
| 887 |
-
B(0x328C021008042, 0x100000000C10204),
|
| 888 |
-
B(0x1964090001018, 0x7002040148001205),
|
| 889 |
-
B(0x800302098404080, 0x4983020000000001),
|
| 890 |
-
B(0x8812244630A02080, 0x8200006204003C08),
|
| 891 |
-
B(0x41120231008000, 0x240441401020),
|
| 892 |
-
B(0x840091030C00040, 0x1400008200023400),
|
| 893 |
-
B(0x8001040E77030200, 0x100040090022000),
|
| 894 |
-
B(0x602022139D835040, 0x101002010025900),
|
| 895 |
-
B(0x405707C48400, 0x40010000008001),
|
| 896 |
-
B(0x982003456A82050, 0x60800820040030),
|
| 897 |
-
B(0x204184849200088, 0x101800004006),
|
| 898 |
-
B(0x300222470949200, 0x2A0800200200800),
|
| 899 |
-
B(0x400001211914000, 0x8200001407001),
|
| 900 |
-
B(0x2000008614831020, 0x4000020001404000),
|
| 901 |
-
B(0x84000024A2048048, 0x1200102000042),
|
| 902 |
-
B(0x424010A58422008, 0x88440242212A0110),
|
| 903 |
-
B(0x20020812C0C4408, 0x4121400000080010),
|
| 904 |
-
B(0x680200062042420, 0x2001100000800000),
|
| 905 |
-
B(0x200010060AEC855, 0x8083002040200000),
|
| 906 |
-
B(0x4000008BAA85810, 0x82000805C0200A90),
|
| 907 |
-
B(0x81450B200A025400, 0x4400101050000040),
|
| 908 |
-
B(0x820A2241409010, 0x888420030000),
|
| 909 |
-
B(0x909203000028, 0xC000004C00200041),
|
| 910 |
-
B(0x8021400A84880240, 0x100180002010020),
|
| 911 |
-
B(0x8001A20061410000, 0x14008499A000000),
|
| 912 |
-
B(0x8201444800A00080, 0x402010040588120),
|
| 913 |
-
B(0x100C06280020, 0x60010104840130),
|
| 914 |
-
B(0x520040800080044, 0x8220000080001402),
|
| 915 |
-
B(0x102021410040202, 0x2004400410006000),
|
| 916 |
-
B(0x5401832090020400, 0x300010020001),
|
| 917 |
-
B(0x180003105A84C108, 0x1012008800081000),
|
| 918 |
-
B(0x480C10210026904, 0xA006000004200418),
|
| 919 |
-
B(0x48050820210843A6, 0x108001004000C00),
|
| 920 |
-
B(0x1030101182206324, 0x4401008921502002),
|
| 921 |
-
B(0x40281060800800, 0x406000201260022),
|
| 922 |
-
B(0xC29002440040C820, 0x400001002008020),
|
| 923 |
-
B(0x40000400800241, 0xC220000000400280),
|
| 924 |
-
B(0x40880126014208, 0x2A8004C008940000),
|
| 925 |
-
B(0x121028100114080, 0x5010280481100082),
|
| 926 |
-
B(0x4000088280442, 0x908420140008041),
|
| 927 |
-
B(0x808C42400C0020, 0x3028100840801000),
|
| 928 |
-
B(0x4000000410078488, 0x501000000620000),
|
| 929 |
-
B(0x90080001421020A4, 0x4118400101060406),
|
| 930 |
-
B(0x280420004855, 0xD200100400820000),
|
| 931 |
-
B(0xA0063423444, 0x41002C15811008),
|
| 932 |
-
B(0x200061201808102, 0x4286969000200002),
|
| 933 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 934 |
-
B(0x4001A04880402000, 0x8100824080000001),
|
| 935 |
-
B(0x60201D8300408190, 0x2010020920200000),
|
| 936 |
-
B(0x20018C04908019, 0x2010884002002040),
|
| 937 |
-
B(0x800000000C40810, 0x680100081150000D),
|
| 938 |
-
B(0x2002002000040040, 0x8810049000010600),
|
| 939 |
-
B(0x41618A0300040040, 0x21200200A421801),
|
| 940 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 941 |
-
B(0x10208018C1020A20, 0x84C0432240610014),
|
| 942 |
-
B(0x5A04001400412854, 0x8A44006000010002),
|
| 943 |
-
B(0x13000C0810072432, 0x50049001021104),
|
| 944 |
-
B(0x400048801142130, 0x4C1204100226010C),
|
| 945 |
-
B(0x80001048, 0x408800104000080),
|
| 946 |
-
B(0x8104868204040412, 0x22244202000081),
|
| 947 |
-
B(0x8104868204040412, 0x22244202000081),
|
| 948 |
-
B(0x4140001000240440, 0x80209004410004E),
|
| 949 |
-
B(0x800800000100, 0xB111820100000002),
|
| 950 |
-
B(0x404240004220, 0x2110402802050080),
|
| 951 |
-
B(0x284010400004040, 0x100245002502020),
|
| 952 |
-
B(0x14880A100114010, 0x400208080010024),
|
| 953 |
-
B(0x4100004040440648, 0x10030D838041A80),
|
| 954 |
-
B(0x32004000210, 0x4010225C88014000),
|
| 955 |
-
B(0x2240180C0800002, 0x4151050280000100),
|
| 956 |
-
B(0x2010A12002000042, 0x189051442010000),
|
| 957 |
-
B(0x4060050080121883, 0x8250C10001000141),
|
| 958 |
-
B(0x10000000044100, 0x8401084010261009),
|
| 959 |
-
B(0xA00028040000, 0x2003224000002000),
|
| 960 |
-
B(0x2060009001000020, 0x1000432022020228),
|
| 961 |
-
B(0x404200000883080, 0x1080800848245000),
|
| 962 |
-
B(0x240000402080, 0xCA0820814210502),
|
| 963 |
-
B(0x200040200080A02C, 0xB890290400080000),
|
| 964 |
-
B(0x800000000300482, 0x9203008100100013),
|
| 965 |
-
B(0x8000210202042000, 0x22642104004C2400),
|
| 966 |
-
B(0x1040400805000401, 0x2A0300102C80010),
|
| 967 |
-
B(0x8010A01088020000, 0x122106105A06A030),
|
| 968 |
-
B(0x8000C00001010494, 0x130A1A20404120),
|
| 969 |
-
B(0x4B084010844290, 0x10A08008900840),
|
| 970 |
-
B(0x1180001802460000, 0xB08000034C82004),
|
| 971 |
-
B(0x4001880060028029, 0x204040002401000),
|
| 972 |
-
B(0x8021A0001308002A, 0x97001822040040),
|
| 973 |
-
B(0xC00000009A020AC1, 0x1000080900400),
|
| 974 |
-
B(0x60010110001990, 0x4000880900400000),
|
| 975 |
-
B(0x10290402401200, 0x230080402C08),
|
| 976 |
-
B(0x4220000219012000, 0x140204804100008),
|
| 977 |
-
B(0x1400200100002, 0x8E62200414128),
|
| 978 |
-
B(0x402808502004403, 0x20049100C0284520),
|
| 979 |
-
B(0xB30041004280280, 0x10020464DB200308),
|
| 980 |
-
B(0x440010800808, 0xA0102E295812100),
|
| 981 |
-
B(0x10008000B000, 0x2000058583220200),
|
| 982 |
-
B(0x2000844000000100, 0x2000024C60800800),
|
| 983 |
-
B(0x110000400100028, 0x24052304508004),
|
| 984 |
-
B(0x8458000000840004, 0x118006463400001),
|
| 985 |
-
B(0x804008000040050, 0x41044890228000),
|
| 986 |
-
B(0x20000050000400, 0x80A101824A00086),
|
| 987 |
-
B(0x600080404000020, 0x100007322480005),
|
| 988 |
-
B(0xD082200020020008, 0x642000630120001),
|
| 989 |
-
B(0x10000100040230, 0x8048114733320002),
|
| 990 |
-
B(0x20200442002A880A, 0x8200002CB4B8052),
|
| 991 |
-
B(0x290080000000, 0xA41297838F40D),
|
| 992 |
-
B(0x800205000080, 0xF221232039874400),
|
| 993 |
-
B(0x1444002004880C20, 0xC4100049144200),
|
| 994 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 995 |
-
B(0x281240881008, 0x204084004C101900),
|
| 996 |
-
B(0x1444002004880C20, 0xC4100049144200),
|
| 997 |
-
B(0x4500080000800, 0x280100002482C842),
|
| 998 |
-
B(0xC0010928430540, 0x92041902180),
|
| 999 |
-
B(0x1051001208A, 0x4900064800C20640),
|
| 1000 |
-
B(0x882020418C00000, 0x30004040092A821),
|
| 1001 |
-
B(0x224404002004268C, 0x202500204C7D254),
|
| 1002 |
-
B(0x290080000000, 0xA41297838F40D),
|
| 1003 |
-
};
|
| 1004 |
-
constexpr Bitboard JanggiElephantMagicInit[SQUARE_NB] = {
|
| 1005 |
-
B(0xC502282200061400, 0x2D07081241D90200),
|
| 1006 |
-
B(0xC502282200061400, 0x2D07081241D90200),
|
| 1007 |
-
B(0x8084810022440C2, 0x81402202004),
|
| 1008 |
-
B(0x80204010A800500, 0x5000021001740218),
|
| 1009 |
-
B(0x8048100401208000, 0x2001000390000044),
|
| 1010 |
-
B(0x202080020000000, 0x4010800010090424),
|
| 1011 |
-
B(0x4081A0480073200, 0x100000A010406000),
|
| 1012 |
-
B(0x4081A0480073200, 0x100000A010406000),
|
| 1013 |
-
B(0x2040450004000C40, 0x8400000006302),
|
| 1014 |
-
B(0x84010410018201, 0xA00A00000100000),
|
| 1015 |
-
B(0x840091030C00040, 0x1400008200023400),
|
| 1016 |
-
B(0x801058C0A0022, 0xC1920480010034),
|
| 1017 |
-
B(0x80B4004800840800, 0x4080210A42040010),
|
| 1018 |
-
B(0x400402221000445, 0x80321200408040),
|
| 1019 |
-
B(0x4028142401012A00, 0x4005009000104448),
|
| 1020 |
-
B(0x1440102040800220, 0x82800010A082000),
|
| 1021 |
-
B(0x4100040300C00200, 0x800805100120000),
|
| 1022 |
-
B(0x8200080061100, 0x2000101400000),
|
| 1023 |
-
B(0x2000100410070001, 0x40818200B0900410),
|
| 1024 |
-
B(0x400088020080000, 0x4A000402000CA0),
|
| 1025 |
-
B(0x1402040410004000, 0x9840044504040),
|
| 1026 |
-
B(0x20800088A00A0400, 0x1000020100180),
|
| 1027 |
-
B(0x2001820520308201, 0x2008003404349000),
|
| 1028 |
-
B(0x4004808022100, 0x8001000008081080),
|
| 1029 |
-
B(0x102041041100425, 0x840400180B100104),
|
| 1030 |
-
B(0x8806446000800214, 0x404402100010000),
|
| 1031 |
-
B(0x8200141409C04101, 0x209030004A00D00),
|
| 1032 |
-
B(0x8806004800880080, 0x1560004201000A01),
|
| 1033 |
-
B(0x4200050600200090, 0x1CD0000000000421),
|
| 1034 |
-
B(0x4820100022408100, 0x101404080320),
|
| 1035 |
-
B(0x2A000A0A08080080, 0x1C02808000C2C0),
|
| 1036 |
-
B(0x8808425040040014, 0x2021000100020),
|
| 1037 |
-
B(0x5282104044A0020, 0x6B402104200008),
|
| 1038 |
-
B(0x4001091040068120, 0x202000004003031),
|
| 1039 |
-
B(0x4001091040068120, 0x202000004003031),
|
| 1040 |
-
B(0x98040200A0214344, 0xA00300840010),
|
| 1041 |
-
B(0x82508040A40808A, 0x40010000110042),
|
| 1042 |
-
B(0x4400100101023, 0x450C8480040022),
|
| 1043 |
-
B(0x210588880010800, 0x800A000108018102),
|
| 1044 |
-
B(0x9400010144400, 0xC00010100018000),
|
| 1045 |
-
B(0x20A0400100040004, 0x1242000101002040),
|
| 1046 |
-
B(0x8022900040001001, 0x100000014000260),
|
| 1047 |
-
B(0x51004124000A080, 0x40098400000002),
|
| 1048 |
-
B(0x2158040001080022, 0x80009238401222),
|
| 1049 |
-
B(0xA0103A0000802220, 0x20000200400010),
|
| 1050 |
-
B(0x1101001208240, 0x100000800001064),
|
| 1051 |
-
B(0x821020002090081, 0x5840D0010290280),
|
| 1052 |
-
B(0x821020002090081, 0x5840D0010290280),
|
| 1053 |
-
B(0x10400C1042000400, 0x4005000000440200),
|
| 1054 |
-
B(0x844022008804820, 0x1000800100118000),
|
| 1055 |
-
B(0x10802A9800800139, 0x4802840100842200),
|
| 1056 |
-
B(0x4000A008200081, 0x4001100200402000),
|
| 1057 |
-
B(0x200000008108400, 0x1000C00008080020),
|
| 1058 |
-
B(0x120C11500100081, 0x440300308041100),
|
| 1059 |
-
B(0x8080040080060100, 0xC00101B0040028),
|
| 1060 |
-
B(0x901420A00110000, 0x8200010044700280),
|
| 1061 |
-
B(0x140080080410000, 0x808040000C001001),
|
| 1062 |
-
B(0x80210C0200A0008, 0x88088004600201),
|
| 1063 |
-
B(0x8000004202020301, 0x2100142104002000),
|
| 1064 |
-
B(0x1101011210004880, 0x8500840400000000),
|
| 1065 |
-
B(0x40208802004800, 0x8080806009011240),
|
| 1066 |
-
B(0x800000140408880, 0xC001018004060040),
|
| 1067 |
-
B(0xC008080420500, 0x8024A10000000000),
|
| 1068 |
-
B(0x2800000000400010, 0x44001C00400408),
|
| 1069 |
-
B(0xA804008001200408, 0x202000020001000),
|
| 1070 |
-
B(0xC08288805004080, 0x200042000800004),
|
| 1071 |
-
B(0xA40A01000080012, 0x8800080042408),
|
| 1072 |
-
B(0x2200100000100810, 0x800200010000100),
|
| 1073 |
-
B(0x9881800004040001, 0x8058100100884004),
|
| 1074 |
-
B(0x820000044020014, 0x4AA00010245012),
|
| 1075 |
-
B(0x820000044020014, 0x4AA00010245012),
|
| 1076 |
-
B(0x4000080240000808, 0x10100022054000),
|
| 1077 |
-
B(0x5002000840101, 0x202020004000A00),
|
| 1078 |
-
B(0x1188008200008402, 0x8088100020A2204),
|
| 1079 |
-
B(0x304012004044080, 0x8028108818006010),
|
| 1080 |
-
B(0x102210000008400, 0x1008000200380002),
|
| 1081 |
-
B(0x51410E114200, 0x100C00084000000),
|
| 1082 |
-
B(0x5001242320218, 0x800025000040040),
|
| 1083 |
-
B(0x4008000200008190, 0x400020021000000),
|
| 1084 |
-
B(0x10910022F0040, 0x450084400040001),
|
| 1085 |
-
B(0x180010810000040, 0x4004100040040),
|
| 1086 |
-
B(0x1088801424062010, 0x400084010030401),
|
| 1087 |
-
B(0x3000120408000040, 0x10802001080A4051),
|
| 1088 |
-
B(0x200008420, 0x40C0100020008804),
|
| 1089 |
-
B(0x1048C000004000, 0x4220120804004000),
|
| 1090 |
-
B(0x404A180000000E, 0x4C30412008110102),
|
| 1091 |
-
B(0x400000404202005, 0x800808550EC40044),
|
| 1092 |
-
B(0x282000200212010, 0x8001C0C102000210),
|
| 1093 |
-
B(0x9012240000008100, 0x280CA04010040000),
|
| 1094 |
-
B(0x2000C04001020C00, 0x2002010101042000),
|
| 1095 |
-
B(0x1010000204408408, 0x8008004800E0C4A),
|
| 1096 |
-
B(0x800286801000025, 0x8402401040050088),
|
| 1097 |
-
B(0x40002000A0880000, 0x8400300108082086),
|
| 1098 |
-
B(0x2080004404011, 0x20C080400100001),
|
| 1099 |
-
B(0xB0010218100800, 0x8040200482C14103),
|
| 1100 |
-
B(0x8011035000000C20, 0x4200044043200040),
|
| 1101 |
-
B(0x804008000040050, 0x41044890228000),
|
| 1102 |
-
B(0x80000400A0020020, 0x5308022021000000),
|
| 1103 |
-
B(0x2118200000008004, 0x4141014004423D00),
|
| 1104 |
-
B(0x90C0000200008040, 0x41041062000082),
|
| 1105 |
-
B(0x1D000100941204, 0x12402001200420),
|
| 1106 |
-
B(0x8C0040400400065, 0x22300B408100000),
|
| 1107 |
-
B(0x8C0040400400065, 0x22300B408100000),
|
| 1108 |
-
B(0x802802044600000, 0x1210100401030082),
|
| 1109 |
-
B(0x9400488010000000, 0x8005404902040000),
|
| 1110 |
-
B(0x2214020200001, 0x40102100820200),
|
| 1111 |
-
B(0x2022000000800000, 0x6400440108480),
|
| 1112 |
-
B(0x110000400100028, 0x24052304508004),
|
| 1113 |
-
B(0x848820140010000, 0x201012500A000),
|
| 1114 |
-
B(0x848820140010000, 0x201012500A000),
|
| 1115 |
-
B(0x100100000000C4, 0x208004084048201),
|
| 1116 |
-
B(0x100500000000290, 0x10102818208000),
|
| 1117 |
-
B(0x2800414000C000, 0x20004005001301),
|
| 1118 |
-
B(0x698180005101241, 0x10002014800210),
|
| 1119 |
-
B(0x20000080000009, 0x440340C040),
|
| 1120 |
-
B(0x1C0220200290020, 0x42100004004011C0),
|
| 1121 |
-
B(0x200E620018320208, 0x440410402),
|
| 1122 |
-
B(0xD04101010004024, 0x20000121104010A4),
|
| 1123 |
-
B(0x220400000A80040, 0x806080020810010C),
|
| 1124 |
-
B(0xA000200000000080, 0x1040801A0081208),
|
| 1125 |
-
};
|
| 1126 |
-
constexpr Bitboard CannonDiagMagicInit[SQUARE_NB] = {
|
| 1127 |
-
B(0x811801000400, 0x312260280280202),
|
| 1128 |
-
B(0x44A000402022680, 0x1020224880420005),
|
| 1129 |
-
B(0x8000C80800200880, 0x2000810060080C0),
|
| 1130 |
-
B(0x2010300240428040, 0x40240002C004E30),
|
| 1131 |
-
B(0x1018010404010004, 0x1001010018081E0),
|
| 1132 |
-
B(0x2042040010080090, 0x100000008410300),
|
| 1133 |
-
B(0x400080020102000, 0x4500005300000000),
|
| 1134 |
-
B(0x2D00C80420010200, 0x804003280020008),
|
| 1135 |
-
B(0x8038820024420, 0x6010010080012040),
|
| 1136 |
-
B(0x1202028004200088, 0x50018100004000C6),
|
| 1137 |
-
B(0xA02010F0410081, 0x20013001000009A),
|
| 1138 |
-
B(0x4013002041030588, 0x4802004110000004),
|
| 1139 |
-
B(0x110020802000081, 0x202001800908002),
|
| 1140 |
-
B(0x22010404103, 0x2020882080491200),
|
| 1141 |
-
B(0x60000220400580, 0x85902800100100),
|
| 1142 |
-
B(0x100080800050100, 0x200010220021088),
|
| 1143 |
-
B(0x8088840404200080, 0x140011040104000),
|
| 1144 |
-
B(0x4008508080082015, 0x8010100200580048),
|
| 1145 |
-
B(0x4010400420201001, 0x260002080A80808),
|
| 1146 |
-
B(0xC2002004A0008008, 0x8020082000110840),
|
| 1147 |
-
B(0xA000A0820042400, 0x810408082100420),
|
| 1148 |
-
B(0x80231808100004, 0x204002000800400),
|
| 1149 |
-
B(0x8296144044004900, 0x4A1003008001840),
|
| 1150 |
-
B(0x80A0020A0011008, 0x800104846080810),
|
| 1151 |
-
B(0x803800801041000, 0x1030500102000404),
|
| 1152 |
-
B(0x240C00900800850, 0x1804000108810000),
|
| 1153 |
-
B(0x800400000088800, 0x800021801020000),
|
| 1154 |
-
B(0x84800409300082, 0x1002D40680044000),
|
| 1155 |
-
B(0xA110C0000200010, 0x401010001200260),
|
| 1156 |
-
B(0x8200160204100004, 0x8040004004002022),
|
| 1157 |
-
B(0x10001000000100C0, 0x84002811000200),
|
| 1158 |
-
B(0x2000080020014001, 0x42002020000102),
|
| 1159 |
-
B(0x109040044020018, 0x2020400202001000),
|
| 1160 |
-
B(0x620000CD0108, 0x40040201008000),
|
| 1161 |
-
B(0xA1402200A0020, 0x81400400300912),
|
| 1162 |
-
B(0x20020CF100018020, 0x801A14086404000),
|
| 1163 |
-
B(0x800801844001, 0x11621488425000),
|
| 1164 |
-
B(0x10201004A8080, 0x100A000801000010),
|
| 1165 |
-
B(0x2800411001000800, 0x80224084900020),
|
| 1166 |
-
B(0x40400024028100, 0x501000400230060),
|
| 1167 |
-
B(0x404808010080, 0x1201000400100004),
|
| 1168 |
-
B(0x80802005200, 0x2000200008A0000),
|
| 1169 |
-
B(0x20800080000022, 0x80040810002010),
|
| 1170 |
-
B(0x40016004808240, 0x400114000801100),
|
| 1171 |
-
B(0x8410004204240, 0x20011000604050),
|
| 1172 |
-
B(0x8000C1009008268, 0x201004000209000),
|
| 1173 |
-
B(0x10240C000920, 0xE000A5C14003002),
|
| 1174 |
-
B(0x10184024280008, 0x90240802000000),
|
| 1175 |
-
B(0x40889081081000, 0x8010050008800000),
|
| 1176 |
-
B(0x100008C089000019, 0x802032014020010),
|
| 1177 |
-
B(0x401C1804C00, 0x402501002002020),
|
| 1178 |
-
B(0x200022000920D0, 0x8000800081300020),
|
| 1179 |
-
B(0x801000400011, 0x400100044010226),
|
| 1180 |
-
B(0x4A04010100100000, 0x500400080400000),
|
| 1181 |
-
B(0xA000050200080000, 0x8500090001010000),
|
| 1182 |
-
B(0x40400040001812, 0x4403000400100A0),
|
| 1183 |
-
B(0x20C2250203020004, 0x210001C000080000),
|
| 1184 |
-
B(0x21000408C6020001, 0x4200830012D1001),
|
| 1185 |
-
B(0x840082016080A210, 0x2400080801081008),
|
| 1186 |
-
B(0x40001020000, 0x4041240200083120),
|
| 1187 |
-
B(0x2C04030010C0818, 0xA670002000818100),
|
| 1188 |
-
B(0x4704A07085000510, 0x914001000040),
|
| 1189 |
-
B(0x900210304100100, 0x1010004000281840),
|
| 1190 |
-
B(0x8202920002002040, 0x810012000003),
|
| 1191 |
-
B(0x4001400100050, 0x1144000408002000),
|
| 1192 |
-
B(0x5900200020008100, 0x40200020002004),
|
| 1193 |
-
B(0x301020002000480, 0x202000C0004),
|
| 1194 |
-
B(0x20D000201104040, 0x34840100020010),
|
| 1195 |
-
B(0x800004200080408, 0x40184200100240),
|
| 1196 |
-
B(0x8430080100404020, 0x90042100244500),
|
| 1197 |
-
B(0x3800100010220062, 0x50404030200218),
|
| 1198 |
-
B(0x42E20008002020, 0x2000008200200300),
|
| 1199 |
-
B(0xE488008280A004, 0x200001010CC80000),
|
| 1200 |
-
B(0x6018010041109810, 0x800002000242041A),
|
| 1201 |
-
B(0x40A8002438980, 0x8000810008208009),
|
| 1202 |
-
B(0x401000480040100, 0x286800404002212),
|
| 1203 |
-
B(0x821030000100009, 0x2000090200A00000),
|
| 1204 |
-
B(0x20000100C0008028, 0x5000000100400082),
|
| 1205 |
-
B(0x80A000048030080, 0x200000120200008),
|
| 1206 |
-
B(0x6300280800204003, 0x48000105C0040100),
|
| 1207 |
-
B(0x83008802420C0200, 0x2008020200080100),
|
| 1208 |
-
B(0x1050C3102200042, 0x20103900010008),
|
| 1209 |
-
B(0x8040902021408180, 0x12000021806200A4),
|
| 1210 |
-
B(0x3008204008C10004, 0x680110100010401),
|
| 1211 |
-
B(0x204321100421000, 0x400E204820494000),
|
| 1212 |
-
B(0x8000044022404048, 0x4024010090024021),
|
| 1213 |
-
B(0x140201424050, 0x280A000130008000),
|
| 1214 |
-
B(0x900340808004002, 0x21026008000380),
|
| 1215 |
-
B(0x82808000300444, 0x20002000A2001141),
|
| 1216 |
-
B(0x140180100406002, 0x4004480001000004),
|
| 1217 |
-
B(0x4808420800841900, 0x14008C0041000000),
|
| 1218 |
-
B(0x2008600009000480, 0x9008020001400000),
|
| 1219 |
-
B(0x2000100800100002, 0x2004100820210020),
|
| 1220 |
-
B(0x2062010401A8100, 0x12200108420090),
|
| 1221 |
-
B(0x1403188200032, 0x40048166105000),
|
| 1222 |
-
B(0x410020020140041, 0x4400348102940040),
|
| 1223 |
-
B(0x414040209208041, 0x4402400028B004),
|
| 1224 |
-
B(0x8008010100421202, 0x401418002008800),
|
| 1225 |
-
B(0x4000020010062200, 0xA02009148048000),
|
| 1226 |
-
B(0x4443080082008B, 0x104014022801010),
|
| 1227 |
-
B(0x42B440A0C000800, 0x9001009016111020),
|
| 1228 |
-
B(0x400000214002, 0x8008080209020009),
|
| 1229 |
-
B(0x480C414A001900, 0x3400100400210200),
|
| 1230 |
-
B(0x1006008800604, 0x20240004030A050),
|
| 1231 |
-
B(0x4C022401002A8300, 0x405008400000600),
|
| 1232 |
-
B(0x3104000800A1042, 0x2004800204406200),
|
| 1233 |
-
B(0xA09010280008200C, 0x4004000208C4168),
|
| 1234 |
-
B(0x2800401120C20120, 0x4A00450200022030),
|
| 1235 |
-
B(0x88001800304C0200, 0x204288102080000),
|
| 1236 |
-
B(0x8044004201440101, 0x400820080C024022),
|
| 1237 |
-
B(0xA000100C080, 0x4B40341004008081),
|
| 1238 |
-
B(0x94802001300810, 0x140206008000800),
|
| 1239 |
-
B(0x40002020202820, 0x280680404000040),
|
| 1240 |
-
B(0xA820800004200, 0x80E1401012000491),
|
| 1241 |
-
B(0x804000010020C000, 0x9403020200802000),
|
| 1242 |
-
B(0x8C0001284201400, 0xC000100C01620800),
|
| 1243 |
-
B(0x4010004002200414, 0x403080080200000),
|
| 1244 |
-
B(0x140400A100800101, 0x10054C031080400),
|
| 1245 |
-
B(0x20012C2400880082, 0x7000880020C03200),
|
| 1246 |
-
B(0x204040300004, 0x840800041101002),
|
| 1247 |
-
};
|
| 1248 |
-
constexpr Bitboard NightriderMagicInit[SQUARE_NB] = {
|
| 1249 |
-
B(0x8008100800020052, 0x8001440000000000),
|
| 1250 |
-
B(0x24028400210090, 0x4200000000021),
|
| 1251 |
-
B(0x22002020A0200800, 0x100820120000082),
|
| 1252 |
-
B(0x424009020002200, 0x84810D4100002A),
|
| 1253 |
-
B(0x404008020000600, 0x1000202000000081),
|
| 1254 |
-
B(0x21020001000680, 0x2140200000000000),
|
| 1255 |
-
B(0x2060021100000608, 0x8080020040000C8),
|
| 1256 |
-
B(0x910C20408001200, 0x80A4030800000500),
|
| 1257 |
-
B(0x2C40100010400009, 0x40400000200000C),
|
| 1258 |
-
B(0x4090210034400004, 0x2104008000000),
|
| 1259 |
-
B(0x1082008040840180, 0x140082080000000F),
|
| 1260 |
-
B(0x8041001002101002, 0x8C002000000),
|
| 1261 |
-
B(0x102205086800080, 0x84400030020D600),
|
| 1262 |
-
B(0x2120080A32044E0, 0x400A02000016000),
|
| 1263 |
-
B(0x6040003021040A0, 0x8000200206040040),
|
| 1264 |
-
B(0x8001000008104082, 0x4002104202000114),
|
| 1265 |
-
B(0x100400081080000, 0x201020020000020),
|
| 1266 |
-
B(0x203000090010040, 0x140040010000000C),
|
| 1267 |
-
B(0x9140000108100040, 0x4004004C08450010),
|
| 1268 |
-
B(0x4402A12120020000, 0x450C002C000040C),
|
| 1269 |
-
B(0x2028000200120800, 0x100100401001000),
|
| 1270 |
-
B(0x800890081000, 0x10700A080180048),
|
| 1271 |
-
B(0x41040C4008400, 0x8080001000080020),
|
| 1272 |
-
B(0x2404000001060401, 0x10800116C0009110),
|
| 1273 |
-
B(0x2001810020400110, 0xA0100800000480E2),
|
| 1274 |
-
B(0x4081400120200218, 0x8800410800000000),
|
| 1275 |
-
B(0x4C020020300E00, 0x810800000000808),
|
| 1276 |
-
B(0xC8002200100108, 0x4860040380000100),
|
| 1277 |
-
B(0x8000E0000804080, 0x4C800000000000),
|
| 1278 |
-
B(0x211880010934041, 0x31000040000188),
|
| 1279 |
-
B(0x4800801000003140, 0x80000000028),
|
| 1280 |
-
B(0x61240410840004, 0x230100050000002),
|
| 1281 |
-
B(0x61240410840004, 0x230100050000002),
|
| 1282 |
-
B(0x4020008000C04C42, 0x3000021000000804),
|
| 1283 |
-
B(0x829808040040840, 0x288010000002200),
|
| 1284 |
-
B(0xA0420002040084, 0x1008604002000048),
|
| 1285 |
-
B(0x10200004980, 0x2010410028000000),
|
| 1286 |
-
B(0x4900200420100010, 0x1000A00401001898),
|
| 1287 |
-
B(0x20000801600134, 0xC0002400000021C),
|
| 1288 |
-
B(0x200040021010001, 0x8800000400000088),
|
| 1289 |
-
B(0x88000824, 0x8800000040010000),
|
| 1290 |
-
B(0x40000000200000D0, 0x8200004000AA84),
|
| 1291 |
-
B(0x1002000000812002, 0x4000001C1008480),
|
| 1292 |
-
B(0xC00010420003, 0x400002C00000004),
|
| 1293 |
-
B(0x208400008008040, 0x111004280000C0),
|
| 1294 |
-
B(0x60004000E800241, 0x202001000010040),
|
| 1295 |
-
B(0x200004800061, 0x1109100480045800),
|
| 1296 |
-
B(0x52880000200001, 0x608204100012DA0),
|
| 1297 |
-
B(0x1000429008100800, 0x2008001000006018),
|
| 1298 |
-
B(0x8490024200123001, 0x1041400080020),
|
| 1299 |
-
B(0x810001020200014, 0x2C50500220000020),
|
| 1300 |
-
B(0x20234B8000A0080, 0x4091200200000020),
|
| 1301 |
-
B(0x400401010012600, 0xE00200000000020),
|
| 1302 |
-
B(0x8040C00804004000, 0x8208014000000083),
|
| 1303 |
-
B(0x102000410001044, 0x8200000000000),
|
| 1304 |
-
B(0x102000410001044, 0x8200000000000),
|
| 1305 |
-
B(0x242E00508040001, 0x80028000000000),
|
| 1306 |
-
B(0x40810368002080, 0x4008080000224),
|
| 1307 |
-
B(0x48200010208800, 0x1020800C000022),
|
| 1308 |
-
B(0x220C4018008000, 0x282100130000211),
|
| 1309 |
-
B(0x8008004400100, 0xC128208200020400),
|
| 1310 |
-
B(0x44C004100020, 0x4008004000011000),
|
| 1311 |
-
B(0x1008000000600008, 0x41C00180480183),
|
| 1312 |
-
B(0x10080000, 0x404090018800020A),
|
| 1313 |
-
B(0x4500000000004200, 0x45200200A0140),
|
| 1314 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 1315 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 1316 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 1317 |
-
B(0x48000000020A0080, 0x1000020200088),
|
| 1318 |
-
B(0xA00000008404200, 0x4204010101001004),
|
| 1319 |
-
B(0x10008030082, 0x2002800200100104),
|
| 1320 |
-
B(0x44080002460010, 0x8007804100082D00),
|
| 1321 |
-
B(0x98400040001802, 0x913002002020301),
|
| 1322 |
-
B(0xA0400501040028, 0x8040481824002024),
|
| 1323 |
-
B(0x4C0A0600100080A0, 0x8005000080008200),
|
| 1324 |
-
B(0x802124000860008, 0x1009081800100080),
|
| 1325 |
-
B(0x4000110040011000, 0x4080422200001081),
|
| 1326 |
-
B(0x422008008000080, 0x4001020C00000202),
|
| 1327 |
-
B(0x8000202008002101, 0xA008010000040),
|
| 1328 |
-
B(0x804200020000020, 0xE0B0008010000001),
|
| 1329 |
-
B(0x14040200002, 0x2000000006000004),
|
| 1330 |
-
B(0x45000002010020, 0xA4040008400000),
|
| 1331 |
-
B(0x800040020204184A, 0x10000402000006),
|
| 1332 |
-
B(0x908000080400004, 0x5040100038400050),
|
| 1333 |
-
B(0x3100002000040014, 0x804008008120000),
|
| 1334 |
-
B(0x6002200000020008, 0xC011409081008881),
|
| 1335 |
-
B(0xC02004060280001, 0x2003004010220254),
|
| 1336 |
-
B(0x16410101, 0x100040108600000),
|
| 1337 |
-
B(0x100000000200000, 0x201200010800200),
|
| 1338 |
-
B(0xC400000004090002, 0x808808010224000A),
|
| 1339 |
-
B(0xC400000004090002, 0x808808010224000A),
|
| 1340 |
-
B(0x1000000000890001, 0x4050002001040),
|
| 1341 |
-
B(0x618000000008484, 0x40000A0150000D4),
|
| 1342 |
-
B(0x500000400009004, 0x1100200204100A1),
|
| 1343 |
-
B(0x6006000008080480, 0x100254800C00904),
|
| 1344 |
-
B(0x6006000008080480, 0x100254800C00904),
|
| 1345 |
-
B(0x404808040044040, 0x4202020040000200),
|
| 1346 |
-
B(0x2000080440810, 0x9044008844920000),
|
| 1347 |
-
B(0x40204418040, 0x412000204080010),
|
| 1348 |
-
B(0x88400820040248, 0x408040010C040800),
|
| 1349 |
-
B(0x8110084000803, 0x102000000000),
|
| 1350 |
-
B(0x4000040140001100, 0x80808102002),
|
| 1351 |
-
B(0x100480044020008, 0x4601000100084488),
|
| 1352 |
-
B(0x6200204420840, 0x41802043B0000),
|
| 1353 |
-
B(0x540000010091010, 0x409004800A01208),
|
| 1354 |
-
B(0x300040008000008, 0x2030080800010000),
|
| 1355 |
-
B(0x408804010400090, 0x4008100800004000),
|
| 1356 |
-
B(0x401600A0000080, 0x8400200201002200),
|
| 1357 |
-
B(0x44000000100000, 0x1140040210000001),
|
| 1358 |
-
B(0xC6000000D00804, 0x1050020C0081090C),
|
| 1359 |
-
B(0x4098002, 0x900000C045008300),
|
| 1360 |
-
B(0x245190008020, 0x2000C00100041000),
|
| 1361 |
-
B(0x1000000A100046, 0x88000084800004),
|
| 1362 |
-
B(0x1000000220240002, 0x400000401001088),
|
| 1363 |
-
B(0x1000000220240002, 0x400000401001088),
|
| 1364 |
-
B(0x820000118808000, 0x8000048161004A),
|
| 1365 |
-
B(0x1100000000071A02, 0x500146102000048),
|
| 1366 |
-
B(0x610000, 0x10010080040641),
|
| 1367 |
-
B(0x2000010441A0044, 0x500800502020188),
|
| 1368 |
-
B(0xA80000000180000, 0x234402012110080),
|
| 1369 |
-
};
|
| 1370 |
-
constexpr Bitboard GrasshopperMagicHInit[SQUARE_NB] = {
|
| 1371 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 1372 |
-
B(0x24200C080840A052, 0x2004004000010008),
|
| 1373 |
-
B(0xC030024000228800, 0x4000010400000020),
|
| 1374 |
-
B(0x1A0020802008802, 0x206010208000),
|
| 1375 |
-
B(0x12002000D001024, 0x80100800090138),
|
| 1376 |
-
B(0x4220010000241010, 0x3098000602001500),
|
| 1377 |
-
B(0x401010004801040, 0x8000280480100000),
|
| 1378 |
-
B(0x820082024921836, 0x220028000),
|
| 1379 |
-
B(0x100400502411400, 0x220402120240D14),
|
| 1380 |
-
B(0x880202020010404, 0xA80202510000),
|
| 1381 |
-
B(0x140002801000018, 0x1000346490040),
|
| 1382 |
-
B(0x120000880110000, 0x1008000000020020),
|
| 1383 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 1384 |
-
B(0x8420060100020000, 0x800280400000120),
|
| 1385 |
-
B(0x4010020018010, 0x40A00001100000),
|
| 1386 |
-
B(0x40006A0004000200, 0x40000000110),
|
| 1387 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 1388 |
-
B(0x8908A20028110011, 0x800080000001A114),
|
| 1389 |
-
B(0x200042000080F009, 0x20001000004000),
|
| 1390 |
-
B(0x2820008820100, 0x10002400058000B9),
|
| 1391 |
-
B(0x6083100420008050, 0x4040012600280080),
|
| 1392 |
-
B(0x216020000000446, 0x4080204000000211),
|
| 1393 |
-
B(0x340140003002089, 0x2402008000000911),
|
| 1394 |
-
B(0xD01004008030400, 0x104000408104420),
|
| 1395 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 1396 |
-
B(0x8C0488120024214, 0x8414880202291),
|
| 1397 |
-
B(0x1010000060050000, 0x4000004050002602),
|
| 1398 |
-
B(0x4022983A0060000, 0x80000040010400),
|
| 1399 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 1400 |
-
B(0x6020101802002840, 0x31000003000004),
|
| 1401 |
-
B(0x9000420008840, 0x4881300000000210),
|
| 1402 |
-
B(0xA200808865, 0x41C0048023000128),
|
| 1403 |
-
B(0x31801100400000, 0x8802DC001221240),
|
| 1404 |
-
B(0x884000080200920, 0x1004002410401001),
|
| 1405 |
-
B(0x2400040000884, 0x421006208040C0),
|
| 1406 |
-
B(0x1404040B20001000, 0x8000824010800011),
|
| 1407 |
-
B(0x24100400060009, 0x112008025042410),
|
| 1408 |
-
B(0x1800040009040200, 0x180000A1004E408A),
|
| 1409 |
-
B(0x24100400060009, 0x112008025042410),
|
| 1410 |
-
B(0x4060402008080, 0xC240080000110000),
|
| 1411 |
-
B(0x20080100920020, 0x2002248010242052),
|
| 1412 |
-
B(0x10001010802050, 0x880000001C98420),
|
| 1413 |
-
B(0x4000800100420022, 0x502022010A00D0),
|
| 1414 |
-
B(0x4C18104500200885, 0x400880800),
|
| 1415 |
-
B(0x8080810081020090, 0x8000000000000),
|
| 1416 |
-
B(0x8000062812080201, 0x8004C8300800),
|
| 1417 |
-
B(0xC010220920198, 0x85000A08000),
|
| 1418 |
-
B(0x24100400060009, 0x112008025042410),
|
| 1419 |
-
B(0x80102204040, 0x1000000900000000),
|
| 1420 |
-
B(0x2080000004202804, 0x120880003461),
|
| 1421 |
-
B(0x102004090A4030, 0x801020589240),
|
| 1422 |
-
B(0x20001100814000A0, 0x420202000820004),
|
| 1423 |
-
B(0x100800000A000120, 0x208000800010000),
|
| 1424 |
-
B(0x1008205000040802, 0x80002000400040),
|
| 1425 |
-
B(0x1480000098008401, 0xA0010000581010),
|
| 1426 |
-
B(0x30C0008200100820, 0x102800080904834),
|
| 1427 |
-
B(0x4810821884000500, 0x4400000200000212),
|
| 1428 |
-
B(0x1811D00128A0180, 0x2500848803000000),
|
| 1429 |
-
B(0x41618A0300040040, 0x21200200A421801),
|
| 1430 |
-
B(0x80102204040, 0x1000000900000000),
|
| 1431 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 1432 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 1433 |
-
B(0x40006002210044, 0x600008000408000),
|
| 1434 |
-
B(0x1200447220090042, 0x80001000160012),
|
| 1435 |
-
B(0x48410010AB000000, 0x9200600000000100),
|
| 1436 |
-
B(0x2040000000240003, 0x8020080288000600),
|
| 1437 |
-
B(0x9080000088848088, 0x4010210500000041),
|
| 1438 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 1439 |
-
B(0x480100400024, 0x1004800018200000),
|
| 1440 |
-
B(0x808403080080200, 0x802601000000500),
|
| 1441 |
-
B(0x8C890020410000A0, 0xA010000048000400),
|
| 1442 |
-
B(0xA1808E0100108000, 0x2008000505000002),
|
| 1443 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 1444 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 1445 |
-
B(0x400014006000000, 0x10006000810001F5),
|
| 1446 |
-
B(0xC410062001414, 0x820080041B01044),
|
| 1447 |
-
B(0x20000800310, 0x430040000201000),
|
| 1448 |
-
B(0xA40010008000008, 0x4002200028000040),
|
| 1449 |
-
B(0xC00102000008021C, 0x10C2000A010E024),
|
| 1450 |
-
B(0x80004200104008, 0x50A00800C400020),
|
| 1451 |
-
B(0x20200080012542, 0x910F0040000402C0),
|
| 1452 |
-
B(0xB040100504000300, 0x24802002000040),
|
| 1453 |
-
B(0x800001000014008, 0x400031004000),
|
| 1454 |
-
B(0x100A40000004008, 0x2800200400200480),
|
| 1455 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 1456 |
-
B(0x440090001012001, 0x4020004010),
|
| 1457 |
-
B(0x100A0028088020, 0x80040E00010020),
|
| 1458 |
-
B(0x2180808000810, 0xB018040A00040000),
|
| 1459 |
-
B(0x40C80920304C4001, 0x42800B200800000),
|
| 1460 |
-
B(0x85000425001000, 0x4810048020001100),
|
| 1461 |
-
B(0x600C000801000004, 0x8015084010200020),
|
| 1462 |
-
B(0x20020050000240C0, 0x100202008600800),
|
| 1463 |
-
B(0x38000050001220, 0x9200010200145900),
|
| 1464 |
-
B(0x1042108040005, 0x1402A0802201001),
|
| 1465 |
-
B(0x824240000C20400, 0x1000000400080010),
|
| 1466 |
-
B(0x84008002041081C0, 0x8080500200000000),
|
| 1467 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 1468 |
-
B(0x8000402308483, 0x20006020100100),
|
| 1469 |
-
B(0x80880120000080, 0x8000240100084),
|
| 1470 |
-
B(0x5840020004882001, 0x1004528000A00010),
|
| 1471 |
-
B(0x8001018800300002, 0x84010040804),
|
| 1472 |
-
B(0x180D10004000A008, 0xA001080008020004),
|
| 1473 |
-
B(0x400080B, 0x10A0000004010000),
|
| 1474 |
-
B(0x8080000200000, 0x2001000082004E0),
|
| 1475 |
-
B(0x40040001000C2000, 0x2024800001004008),
|
| 1476 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 1477 |
-
B(0x8000402308483, 0x20006020100100),
|
| 1478 |
-
B(0x400804A1000008, 0x1024104A0200010),
|
| 1479 |
-
B(0x2000200000, 0x1201011000802),
|
| 1480 |
-
B(0x100100000000C4, 0x208004084048201),
|
| 1481 |
-
B(0x400084000044, 0x100810140300),
|
| 1482 |
-
B(0x29040C0C01010, 0x300204010820080),
|
| 1483 |
-
B(0x1A808000020200, 0x1000000005210040),
|
| 1484 |
-
B(0x20000400150000, 0x85008020),
|
| 1485 |
-
B(0x40C040008184014, 0x8002AA00024010),
|
| 1486 |
-
B(0x202000081B00804, 0x10001002008),
|
| 1487 |
-
B(0x40011000210060, 0x6080C40000021004),
|
| 1488 |
-
B(0x2000200000, 0x1201011000802),
|
| 1489 |
-
B(0x4100480203840, 0x300080100804),
|
| 1490 |
-
B(0x2000200000, 0x1201011000802),
|
| 1491 |
-
};
|
| 1492 |
-
constexpr Bitboard GrasshopperMagicVInit[SQUARE_NB] = {
|
| 1493 |
-
B(0x202000812104400, 0x24800B01C0000303),
|
| 1494 |
-
B(0x340020400010D, 0x88060150C00400),
|
| 1495 |
-
B(0x400802040609, 0x49010200501A0002),
|
| 1496 |
-
B(0x8002680301000208, 0x628006C0C020200),
|
| 1497 |
-
B(0x20400209001C0804, 0xA044000800143110),
|
| 1498 |
-
B(0xC400082060010202, 0x4000480401014000),
|
| 1499 |
-
B(0x22500200144040, 0x8204820084704C00),
|
| 1500 |
-
B(0x8C1204009030020, 0x328400805000000),
|
| 1501 |
-
B(0x84800800D0001640, 0x200080040060108),
|
| 1502 |
-
B(0x804810208020040, 0x140010108020000),
|
| 1503 |
-
B(0x1102010B008004, 0x300208006220020),
|
| 1504 |
-
B(0x140080404A0A2428, 0x6308010100080),
|
| 1505 |
-
B(0x20444002120408, 0xA080010508010001),
|
| 1506 |
-
B(0x82011044000D02, 0x4112028620110809),
|
| 1507 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 1508 |
-
B(0x81010831000C02, 0x408802085000000),
|
| 1509 |
-
B(0x920008920600040, 0x8053801004000028),
|
| 1510 |
-
B(0x81140283208300, 0x10040C004200420),
|
| 1511 |
-
B(0x103080022201, 0xC01000081312620),
|
| 1512 |
-
B(0x2200221100008, 0x1000408104000A4),
|
| 1513 |
-
B(0x4402088080042008, 0x210401501040340),
|
| 1514 |
-
B(0x898400202170001, 0x80040404208000),
|
| 1515 |
-
B(0x20080004051012, 0x5100048200081800),
|
| 1516 |
-
B(0x2320020000401018, 0x108501021040210),
|
| 1517 |
-
B(0x21080410A422021, 0x83040180008800),
|
| 1518 |
-
B(0x44E8100000408224, 0x20010008040400),
|
| 1519 |
-
B(0x1800240002810405, 0x23004820000020),
|
| 1520 |
-
B(0x80A0100400110, 0x80104020100C4028),
|
| 1521 |
-
B(0x1002050001222C0, 0x5100818004024020),
|
| 1522 |
-
B(0x104000200040, 0xC010A09800102000),
|
| 1523 |
-
B(0x1020003A058120, 0x450900809000302),
|
| 1524 |
-
B(0x40040045008B1, 0x202800400383010),
|
| 1525 |
-
B(0x4640200220034, 0x8800485420304000),
|
| 1526 |
-
B(0x5001042100084288, 0x110820001240080A),
|
| 1527 |
-
B(0x2002C04004010120, 0xA15008020880001),
|
| 1528 |
-
B(0x2800004080C4190, 0x890808280020080),
|
| 1529 |
-
B(0x40C0401000104000, 0x2020880008002580),
|
| 1530 |
-
B(0x40020C002400802, 0x801104010000000),
|
| 1531 |
-
B(0x44842000040080, 0x2050011084000400),
|
| 1532 |
-
B(0x4110040800000401, 0x2023810029008000),
|
| 1533 |
-
B(0x20884000840, 0x8017102004008000),
|
| 1534 |
-
B(0x10411104000480, 0x1414042000201001),
|
| 1535 |
-
B(0x220040000008, 0x800306021000000),
|
| 1536 |
-
B(0x41400A0008080, 0x501000298ACAD10),
|
| 1537 |
-
B(0x800240012831810, 0x80120004468050E),
|
| 1538 |
-
B(0x800005020801008, 0x20102400240000),
|
| 1539 |
-
B(0x20C00040C114C010, 0x88080820200C00),
|
| 1540 |
-
B(0x1044010100820081, 0x20080841004000),
|
| 1541 |
-
B(0x8041048400022, 0x8020836040005002),
|
| 1542 |
-
B(0x2001004010205, 0x8001002884042009),
|
| 1543 |
-
B(0x128088400087, 0x20008002201002),
|
| 1544 |
-
B(0x8084108040402000, 0x80809000A080400),
|
| 1545 |
-
B(0x408081840880, 0x201002088000040),
|
| 1546 |
-
B(0xA40180010280, 0x241004006000010),
|
| 1547 |
-
B(0x4204100080048140, 0x2002C4F104202020),
|
| 1548 |
-
B(0x100140A10204, 0x980200800840060),
|
| 1549 |
-
B(0x1005140010202048, 0x1442280800202815),
|
| 1550 |
-
B(0x2000082025008600, 0x1108400040600003),
|
| 1551 |
-
B(0x1005050648000, 0x200020240008002),
|
| 1552 |
-
B(0x202010208044000, 0x8210404060008),
|
| 1553 |
-
B(0x8011040402000210, 0xC840180408016004),
|
| 1554 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 1555 |
-
B(0x404098801028, 0x80020A0001000400),
|
| 1556 |
-
B(0x80101002180140, 0x40C2080820000C0),
|
| 1557 |
-
B(0x208202081260800, 0x14090E4C04000050),
|
| 1558 |
-
B(0x4221201084004C2, 0x110480A011060),
|
| 1559 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 1560 |
-
B(0x8000008421090204, 0x1C01010800024),
|
| 1561 |
-
B(0x200180C840088A0, 0x401100400820000),
|
| 1562 |
-
B(0x10084043A021070, 0x202041600080200),
|
| 1563 |
-
B(0x210E6202001040C, 0x10100800080B0),
|
| 1564 |
-
B(0x848008021204002, 0x801004308100BAD),
|
| 1565 |
-
B(0xC082C0390A000601, 0x4040080189008),
|
| 1566 |
-
B(0x431200240210402D, 0x58102820000),
|
| 1567 |
-
B(0x202020100A0019B0, 0x4010C0D018000000),
|
| 1568 |
-
B(0x800800908402203, 0x102948C84C184),
|
| 1569 |
-
B(0x26801100080845, 0x4009702022A00820),
|
| 1570 |
-
B(0x8880520010401040, 0x1060084832052000),
|
| 1571 |
-
B(0x100100022042081, 0x10000600008C121),
|
| 1572 |
-
B(0x46020384100040, 0x800200320882021),
|
| 1573 |
-
B(0xC0002010148, 0x4200800800040003),
|
| 1574 |
-
B(0x2002208020090040, 0x40820210021410),
|
| 1575 |
-
B(0x9000A41160002004, 0x2A09000100080043),
|
| 1576 |
-
B(0x800004010008001, 0x1108002020104600),
|
| 1577 |
-
B(0x800540C000A4E041, 0x18021180000401),
|
| 1578 |
-
B(0x808200900A900202, 0x8364202140012005),
|
| 1579 |
-
B(0x1DBA52000081010, 0x4008000023000010),
|
| 1580 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 1581 |
-
B(0x4100110204401481, 0x800040091020001C),
|
| 1582 |
-
B(0x4101100020400482, 0x2000402302100120),
|
| 1583 |
-
B(0x100408000A020212, 0xA000400111000020),
|
| 1584 |
-
B(0x2000010488080104, 0x3000404410208100),
|
| 1585 |
-
B(0x2684220180008DD0, 0x422040200004000A),
|
| 1586 |
-
B(0x2021200C0424, 0x1010100000080200),
|
| 1587 |
-
B(0x8908020020801006, 0x3010800020C2000),
|
| 1588 |
-
B(0x4000030008062044, 0x244010202688000),
|
| 1589 |
-
B(0x242101200408009, 0x8150040000200015),
|
| 1590 |
-
B(0x42004C02180204, 0x210208014241040),
|
| 1591 |
-
B(0x4E1A01C208410804, 0x8890041000012004),
|
| 1592 |
-
B(0x2080200401000080, 0x8001098429008004),
|
| 1593 |
-
B(0xA01400121804104, 0x280200C400000500),
|
| 1594 |
-
B(0xD0080408040420, 0x1006040100224000),
|
| 1595 |
-
B(0x28400205000800C9, 0x6021101401040075),
|
| 1596 |
-
B(0x4000900040020104, 0x88129801100D0C),
|
| 1597 |
-
B(0x8000004002180410, 0x400380200400204),
|
| 1598 |
-
B(0x4002A430043008, 0x400200340100020),
|
| 1599 |
-
B(0x401960004140A42, 0x100880710000464),
|
| 1600 |
-
B(0x58014090102, 0xB8D30004010080),
|
| 1601 |
-
B(0xA004C08000244000, 0x11280100E0000040),
|
| 1602 |
-
B(0x2102008089208804, 0x110001004080040),
|
| 1603 |
-
B(0x700010084E003004, 0x8080864112000D40),
|
| 1604 |
-
B(0x4080881000200C20, 0x30324040880E0600),
|
| 1605 |
-
B(0x2024A40401810820, 0x3000888002000000),
|
| 1606 |
-
B(0x8200100400014, 0x4400340800252844),
|
| 1607 |
-
B(0x24A00804288281, 0x410103002201140),
|
| 1608 |
-
B(0x4080005022A08, 0x1000402200100264),
|
| 1609 |
-
B(0x200080032244040, 0x200502189010001),
|
| 1610 |
-
B(0x28108110404001, 0x400600120008412),
|
| 1611 |
-
B(0xA00002102810020, 0xB1080240015408),
|
| 1612 |
-
B(0x810080200806, 0x410440804080046),
|
| 1613 |
-
};
|
| 1614 |
-
constexpr Bitboard GrasshopperMagicDInit[SQUARE_NB] = {
|
| 1615 |
-
B(0x811801000400, 0x312260280280202),
|
| 1616 |
-
B(0x44A000402022680, 0x1020224880420005),
|
| 1617 |
-
B(0x8000C80800200880, 0x2000810060080C0),
|
| 1618 |
-
B(0x2010300240428040, 0x40240002C004E30),
|
| 1619 |
-
B(0x1018010404010004, 0x1001010018081E0),
|
| 1620 |
-
B(0x2042040010080090, 0x100000008410300),
|
| 1621 |
-
B(0x400080020102000, 0x4500005300000000),
|
| 1622 |
-
B(0x2D00C80420010200, 0x804003280020008),
|
| 1623 |
-
B(0x8038820024420, 0x6010010080012040),
|
| 1624 |
-
B(0x1202028004200088, 0x50018100004000C6),
|
| 1625 |
-
B(0xA02010F0410081, 0x20013001000009A),
|
| 1626 |
-
B(0x4013002041030588, 0x4802004110000004),
|
| 1627 |
-
B(0x110020802000081, 0x202001800908002),
|
| 1628 |
-
B(0x22010404103, 0x2020882080491200),
|
| 1629 |
-
B(0x60000220400580, 0x85902800100100),
|
| 1630 |
-
B(0x100080800050100, 0x200010220021088),
|
| 1631 |
-
B(0x8088840404200080, 0x140011040104000),
|
| 1632 |
-
B(0x4008508080082015, 0x8010100200580048),
|
| 1633 |
-
B(0x4010400420201001, 0x260002080A80808),
|
| 1634 |
-
B(0xC2002004A0008008, 0x8020082000110840),
|
| 1635 |
-
B(0xA000A0820042400, 0x810408082100420),
|
| 1636 |
-
B(0x80231808100004, 0x204002000800400),
|
| 1637 |
-
B(0x8296144044004900, 0x4A1003008001840),
|
| 1638 |
-
B(0x80A0020A0011008, 0x800104846080810),
|
| 1639 |
-
B(0x803800801041000, 0x1030500102000404),
|
| 1640 |
-
B(0x240C00900800850, 0x1804000108810000),
|
| 1641 |
-
B(0x800400000088800, 0x800021801020000),
|
| 1642 |
-
B(0x84800409300082, 0x1002D40680044000),
|
| 1643 |
-
B(0xA110C0000200010, 0x401010001200260),
|
| 1644 |
-
B(0x8200160204100004, 0x8040004004002022),
|
| 1645 |
-
B(0x10001000000100C0, 0x84002811000200),
|
| 1646 |
-
B(0x2000080020014001, 0x42002020000102),
|
| 1647 |
-
B(0x109040044020018, 0x2020400202001000),
|
| 1648 |
-
B(0x620000CD0108, 0x40040201008000),
|
| 1649 |
-
B(0xA1402200A0020, 0x81400400300912),
|
| 1650 |
-
B(0x20020CF100018020, 0x801A14086404000),
|
| 1651 |
-
B(0x800801844001, 0x11621488425000),
|
| 1652 |
-
B(0x10201004A8080, 0x100A000801000010),
|
| 1653 |
-
B(0x2800411001000800, 0x80224084900020),
|
| 1654 |
-
B(0x40400024028100, 0x501000400230060),
|
| 1655 |
-
B(0x404808010080, 0x1201000400100004),
|
| 1656 |
-
B(0x80802005200, 0x2000200008A0000),
|
| 1657 |
-
B(0x20800080000022, 0x80040810002010),
|
| 1658 |
-
B(0x40016004808240, 0x400114000801100),
|
| 1659 |
-
B(0x8410004204240, 0x20011000604050),
|
| 1660 |
-
B(0x8000C1009008268, 0x201004000209000),
|
| 1661 |
-
B(0x10240C000920, 0xE000A5C14003002),
|
| 1662 |
-
B(0x10184024280008, 0x90240802000000),
|
| 1663 |
-
B(0x40889081081000, 0x8010050008800000),
|
| 1664 |
-
B(0x100008C089000019, 0x802032014020010),
|
| 1665 |
-
B(0x401C1804C00, 0x402501002002020),
|
| 1666 |
-
B(0x200022000920D0, 0x8000800081300020),
|
| 1667 |
-
B(0x801000400011, 0x400100044010226),
|
| 1668 |
-
B(0x4A04010100100000, 0x500400080400000),
|
| 1669 |
-
B(0xA000050200080000, 0x8500090001010000),
|
| 1670 |
-
B(0x40400040001812, 0x4403000400100A0),
|
| 1671 |
-
B(0x20C2250203020004, 0x210001C000080000),
|
| 1672 |
-
B(0x21000408C6020001, 0x4200830012D1001),
|
| 1673 |
-
B(0x840082016080A210, 0x2400080801081008),
|
| 1674 |
-
B(0x40001020000, 0x4041240200083120),
|
| 1675 |
-
B(0x2C04030010C0818, 0xA670002000818100),
|
| 1676 |
-
B(0x4704A07085000510, 0x914001000040),
|
| 1677 |
-
B(0x900210304100100, 0x1010004000281840),
|
| 1678 |
-
B(0x8202920002002040, 0x810012000003),
|
| 1679 |
-
B(0x4001400100050, 0x1144000408002000),
|
| 1680 |
-
B(0x5900200020008100, 0x40200020002004),
|
| 1681 |
-
B(0x301020002000480, 0x202000C0004),
|
| 1682 |
-
B(0x20D000201104040, 0x34840100020010),
|
| 1683 |
-
B(0x800004200080408, 0x40184200100240),
|
| 1684 |
-
B(0x8430080100404020, 0x90042100244500),
|
| 1685 |
-
B(0x3800100010220062, 0x50404030200218),
|
| 1686 |
-
B(0x42E20008002020, 0x2000008200200300),
|
| 1687 |
-
B(0xE488008280A004, 0x200001010CC80000),
|
| 1688 |
-
B(0x6018010041109810, 0x800002000242041A),
|
| 1689 |
-
B(0x40A8002438980, 0x8000810008208009),
|
| 1690 |
-
B(0x401000480040100, 0x286800404002212),
|
| 1691 |
-
B(0x821030000100009, 0x2000090200A00000),
|
| 1692 |
-
B(0x20000100C0008028, 0x5000000100400082),
|
| 1693 |
-
B(0x80A000048030080, 0x200000120200008),
|
| 1694 |
-
B(0x6300280800204003, 0x48000105C0040100),
|
| 1695 |
-
B(0x83008802420C0200, 0x2008020200080100),
|
| 1696 |
-
B(0x1050C3102200042, 0x20103900010008),
|
| 1697 |
-
B(0x8040902021408180, 0x12000021806200A4),
|
| 1698 |
-
B(0x3008204008C10004, 0x680110100010401),
|
| 1699 |
-
B(0x204321100421000, 0x400E204820494000),
|
| 1700 |
-
B(0x8000044022404048, 0x4024010090024021),
|
| 1701 |
-
B(0x140201424050, 0x280A000130008000),
|
| 1702 |
-
B(0x900340808004002, 0x21026008000380),
|
| 1703 |
-
B(0x82808000300444, 0x20002000A2001141),
|
| 1704 |
-
B(0x140180100406002, 0x4004480001000004),
|
| 1705 |
-
B(0x4808420800841900, 0x14008C0041000000),
|
| 1706 |
-
B(0x2008600009000480, 0x9008020001400000),
|
| 1707 |
-
B(0x2000100800100002, 0x2004100820210020),
|
| 1708 |
-
B(0x2062010401A8100, 0x12200108420090),
|
| 1709 |
-
B(0x1403188200032, 0x40048166105000),
|
| 1710 |
-
B(0x410020020140041, 0x4400348102940040),
|
| 1711 |
-
B(0x414040209208041, 0x4402400028B004),
|
| 1712 |
-
B(0x8008010100421202, 0x401418002008800),
|
| 1713 |
-
B(0x4000020010062200, 0xA02009148048000),
|
| 1714 |
-
B(0x4443080082008B, 0x104014022801010),
|
| 1715 |
-
B(0x42B440A0C000800, 0x9001009016111020),
|
| 1716 |
-
B(0x400000214002, 0x8008080209020009),
|
| 1717 |
-
B(0x480C414A001900, 0x3400100400210200),
|
| 1718 |
-
B(0x1006008800604, 0x20240004030A050),
|
| 1719 |
-
B(0x4C022401002A8300, 0x405008400000600),
|
| 1720 |
-
B(0x3104000800A1042, 0x2004800204406200),
|
| 1721 |
-
B(0xA09010280008200C, 0x4004000208C4168),
|
| 1722 |
-
B(0x2800401120C20120, 0x4A00450200022030),
|
| 1723 |
-
B(0x88001800304C0200, 0x204288102080000),
|
| 1724 |
-
B(0x8044004201440101, 0x400820080C024022),
|
| 1725 |
-
B(0xA000100C080, 0x4B40341004008081),
|
| 1726 |
-
B(0x94802001300810, 0x140206008000800),
|
| 1727 |
-
B(0x40002020202820, 0x280680404000040),
|
| 1728 |
-
B(0xA820800004200, 0x80E1401012000491),
|
| 1729 |
-
B(0x804000010020C000, 0x9403020200802000),
|
| 1730 |
-
B(0x8C0001284201400, 0xC000100C01620800),
|
| 1731 |
-
B(0x4010004002200414, 0x403080080200000),
|
| 1732 |
-
B(0x140400A100800101, 0x10054C031080400),
|
| 1733 |
-
B(0x20012C2400880082, 0x7000880020C03200),
|
| 1734 |
-
B(0x204040300004, 0x840800041101002),
|
| 1735 |
-
};
|
| 1736 |
-
#undef B
|
| 1737 |
-
#endif
|
| 1738 |
-
|
| 1739 |
-
} // namespace Stockfish
|
| 1740 |
-
|
| 1741 |
-
#endif // #ifndef MAGIC_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/main.cpp
DELETED
|
@@ -1,63 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <iostream>
|
| 20 |
-
|
| 21 |
-
#include "bitboard.h"
|
| 22 |
-
#include "endgame.h"
|
| 23 |
-
#include "position.h"
|
| 24 |
-
#include "psqt.h"
|
| 25 |
-
#include "search.h"
|
| 26 |
-
#include "syzygy/tbprobe.h"
|
| 27 |
-
#include "thread.h"
|
| 28 |
-
#include "tt.h"
|
| 29 |
-
#include "uci.h"
|
| 30 |
-
|
| 31 |
-
#include "piece.h"
|
| 32 |
-
#include "variant.h"
|
| 33 |
-
#include "xboard.h"
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
using namespace Stockfish;
|
| 37 |
-
|
| 38 |
-
int main(int argc, char* argv[]) {
|
| 39 |
-
|
| 40 |
-
std::cout << engine_info() << std::endl;
|
| 41 |
-
|
| 42 |
-
pieceMap.init();
|
| 43 |
-
variants.init();
|
| 44 |
-
CommandLine::init(argc, argv);
|
| 45 |
-
UCI::init(Options);
|
| 46 |
-
Tune::init();
|
| 47 |
-
PSQT::init(variants.find(Options["UCI_Variant"])->second);
|
| 48 |
-
Bitboards::init();
|
| 49 |
-
Position::init();
|
| 50 |
-
Bitbases::init();
|
| 51 |
-
Endgames::init();
|
| 52 |
-
Threads.set(size_t(Options["Threads"]));
|
| 53 |
-
Search::clear(); // After threads are up
|
| 54 |
-
Eval::NNUE::init();
|
| 55 |
-
|
| 56 |
-
UCI::loop(argc, argv);
|
| 57 |
-
|
| 58 |
-
Threads.set(0);
|
| 59 |
-
variants.clear_all();
|
| 60 |
-
pieceMap.clear_all();
|
| 61 |
-
delete XBoard::stateMachine;
|
| 62 |
-
return 0;
|
| 63 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/material.cpp
DELETED
|
@@ -1,321 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <cassert>
|
| 20 |
-
#include <cstring> // For std::memset
|
| 21 |
-
|
| 22 |
-
#include "material.h"
|
| 23 |
-
#include "thread.h"
|
| 24 |
-
|
| 25 |
-
using namespace std;
|
| 26 |
-
|
| 27 |
-
namespace Stockfish {
|
| 28 |
-
|
| 29 |
-
namespace {
|
| 30 |
-
#define S(mg, eg) make_score(mg, eg)
|
| 31 |
-
|
| 32 |
-
// Polynomial material imbalance parameters
|
| 33 |
-
|
| 34 |
-
// One Score parameter for each pair (our piece, another of our pieces)
|
| 35 |
-
constexpr Score QuadraticOurs[][PIECE_TYPE_NB] = {
|
| 36 |
-
// OUR PIECE 2
|
| 37 |
-
// bishop pair pawn knight bishop rook queen
|
| 38 |
-
{S(1419, 1455) }, // Bishop pair
|
| 39 |
-
{S( 101, 28), S( 37, 39) }, // Pawn
|
| 40 |
-
{S( 57, 64), S(249, 187), S(-49, -62) }, // Knight OUR PIECE 1
|
| 41 |
-
{S( 0, 0), S(118, 137), S( 10, 27), S( 0, 0) }, // Bishop
|
| 42 |
-
{S( -63, -68), S( -5, 3), S(100, 81), S(132, 118), S(-246, -244) }, // Rook
|
| 43 |
-
{S(-210, -211), S( 37, 14), S(147, 141), S(161, 105), S(-158, -174), S(-9,-31) } // Queen
|
| 44 |
-
};
|
| 45 |
-
|
| 46 |
-
// One Score parameter for each pair (our piece, their piece)
|
| 47 |
-
constexpr Score QuadraticTheirs[][PIECE_TYPE_NB] = {
|
| 48 |
-
// THEIR PIECE
|
| 49 |
-
// bishop pair pawn knight bishop rook queen
|
| 50 |
-
{ }, // Bishop pair
|
| 51 |
-
{S( 33, 30) }, // Pawn
|
| 52 |
-
{S( 46, 18), S(106, 84) }, // Knight OUR PIECE
|
| 53 |
-
{S( 75, 35), S( 59, 44), S( 60, 15) }, // Bishop
|
| 54 |
-
{S( 26, 35), S( 6, 22), S( 38, 39), S(-12, -2) }, // Rook
|
| 55 |
-
{S( 97, 93), S(100, 163), S(-58, -91), S(112, 192), S(276, 225) } // Queen
|
| 56 |
-
};
|
| 57 |
-
|
| 58 |
-
#undef S
|
| 59 |
-
|
| 60 |
-
// Endgame evaluation and scaling functions are accessed directly and not through
|
| 61 |
-
// the function maps because they correspond to more than one material hash key.
|
| 62 |
-
Endgame<KFsPsK> EvaluateKFsPsK[] = { Endgame<KFsPsK>(WHITE), Endgame<KFsPsK>(BLACK) };
|
| 63 |
-
Endgame<KXK> EvaluateKXK[] = { Endgame<KXK>(WHITE), Endgame<KXK>(BLACK) };
|
| 64 |
-
Endgame<KXK, EG_EVAL_ATOMIC> EvaluateKXKAtomic[] = { Endgame<KXK, EG_EVAL_ATOMIC>(WHITE), Endgame<KXK, EG_EVAL_ATOMIC>(BLACK) };
|
| 65 |
-
Endgame<KXK, EG_EVAL_DUCK> EvaluateKXKDuck[] = { Endgame<KXK, EG_EVAL_DUCK>(WHITE), Endgame<KXK, EG_EVAL_DUCK>(BLACK) };
|
| 66 |
-
Endgame<KXKX, EG_EVAL_MISERE> EvaluateKXKXMisere[] = { Endgame<KXKX, EG_EVAL_MISERE>(WHITE), Endgame<KXKX, EG_EVAL_MISERE>(BLACK) };
|
| 67 |
-
|
| 68 |
-
Endgame<KBPsK> ScaleKBPsK[] = { Endgame<KBPsK>(WHITE), Endgame<KBPsK>(BLACK) };
|
| 69 |
-
Endgame<KQKRPs> ScaleKQKRPs[] = { Endgame<KQKRPs>(WHITE), Endgame<KQKRPs>(BLACK) };
|
| 70 |
-
Endgame<KPsK> ScaleKPsK[] = { Endgame<KPsK>(WHITE), Endgame<KPsK>(BLACK) };
|
| 71 |
-
Endgame<KPKP> ScaleKPKP[] = { Endgame<KPKP>(WHITE), Endgame<KPKP>(BLACK) };
|
| 72 |
-
|
| 73 |
-
// Helper used to detect a given material distribution
|
| 74 |
-
bool is_KFsPsK(const Position& pos, Color us) {
|
| 75 |
-
return (pos.promotion_piece_types(us) == piece_set(FERS))
|
| 76 |
-
&& !more_than_one(pos.pieces(~us))
|
| 77 |
-
&& (pos.count<FERS>(us) || pos.count<PAWN>(us))
|
| 78 |
-
&& !(pos.count<ALL_PIECES>(us) - pos.count<FERS>(us) - pos.count<PAWN>(us) - pos.count<KING>(us));
|
| 79 |
-
}
|
| 80 |
-
|
| 81 |
-
bool is_KXK(const Position& pos, Color us) {
|
| 82 |
-
return !more_than_one(pos.pieces(~us))
|
| 83 |
-
&& pos.non_pawn_material(us) >= std::min(RookValueMg, 2 * SilverValueMg);
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
bool is_KXK_atomic(const Position& pos, Color us) {
|
| 87 |
-
return !more_than_one(pos.pieces(~us))
|
| 88 |
-
&& pos.non_pawn_material(us) >= RookValueMg + KnightValueMg;
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
bool is_KXKX(const Position& pos, Color us) {
|
| 92 |
-
return pos.non_pawn_material(us) - pos.non_pawn_material(~us) > QueenValueMg;
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
-
bool is_KBPsK(const Position& pos, Color us) {
|
| 96 |
-
return pos.non_pawn_material(us) == BishopValueMg
|
| 97 |
-
&& pos.count<PAWN>(us) >= 1;
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
bool is_KQKRPs(const Position& pos, Color us) {
|
| 101 |
-
return !pos.count<PAWN>(us)
|
| 102 |
-
&& pos.non_pawn_material(us) == QueenValueMg
|
| 103 |
-
&& pos.count<ROOK>(~us) == 1
|
| 104 |
-
&& pos.count<PAWN>(~us) >= 1;
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
/// imbalance() calculates the imbalance by comparing the piece count of each
|
| 109 |
-
/// piece type for both colors.
|
| 110 |
-
|
| 111 |
-
template<Color Us>
|
| 112 |
-
Score imbalance(const Position& pos, const int pieceCount[][PIECE_TYPE_NB]) {
|
| 113 |
-
|
| 114 |
-
constexpr Color Them = ~Us;
|
| 115 |
-
|
| 116 |
-
Score bonus = SCORE_ZERO;
|
| 117 |
-
|
| 118 |
-
// Second-degree polynomial material imbalance, by Tord Romstad
|
| 119 |
-
for (int pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; ++pt1)
|
| 120 |
-
{
|
| 121 |
-
if (!pieceCount[Us][pt1])
|
| 122 |
-
continue;
|
| 123 |
-
|
| 124 |
-
int v = QuadraticOurs[pt1][pt1] * pieceCount[Us][pt1];
|
| 125 |
-
|
| 126 |
-
for (int pt2 = NO_PIECE_TYPE; pt2 < pt1; ++pt2)
|
| 127 |
-
v += QuadraticOurs[pt1][pt2] * pieceCount[Us][pt2]
|
| 128 |
-
+ QuadraticTheirs[pt1][pt2] * pieceCount[Them][pt2];
|
| 129 |
-
|
| 130 |
-
bonus += pieceCount[Us][pt1] * v;
|
| 131 |
-
}
|
| 132 |
-
|
| 133 |
-
if (pos.must_capture())
|
| 134 |
-
bonus += (make_score(mg_value(QuadraticOurs[PAWN][PAWN]), 0) * pieceCount[Us][PAWN]
|
| 135 |
-
+ 3 * QuadraticOurs[KNIGHT][PAWN] * pieceCount[Us][KNIGHT]
|
| 136 |
-
+ QuadraticOurs[QUEEN][PAWN] * pieceCount[Us][QUEEN]) * pieceCount[Us][PAWN]
|
| 137 |
-
+ make_score( mg_value(QuadraticOurs[KNIGHT][KNIGHT]),
|
| 138 |
-
-eg_value(QuadraticOurs[KNIGHT][KNIGHT])) * pieceCount[Us][KNIGHT] * pieceCount[Us][KNIGHT];
|
| 139 |
-
else if (pos.blast_on_capture())
|
| 140 |
-
bonus -= make_score(mg_value(QuadraticOurs[KNIGHT][PAWN]) * pieceCount[Us][KNIGHT] * pieceCount[Us][PAWN] / 2, 0);
|
| 141 |
-
else if (pos.check_counting())
|
| 142 |
-
bonus -= 2 * QuadraticOurs[PAWN][PAWN] * pieceCount[Us][PAWN] * pieceCount[Us][PAWN];
|
| 143 |
-
else if (pos.captures_to_hand())
|
| 144 |
-
bonus -= bonus / 10;
|
| 145 |
-
|
| 146 |
-
return bonus;
|
| 147 |
-
}
|
| 148 |
-
|
| 149 |
-
} // namespace
|
| 150 |
-
|
| 151 |
-
namespace Material {
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
/// Material::probe() looks up the current position's material configuration in
|
| 155 |
-
/// the material hash table. It returns a pointer to the Entry if the position
|
| 156 |
-
/// is found. Otherwise a new Entry is computed and stored there, so we don't
|
| 157 |
-
/// have to recompute all when the same material configuration occurs again.
|
| 158 |
-
|
| 159 |
-
Entry* probe(const Position& pos) {
|
| 160 |
-
|
| 161 |
-
Key key = pos.material_key(pos.endgame_eval());
|
| 162 |
-
Entry* e = pos.this_thread()->materialTable[key];
|
| 163 |
-
|
| 164 |
-
if (e->key == key)
|
| 165 |
-
return e;
|
| 166 |
-
|
| 167 |
-
std::memset(e, 0, sizeof(Entry));
|
| 168 |
-
e->key = key;
|
| 169 |
-
e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
|
| 170 |
-
|
| 171 |
-
Value npm_w = pos.non_pawn_material(WHITE);
|
| 172 |
-
Value npm_b = pos.non_pawn_material(BLACK);
|
| 173 |
-
Value npm = std::clamp(npm_w + npm_b, EndgameLimit, MidgameLimit);
|
| 174 |
-
|
| 175 |
-
// Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME]
|
| 176 |
-
if (pos.captures_to_hand() || pos.two_boards())
|
| 177 |
-
{
|
| 178 |
-
Value npm2 = VALUE_ZERO;
|
| 179 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 180 |
-
{
|
| 181 |
-
PieceType pt = pop_lsb(ps);
|
| 182 |
-
npm2 += pos.count_in_hand(pt) * PieceValue[MG][make_piece(WHITE, pt)];
|
| 183 |
-
}
|
| 184 |
-
e->gamePhase = Phase(PHASE_MIDGAME * npm / std::max(int(npm + npm2), 1));
|
| 185 |
-
int countAll = pos.count_with_hand(WHITE, ALL_PIECES) + pos.count_with_hand(BLACK, ALL_PIECES);
|
| 186 |
-
e->materialDensity = (npm + npm2 + pos.count<PAWN>() * PawnValueMg) * countAll / (pos.files() * pos.ranks());
|
| 187 |
-
}
|
| 188 |
-
else
|
| 189 |
-
e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
|
| 190 |
-
|
| 191 |
-
// Let's look if we have a specialized evaluation function for this particular
|
| 192 |
-
// material configuration. Firstly we look for a fixed configuration one, then
|
| 193 |
-
// for a generic one if the previous search failed.
|
| 194 |
-
if (pos.endgame_eval() && (e->evaluationFunction = Endgames::probe<Value>(key)) != nullptr)
|
| 195 |
-
return e;
|
| 196 |
-
|
| 197 |
-
switch (pos.endgame_eval())
|
| 198 |
-
{
|
| 199 |
-
case EG_EVAL_CHESS:
|
| 200 |
-
for (Color c : { WHITE, BLACK })
|
| 201 |
-
if (is_KFsPsK(pos, c))
|
| 202 |
-
{
|
| 203 |
-
e->evaluationFunction = &EvaluateKFsPsK[c];
|
| 204 |
-
return e;
|
| 205 |
-
}
|
| 206 |
-
|
| 207 |
-
for (Color c : { WHITE, BLACK })
|
| 208 |
-
if (is_KXK(pos, c))
|
| 209 |
-
{
|
| 210 |
-
e->evaluationFunction = &EvaluateKXK[c];
|
| 211 |
-
return e;
|
| 212 |
-
}
|
| 213 |
-
|
| 214 |
-
// OK, we didn't find any special evaluation function for the current material
|
| 215 |
-
// configuration. Is there a suitable specialized scaling function?
|
| 216 |
-
{
|
| 217 |
-
const auto* sf = Endgames::probe<ScaleFactor>(key);
|
| 218 |
-
|
| 219 |
-
if (sf)
|
| 220 |
-
{
|
| 221 |
-
e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned
|
| 222 |
-
return e;
|
| 223 |
-
}
|
| 224 |
-
}
|
| 225 |
-
|
| 226 |
-
// We didn't find any specialized scaling function, so fall back on generic
|
| 227 |
-
// ones that refer to more than one material distribution. Note that in this
|
| 228 |
-
// case we don't return after setting the function.
|
| 229 |
-
for (Color c : { WHITE, BLACK })
|
| 230 |
-
{
|
| 231 |
-
if (is_KBPsK(pos, c))
|
| 232 |
-
e->scalingFunction[c] = &ScaleKBPsK[c];
|
| 233 |
-
|
| 234 |
-
else if (is_KQKRPs(pos, c))
|
| 235 |
-
e->scalingFunction[c] = &ScaleKQKRPs[c];
|
| 236 |
-
}
|
| 237 |
-
|
| 238 |
-
if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board
|
| 239 |
-
{
|
| 240 |
-
if (!pos.count<PAWN>(BLACK))
|
| 241 |
-
{
|
| 242 |
-
assert(pos.count<PAWN>(WHITE) >= 2);
|
| 243 |
-
|
| 244 |
-
e->scalingFunction[WHITE] = &ScaleKPsK[WHITE];
|
| 245 |
-
}
|
| 246 |
-
else if (!pos.count<PAWN>(WHITE))
|
| 247 |
-
{
|
| 248 |
-
assert(pos.count<PAWN>(BLACK) >= 2);
|
| 249 |
-
|
| 250 |
-
e->scalingFunction[BLACK] = &ScaleKPsK[BLACK];
|
| 251 |
-
}
|
| 252 |
-
else if (pos.count<PAWN>(WHITE) == 1 && pos.count<PAWN>(BLACK) == 1)
|
| 253 |
-
{
|
| 254 |
-
// This is a special case because we set scaling functions
|
| 255 |
-
// for both colors instead of only one.
|
| 256 |
-
e->scalingFunction[WHITE] = &ScaleKPKP[WHITE];
|
| 257 |
-
e->scalingFunction[BLACK] = &ScaleKPKP[BLACK];
|
| 258 |
-
}
|
| 259 |
-
}
|
| 260 |
-
|
| 261 |
-
// Zero or just one pawn makes it difficult to win, even with a small material
|
| 262 |
-
// advantage. This catches some trivial draws like KK, KBK and KNK and gives a
|
| 263 |
-
// drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN).
|
| 264 |
-
if (!pos.count<PAWN>(WHITE) && npm_w - npm_b <= BishopValueMg)
|
| 265 |
-
e->factor[WHITE] = uint8_t(npm_w < RookValueMg && pos.count<ALL_PIECES>(WHITE) <= 2 ? SCALE_FACTOR_DRAW :
|
| 266 |
-
npm_b <= BishopValueMg && pos.count<ALL_PIECES>(WHITE) <= 3 ? 4 : 14);
|
| 267 |
-
|
| 268 |
-
if (!pos.count<PAWN>(BLACK) && npm_b - npm_w <= BishopValueMg)
|
| 269 |
-
e->factor[BLACK] = uint8_t(npm_b < RookValueMg && pos.count<ALL_PIECES>(BLACK) <= 2 ? SCALE_FACTOR_DRAW :
|
| 270 |
-
npm_w <= BishopValueMg && pos.count<ALL_PIECES>(BLACK) <= 3 ? 4 : 14);
|
| 271 |
-
break;
|
| 272 |
-
case EG_EVAL_ANTI:
|
| 273 |
-
break;
|
| 274 |
-
case EG_EVAL_ATOMIC:
|
| 275 |
-
for (Color c : { WHITE, BLACK })
|
| 276 |
-
if (is_KXK_atomic(pos, c))
|
| 277 |
-
{
|
| 278 |
-
e->evaluationFunction = &EvaluateKXKAtomic[c];
|
| 279 |
-
return e;
|
| 280 |
-
}
|
| 281 |
-
break;
|
| 282 |
-
case EG_EVAL_DUCK:
|
| 283 |
-
for (Color c : { WHITE, BLACK })
|
| 284 |
-
if (is_KXK(pos, c))
|
| 285 |
-
{
|
| 286 |
-
e->evaluationFunction = &EvaluateKXKDuck[c];
|
| 287 |
-
return e;
|
| 288 |
-
}
|
| 289 |
-
break;
|
| 290 |
-
case EG_EVAL_MISERE:
|
| 291 |
-
for (Color c : { WHITE, BLACK })
|
| 292 |
-
if (is_KXKX(pos, c))
|
| 293 |
-
{
|
| 294 |
-
e->evaluationFunction = &EvaluateKXKXMisere[c];
|
| 295 |
-
return e;
|
| 296 |
-
}
|
| 297 |
-
break;
|
| 298 |
-
case EG_EVAL_RK:
|
| 299 |
-
break;
|
| 300 |
-
case NO_EG_EVAL:
|
| 301 |
-
break;
|
| 302 |
-
default:
|
| 303 |
-
assert(false);
|
| 304 |
-
}
|
| 305 |
-
|
| 306 |
-
// Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder
|
| 307 |
-
// for the bishop pair "extended piece", which allows us to be more flexible
|
| 308 |
-
// in defining bishop pair bonuses.
|
| 309 |
-
const int pieceCount[COLOR_NB][PIECE_TYPE_NB] = {
|
| 310 |
-
{ pos.count<BISHOP>(WHITE) > 1, pos.count<PAWN>(WHITE), pos.count<KNIGHT>(WHITE),
|
| 311 |
-
pos.count<BISHOP>(WHITE) , pos.count<ROOK>(WHITE), pos.count<QUEEN >(WHITE) },
|
| 312 |
-
{ pos.count<BISHOP>(BLACK) > 1, pos.count<PAWN>(BLACK), pos.count<KNIGHT>(BLACK),
|
| 313 |
-
pos.count<BISHOP>(BLACK) , pos.count<ROOK>(BLACK), pos.count<QUEEN >(BLACK) } };
|
| 314 |
-
|
| 315 |
-
e->score = (imbalance<WHITE>(pos, pieceCount) - imbalance<BLACK>(pos, pieceCount)) / 16;
|
| 316 |
-
return e;
|
| 317 |
-
}
|
| 318 |
-
|
| 319 |
-
} // namespace Material
|
| 320 |
-
|
| 321 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/material.h
DELETED
|
@@ -1,75 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef MATERIAL_H_INCLUDED
|
| 20 |
-
#define MATERIAL_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include "endgame.h"
|
| 23 |
-
#include "misc.h"
|
| 24 |
-
#include "position.h"
|
| 25 |
-
#include "types.h"
|
| 26 |
-
|
| 27 |
-
namespace Stockfish::Material {
|
| 28 |
-
|
| 29 |
-
/// Material::Entry contains various information about a material configuration.
|
| 30 |
-
/// It contains a material imbalance evaluation, a function pointer to a special
|
| 31 |
-
/// endgame evaluation function (which in most cases is NULL, meaning that the
|
| 32 |
-
/// standard evaluation function will be used), and scale factors.
|
| 33 |
-
///
|
| 34 |
-
/// The scale factors are used to scale the evaluation score up or down. For
|
| 35 |
-
/// instance, in KRB vs KR endgames, the score is scaled down by a factor of 4,
|
| 36 |
-
/// which will result in scores of absolute value less than one pawn.
|
| 37 |
-
|
| 38 |
-
struct Entry {
|
| 39 |
-
|
| 40 |
-
Score imbalance() const { return score; }
|
| 41 |
-
Phase game_phase() const { return (Phase)gamePhase; }
|
| 42 |
-
bool specialized_eval_exists() const { return evaluationFunction != nullptr; }
|
| 43 |
-
Value evaluate(const Position& pos) const { return (*evaluationFunction)(pos); }
|
| 44 |
-
|
| 45 |
-
int material_density() const { return materialDensity; }
|
| 46 |
-
|
| 47 |
-
// scale_factor() takes a position and a color as input and returns a scale factor
|
| 48 |
-
// for the given color. We have to provide the position in addition to the color
|
| 49 |
-
// because the scale factor may also be a function which should be applied to
|
| 50 |
-
// the position. For instance, in KBP vs K endgames, the scaling function looks
|
| 51 |
-
// for rook pawns and wrong-colored bishops.
|
| 52 |
-
ScaleFactor scale_factor(const Position& pos, Color c) const {
|
| 53 |
-
ScaleFactor sf = scalingFunction[c] ? (*scalingFunction[c])(pos)
|
| 54 |
-
: SCALE_FACTOR_NONE;
|
| 55 |
-
return sf != SCALE_FACTOR_NONE ? sf : ScaleFactor(factor[c]);
|
| 56 |
-
}
|
| 57 |
-
|
| 58 |
-
Key key;
|
| 59 |
-
const EndgameBase<Value>* evaluationFunction;
|
| 60 |
-
const EndgameBase<ScaleFactor>* scalingFunction[COLOR_NB]; // Could be one for each
|
| 61 |
-
// side (e.g. KPKP, KBPsK)
|
| 62 |
-
Score score;
|
| 63 |
-
int16_t gamePhase;
|
| 64 |
-
uint8_t factor[COLOR_NB];
|
| 65 |
-
|
| 66 |
-
int materialDensity;
|
| 67 |
-
};
|
| 68 |
-
|
| 69 |
-
typedef HashTable<Entry, 8192> Table;
|
| 70 |
-
|
| 71 |
-
Entry* probe(const Position& pos);
|
| 72 |
-
|
| 73 |
-
} // namespace Stockfish::Material
|
| 74 |
-
|
| 75 |
-
#endif // #ifndef MATERIAL_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/misc.cpp
DELETED
|
@@ -1,656 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifdef _WIN32
|
| 20 |
-
#if _WIN32_WINNT < 0x0601
|
| 21 |
-
#undef _WIN32_WINNT
|
| 22 |
-
#define _WIN32_WINNT 0x0601 // Force to include needed API prototypes
|
| 23 |
-
#endif
|
| 24 |
-
|
| 25 |
-
#ifndef NOMINMAX
|
| 26 |
-
#define NOMINMAX
|
| 27 |
-
#endif
|
| 28 |
-
|
| 29 |
-
#include <windows.h>
|
| 30 |
-
// The needed Windows API for processor groups could be missed from old Windows
|
| 31 |
-
// versions, so instead of calling them directly (forcing the linker to resolve
|
| 32 |
-
// the calls at compile time), try to load them at runtime. To do this we need
|
| 33 |
-
// first to define the corresponding function pointers.
|
| 34 |
-
extern "C" {
|
| 35 |
-
typedef bool(*fun1_t)(LOGICAL_PROCESSOR_RELATIONSHIP,
|
| 36 |
-
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
|
| 37 |
-
typedef bool(*fun2_t)(USHORT, PGROUP_AFFINITY);
|
| 38 |
-
typedef bool(*fun3_t)(HANDLE, CONST GROUP_AFFINITY*, PGROUP_AFFINITY);
|
| 39 |
-
}
|
| 40 |
-
#endif
|
| 41 |
-
|
| 42 |
-
#include <fstream>
|
| 43 |
-
#include <iomanip>
|
| 44 |
-
#include <iostream>
|
| 45 |
-
#include <sstream>
|
| 46 |
-
#include <vector>
|
| 47 |
-
#include <cstdlib>
|
| 48 |
-
|
| 49 |
-
#if defined(__linux__) && !defined(__ANDROID__)
|
| 50 |
-
#include <stdlib.h>
|
| 51 |
-
#include <sys/mman.h>
|
| 52 |
-
#endif
|
| 53 |
-
|
| 54 |
-
#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) || (defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) && !defined(_WIN32)) || defined(__e2k__)
|
| 55 |
-
#define POSIXALIGNEDALLOC
|
| 56 |
-
#include <stdlib.h>
|
| 57 |
-
#endif
|
| 58 |
-
|
| 59 |
-
#include "misc.h"
|
| 60 |
-
#include "thread.h"
|
| 61 |
-
|
| 62 |
-
using namespace std;
|
| 63 |
-
|
| 64 |
-
namespace Stockfish {
|
| 65 |
-
|
| 66 |
-
namespace {
|
| 67 |
-
|
| 68 |
-
/// Version number. If Version is left empty, then compile date in the format
|
| 69 |
-
/// DD-MM-YY and show in engine_info.
|
| 70 |
-
const string Version = "";
|
| 71 |
-
|
| 72 |
-
/// Our fancy logging facility. The trick here is to replace cin.rdbuf() and
|
| 73 |
-
/// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We
|
| 74 |
-
/// can toggle the logging of std::cout and std:cin at runtime whilst preserving
|
| 75 |
-
/// usual I/O functionality, all without changing a single line of code!
|
| 76 |
-
/// Idea from http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81
|
| 77 |
-
|
| 78 |
-
struct Tie: public streambuf { // MSVC requires split streambuf for cin and cout
|
| 79 |
-
|
| 80 |
-
Tie(streambuf* b, streambuf* l) : buf(b), logBuf(l) {}
|
| 81 |
-
|
| 82 |
-
int sync() override { return logBuf->pubsync(), buf->pubsync(); }
|
| 83 |
-
int overflow(int c) override { return log(buf->sputc((char)c), "<< "); }
|
| 84 |
-
int underflow() override { return buf->sgetc(); }
|
| 85 |
-
int uflow() override { return log(buf->sbumpc(), ">> "); }
|
| 86 |
-
|
| 87 |
-
streambuf *buf, *logBuf;
|
| 88 |
-
|
| 89 |
-
int log(int c, const char* prefix) {
|
| 90 |
-
|
| 91 |
-
static int last = '\n'; // Single log file
|
| 92 |
-
|
| 93 |
-
if (last == '\n')
|
| 94 |
-
logBuf->sputn(prefix, 3);
|
| 95 |
-
|
| 96 |
-
return last = logBuf->sputc((char)c);
|
| 97 |
-
}
|
| 98 |
-
};
|
| 99 |
-
|
| 100 |
-
class Logger {
|
| 101 |
-
|
| 102 |
-
Logger() : in(cin.rdbuf(), file.rdbuf()), out(cout.rdbuf(), file.rdbuf()) {}
|
| 103 |
-
~Logger() { start(""); }
|
| 104 |
-
|
| 105 |
-
ofstream file;
|
| 106 |
-
Tie in, out;
|
| 107 |
-
|
| 108 |
-
public:
|
| 109 |
-
static void start(const std::string& fname) {
|
| 110 |
-
|
| 111 |
-
static Logger l;
|
| 112 |
-
|
| 113 |
-
if (!fname.empty() && !l.file.is_open())
|
| 114 |
-
{
|
| 115 |
-
l.file.open(fname, ifstream::out);
|
| 116 |
-
|
| 117 |
-
if (!l.file.is_open())
|
| 118 |
-
{
|
| 119 |
-
cerr << "Unable to open debug log file " << fname << endl;
|
| 120 |
-
exit(EXIT_FAILURE);
|
| 121 |
-
}
|
| 122 |
-
|
| 123 |
-
cin.rdbuf(&l.in);
|
| 124 |
-
cout.rdbuf(&l.out);
|
| 125 |
-
}
|
| 126 |
-
else if (fname.empty() && l.file.is_open())
|
| 127 |
-
{
|
| 128 |
-
cout.rdbuf(l.out.buf);
|
| 129 |
-
cin.rdbuf(l.in.buf);
|
| 130 |
-
l.file.close();
|
| 131 |
-
}
|
| 132 |
-
}
|
| 133 |
-
};
|
| 134 |
-
|
| 135 |
-
} // namespace
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
/// engine_info() returns the full name of the current Stockfish version. This
|
| 139 |
-
/// will be either "Stockfish <Tag> DD-MM-YY" (where DD-MM-YY is the date when
|
| 140 |
-
/// the program was compiled) or "Stockfish <Version>", depending on whether
|
| 141 |
-
/// Version is empty.
|
| 142 |
-
|
| 143 |
-
string engine_info(bool to_uci, bool to_xboard) {
|
| 144 |
-
|
| 145 |
-
const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
|
| 146 |
-
string month, day, year;
|
| 147 |
-
stringstream ss, date(__DATE__); // From compiler, format is "Sep 21 2008"
|
| 148 |
-
|
| 149 |
-
ss << "Fairy-Stockfish " << Version << setfill('0');
|
| 150 |
-
|
| 151 |
-
if (Version.empty())
|
| 152 |
-
{
|
| 153 |
-
date >> month >> day >> year;
|
| 154 |
-
ss << setw(2) << day << setw(2) << (1 + months.find(month) / 4) << year.substr(2);
|
| 155 |
-
}
|
| 156 |
-
|
| 157 |
-
#ifdef LARGEBOARDS
|
| 158 |
-
ss << " LB";
|
| 159 |
-
#endif
|
| 160 |
-
|
| 161 |
-
if (!to_xboard)
|
| 162 |
-
ss << (to_uci ? "\nid author ": " by ")
|
| 163 |
-
<< "Fabian Fichter";
|
| 164 |
-
|
| 165 |
-
return ss.str();
|
| 166 |
-
}
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
/// compiler_info() returns a string trying to describe the compiler we use
|
| 170 |
-
|
| 171 |
-
std::string compiler_info() {
|
| 172 |
-
|
| 173 |
-
#define stringify2(x) #x
|
| 174 |
-
#define stringify(x) stringify2(x)
|
| 175 |
-
#define make_version_string(major, minor, patch) stringify(major) "." stringify(minor) "." stringify(patch)
|
| 176 |
-
|
| 177 |
-
/// Predefined macros hell:
|
| 178 |
-
///
|
| 179 |
-
/// __GNUC__ Compiler is gcc, Clang or Intel on Linux
|
| 180 |
-
/// __INTEL_COMPILER Compiler is Intel
|
| 181 |
-
/// _MSC_VER Compiler is MSVC or Intel on Windows
|
| 182 |
-
/// _WIN32 Building on Windows (any)
|
| 183 |
-
/// _WIN64 Building on Windows 64 bit
|
| 184 |
-
|
| 185 |
-
std::string compiler = "\nCompiled by ";
|
| 186 |
-
|
| 187 |
-
#ifdef __clang__
|
| 188 |
-
compiler += "clang++ ";
|
| 189 |
-
compiler += make_version_string(__clang_major__, __clang_minor__, __clang_patchlevel__);
|
| 190 |
-
#elif __INTEL_COMPILER
|
| 191 |
-
compiler += "Intel compiler ";
|
| 192 |
-
compiler += "(version ";
|
| 193 |
-
compiler += stringify(__INTEL_COMPILER) " update " stringify(__INTEL_COMPILER_UPDATE);
|
| 194 |
-
compiler += ")";
|
| 195 |
-
#elif _MSC_VER
|
| 196 |
-
compiler += "MSVC ";
|
| 197 |
-
compiler += "(version ";
|
| 198 |
-
compiler += stringify(_MSC_FULL_VER) "." stringify(_MSC_BUILD);
|
| 199 |
-
compiler += ")";
|
| 200 |
-
#elif defined(__e2k__) && defined(__LCC__)
|
| 201 |
-
#define dot_ver2(n) \
|
| 202 |
-
compiler += (char)'.'; \
|
| 203 |
-
compiler += (char)('0' + (n) / 10); \
|
| 204 |
-
compiler += (char)('0' + (n) % 10);
|
| 205 |
-
|
| 206 |
-
compiler += "MCST LCC ";
|
| 207 |
-
compiler += "(version ";
|
| 208 |
-
compiler += std::to_string(__LCC__ / 100);
|
| 209 |
-
dot_ver2(__LCC__ % 100)
|
| 210 |
-
dot_ver2(__LCC_MINOR__)
|
| 211 |
-
compiler += ")";
|
| 212 |
-
#elif __GNUC__
|
| 213 |
-
compiler += "g++ (GNUC) ";
|
| 214 |
-
compiler += make_version_string(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
|
| 215 |
-
#else
|
| 216 |
-
compiler += "Unknown compiler ";
|
| 217 |
-
compiler += "(unknown version)";
|
| 218 |
-
#endif
|
| 219 |
-
|
| 220 |
-
#if defined(__APPLE__)
|
| 221 |
-
compiler += " on Apple";
|
| 222 |
-
#elif defined(__CYGWIN__)
|
| 223 |
-
compiler += " on Cygwin";
|
| 224 |
-
#elif defined(__MINGW64__)
|
| 225 |
-
compiler += " on MinGW64";
|
| 226 |
-
#elif defined(__MINGW32__)
|
| 227 |
-
compiler += " on MinGW32";
|
| 228 |
-
#elif defined(__ANDROID__)
|
| 229 |
-
compiler += " on Android";
|
| 230 |
-
#elif defined(__linux__)
|
| 231 |
-
compiler += " on Linux";
|
| 232 |
-
#elif defined(_WIN64)
|
| 233 |
-
compiler += " on Microsoft Windows 64-bit";
|
| 234 |
-
#elif defined(_WIN32)
|
| 235 |
-
compiler += " on Microsoft Windows 32-bit";
|
| 236 |
-
#else
|
| 237 |
-
compiler += " on unknown system";
|
| 238 |
-
#endif
|
| 239 |
-
|
| 240 |
-
compiler += "\nCompilation settings include: ";
|
| 241 |
-
compiler += (Is64Bit ? " 64bit" : " 32bit");
|
| 242 |
-
#if defined(USE_VNNI)
|
| 243 |
-
compiler += " VNNI";
|
| 244 |
-
#endif
|
| 245 |
-
#if defined(USE_AVX512)
|
| 246 |
-
compiler += " AVX512";
|
| 247 |
-
#endif
|
| 248 |
-
compiler += (HasPext ? " BMI2" : "");
|
| 249 |
-
#if defined(USE_AVX2)
|
| 250 |
-
compiler += " AVX2";
|
| 251 |
-
#endif
|
| 252 |
-
#if defined(USE_SSE41)
|
| 253 |
-
compiler += " SSE41";
|
| 254 |
-
#endif
|
| 255 |
-
#if defined(USE_SSSE3)
|
| 256 |
-
compiler += " SSSE3";
|
| 257 |
-
#endif
|
| 258 |
-
#if defined(USE_SSE2)
|
| 259 |
-
compiler += " SSE2";
|
| 260 |
-
#endif
|
| 261 |
-
compiler += (HasPopCnt ? " POPCNT" : "");
|
| 262 |
-
#if defined(USE_MMX)
|
| 263 |
-
compiler += " MMX";
|
| 264 |
-
#endif
|
| 265 |
-
#if defined(USE_NEON)
|
| 266 |
-
compiler += " NEON";
|
| 267 |
-
#endif
|
| 268 |
-
|
| 269 |
-
#if !defined(NDEBUG)
|
| 270 |
-
compiler += " DEBUG";
|
| 271 |
-
#endif
|
| 272 |
-
|
| 273 |
-
compiler += "\n__VERSION__ macro expands to: ";
|
| 274 |
-
#ifdef __VERSION__
|
| 275 |
-
compiler += __VERSION__;
|
| 276 |
-
#else
|
| 277 |
-
compiler += "(undefined macro)";
|
| 278 |
-
#endif
|
| 279 |
-
compiler += "\n";
|
| 280 |
-
|
| 281 |
-
return compiler;
|
| 282 |
-
}
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
/// Debug functions used mainly to collect run-time statistics
|
| 286 |
-
static std::atomic<int64_t> hits[2], means[2];
|
| 287 |
-
|
| 288 |
-
void dbg_hit_on(bool b) { ++hits[0]; if (b) ++hits[1]; }
|
| 289 |
-
void dbg_hit_on(bool c, bool b) { if (c) dbg_hit_on(b); }
|
| 290 |
-
void dbg_mean_of(int v) { ++means[0]; means[1] += v; }
|
| 291 |
-
|
| 292 |
-
void dbg_print() {
|
| 293 |
-
|
| 294 |
-
if (hits[0])
|
| 295 |
-
cerr << "Total " << hits[0] << " Hits " << hits[1]
|
| 296 |
-
<< " hit rate (%) " << 100 * hits[1] / hits[0] << endl;
|
| 297 |
-
|
| 298 |
-
if (means[0])
|
| 299 |
-
cerr << "Total " << means[0] << " Mean "
|
| 300 |
-
<< (double)means[1] / means[0] << endl;
|
| 301 |
-
}
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
/// Used to serialize access to std::cout to avoid multiple threads writing at
|
| 305 |
-
/// the same time.
|
| 306 |
-
|
| 307 |
-
std::ostream& operator<<(std::ostream& os, SyncCout sc) {
|
| 308 |
-
|
| 309 |
-
static std::mutex m;
|
| 310 |
-
|
| 311 |
-
if (sc == IO_LOCK)
|
| 312 |
-
m.lock();
|
| 313 |
-
|
| 314 |
-
if (sc == IO_UNLOCK)
|
| 315 |
-
m.unlock();
|
| 316 |
-
|
| 317 |
-
return os;
|
| 318 |
-
}
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
/// Trampoline helper to avoid moving Logger to misc.h
|
| 322 |
-
void start_logger(const std::string& fname) { Logger::start(fname); }
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
/// prefetch() preloads the given address in L1/L2 cache. This is a non-blocking
|
| 326 |
-
/// function that doesn't stall the CPU waiting for data to be loaded from memory,
|
| 327 |
-
/// which can be quite slow.
|
| 328 |
-
#ifdef NO_PREFETCH
|
| 329 |
-
|
| 330 |
-
void prefetch(void*) {}
|
| 331 |
-
|
| 332 |
-
#else
|
| 333 |
-
|
| 334 |
-
void prefetch(void* addr) {
|
| 335 |
-
|
| 336 |
-
# if defined(__INTEL_COMPILER)
|
| 337 |
-
// This hack prevents prefetches from being optimized away by
|
| 338 |
-
// Intel compiler. Both MSVC and gcc seem not be affected by this.
|
| 339 |
-
__asm__ ("");
|
| 340 |
-
# endif
|
| 341 |
-
|
| 342 |
-
# if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
| 343 |
-
_mm_prefetch((char*)addr, _MM_HINT_T0);
|
| 344 |
-
# else
|
| 345 |
-
__builtin_prefetch(addr);
|
| 346 |
-
# endif
|
| 347 |
-
}
|
| 348 |
-
|
| 349 |
-
#endif
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
/// std_aligned_alloc() is our wrapper for systems where the c++17 implementation
|
| 353 |
-
/// does not guarantee the availability of aligned_alloc(). Memory allocated with
|
| 354 |
-
/// std_aligned_alloc() must be freed with std_aligned_free().
|
| 355 |
-
|
| 356 |
-
void* std_aligned_alloc(size_t alignment, size_t size) {
|
| 357 |
-
|
| 358 |
-
#if defined(POSIXALIGNEDALLOC)
|
| 359 |
-
void *mem;
|
| 360 |
-
return posix_memalign(&mem, alignment, size) ? nullptr : mem;
|
| 361 |
-
#elif defined(_WIN32)
|
| 362 |
-
return _mm_malloc(size, alignment);
|
| 363 |
-
#else
|
| 364 |
-
return aligned_alloc(alignment, size);
|
| 365 |
-
#endif
|
| 366 |
-
}
|
| 367 |
-
|
| 368 |
-
void std_aligned_free(void* ptr) {
|
| 369 |
-
|
| 370 |
-
#if defined(POSIXALIGNEDALLOC)
|
| 371 |
-
free(ptr);
|
| 372 |
-
#elif defined(_WIN32)
|
| 373 |
-
_mm_free(ptr);
|
| 374 |
-
#else
|
| 375 |
-
free(ptr);
|
| 376 |
-
#endif
|
| 377 |
-
}
|
| 378 |
-
|
| 379 |
-
/// aligned_large_pages_alloc() will return suitably aligned memory, if possible using large pages.
|
| 380 |
-
|
| 381 |
-
#if defined(_WIN32)
|
| 382 |
-
|
| 383 |
-
static void* aligned_large_pages_alloc_windows(size_t allocSize) {
|
| 384 |
-
|
| 385 |
-
#if !defined(_WIN64)
|
| 386 |
-
return nullptr;
|
| 387 |
-
#else
|
| 388 |
-
|
| 389 |
-
HANDLE hProcessToken { };
|
| 390 |
-
LUID luid { };
|
| 391 |
-
void* mem = nullptr;
|
| 392 |
-
|
| 393 |
-
const size_t largePageSize = GetLargePageMinimum();
|
| 394 |
-
if (!largePageSize)
|
| 395 |
-
return nullptr;
|
| 396 |
-
|
| 397 |
-
// We need SeLockMemoryPrivilege, so try to enable it for the process
|
| 398 |
-
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken))
|
| 399 |
-
return nullptr;
|
| 400 |
-
|
| 401 |
-
if (LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luid))
|
| 402 |
-
{
|
| 403 |
-
TOKEN_PRIVILEGES tp { };
|
| 404 |
-
TOKEN_PRIVILEGES prevTp { };
|
| 405 |
-
DWORD prevTpLen = 0;
|
| 406 |
-
|
| 407 |
-
tp.PrivilegeCount = 1;
|
| 408 |
-
tp.Privileges[0].Luid = luid;
|
| 409 |
-
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
| 410 |
-
|
| 411 |
-
// Try to enable SeLockMemoryPrivilege. Note that even if AdjustTokenPrivileges() succeeds,
|
| 412 |
-
// we still need to query GetLastError() to ensure that the privileges were actually obtained.
|
| 413 |
-
if (AdjustTokenPrivileges(
|
| 414 |
-
hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &prevTp, &prevTpLen) &&
|
| 415 |
-
GetLastError() == ERROR_SUCCESS)
|
| 416 |
-
{
|
| 417 |
-
// Round up size to full pages and allocate
|
| 418 |
-
allocSize = (allocSize + largePageSize - 1) & ~size_t(largePageSize - 1);
|
| 419 |
-
mem = VirtualAlloc(
|
| 420 |
-
NULL, allocSize, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
| 421 |
-
|
| 422 |
-
// Privilege no longer needed, restore previous state
|
| 423 |
-
AdjustTokenPrivileges(hProcessToken, FALSE, &prevTp, 0, NULL, NULL);
|
| 424 |
-
}
|
| 425 |
-
}
|
| 426 |
-
|
| 427 |
-
CloseHandle(hProcessToken);
|
| 428 |
-
|
| 429 |
-
return mem;
|
| 430 |
-
|
| 431 |
-
#endif
|
| 432 |
-
}
|
| 433 |
-
|
| 434 |
-
void* aligned_large_pages_alloc(size_t allocSize) {
|
| 435 |
-
|
| 436 |
-
// Try to allocate large pages
|
| 437 |
-
void* mem = aligned_large_pages_alloc_windows(allocSize);
|
| 438 |
-
|
| 439 |
-
// Fall back to regular, page aligned, allocation if necessary
|
| 440 |
-
if (!mem)
|
| 441 |
-
mem = VirtualAlloc(NULL, allocSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
| 442 |
-
|
| 443 |
-
return mem;
|
| 444 |
-
}
|
| 445 |
-
|
| 446 |
-
#else
|
| 447 |
-
|
| 448 |
-
void* aligned_large_pages_alloc(size_t allocSize) {
|
| 449 |
-
|
| 450 |
-
#if defined(__linux__)
|
| 451 |
-
constexpr size_t alignment = 2 * 1024 * 1024; // assumed 2MB page size
|
| 452 |
-
#else
|
| 453 |
-
constexpr size_t alignment = 4096; // assumed small page size
|
| 454 |
-
#endif
|
| 455 |
-
|
| 456 |
-
// round up to multiples of alignment
|
| 457 |
-
size_t size = ((allocSize + alignment - 1) / alignment) * alignment;
|
| 458 |
-
void *mem = std_aligned_alloc(alignment, size);
|
| 459 |
-
#if defined(MADV_HUGEPAGE)
|
| 460 |
-
madvise(mem, size, MADV_HUGEPAGE);
|
| 461 |
-
#endif
|
| 462 |
-
return mem;
|
| 463 |
-
}
|
| 464 |
-
|
| 465 |
-
#endif
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
/// aligned_large_pages_free() will free the previously allocated ttmem
|
| 469 |
-
|
| 470 |
-
#if defined(_WIN32)
|
| 471 |
-
|
| 472 |
-
void aligned_large_pages_free(void* mem) {
|
| 473 |
-
|
| 474 |
-
if (mem && !VirtualFree(mem, 0, MEM_RELEASE))
|
| 475 |
-
{
|
| 476 |
-
DWORD err = GetLastError();
|
| 477 |
-
std::cerr << "Failed to free large page memory. Error code: 0x"
|
| 478 |
-
<< std::hex << err
|
| 479 |
-
<< std::dec << std::endl;
|
| 480 |
-
exit(EXIT_FAILURE);
|
| 481 |
-
}
|
| 482 |
-
}
|
| 483 |
-
|
| 484 |
-
#else
|
| 485 |
-
|
| 486 |
-
void aligned_large_pages_free(void *mem) {
|
| 487 |
-
std_aligned_free(mem);
|
| 488 |
-
}
|
| 489 |
-
|
| 490 |
-
#endif
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
namespace WinProcGroup {
|
| 494 |
-
|
| 495 |
-
#ifndef _WIN32
|
| 496 |
-
|
| 497 |
-
void bindThisThread(size_t) {}
|
| 498 |
-
|
| 499 |
-
#else
|
| 500 |
-
|
| 501 |
-
/// best_group() retrieves logical processor information using Windows specific
|
| 502 |
-
/// API and returns the best group id for the thread with index idx. Original
|
| 503 |
-
/// code from Texel by Peter Österlund.
|
| 504 |
-
|
| 505 |
-
int best_group(size_t idx) {
|
| 506 |
-
|
| 507 |
-
int threads = 0;
|
| 508 |
-
int nodes = 0;
|
| 509 |
-
int cores = 0;
|
| 510 |
-
DWORD returnLength = 0;
|
| 511 |
-
DWORD byteOffset = 0;
|
| 512 |
-
|
| 513 |
-
// Early exit if the needed API is not available at runtime
|
| 514 |
-
HMODULE k32 = GetModuleHandle("Kernel32.dll");
|
| 515 |
-
auto fun1 = (fun1_t)(void(*)())GetProcAddress(k32, "GetLogicalProcessorInformationEx");
|
| 516 |
-
if (!fun1)
|
| 517 |
-
return -1;
|
| 518 |
-
|
| 519 |
-
// First call to get returnLength. We expect it to fail due to null buffer
|
| 520 |
-
if (fun1(RelationAll, nullptr, &returnLength))
|
| 521 |
-
return -1;
|
| 522 |
-
|
| 523 |
-
// Once we know returnLength, allocate the buffer
|
| 524 |
-
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buffer, *ptr;
|
| 525 |
-
ptr = buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(returnLength);
|
| 526 |
-
|
| 527 |
-
// Second call, now we expect to succeed
|
| 528 |
-
if (!fun1(RelationAll, buffer, &returnLength))
|
| 529 |
-
{
|
| 530 |
-
free(buffer);
|
| 531 |
-
return -1;
|
| 532 |
-
}
|
| 533 |
-
|
| 534 |
-
while (byteOffset < returnLength)
|
| 535 |
-
{
|
| 536 |
-
if (ptr->Relationship == RelationNumaNode)
|
| 537 |
-
nodes++;
|
| 538 |
-
|
| 539 |
-
else if (ptr->Relationship == RelationProcessorCore)
|
| 540 |
-
{
|
| 541 |
-
cores++;
|
| 542 |
-
threads += (ptr->Processor.Flags == LTP_PC_SMT) ? 2 : 1;
|
| 543 |
-
}
|
| 544 |
-
|
| 545 |
-
assert(ptr->Size);
|
| 546 |
-
byteOffset += ptr->Size;
|
| 547 |
-
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size);
|
| 548 |
-
}
|
| 549 |
-
|
| 550 |
-
free(buffer);
|
| 551 |
-
|
| 552 |
-
std::vector<int> groups;
|
| 553 |
-
|
| 554 |
-
// Run as many threads as possible on the same node until core limit is
|
| 555 |
-
// reached, then move on filling the next node.
|
| 556 |
-
for (int n = 0; n < nodes; n++)
|
| 557 |
-
for (int i = 0; i < cores / nodes; i++)
|
| 558 |
-
groups.push_back(n);
|
| 559 |
-
|
| 560 |
-
// In case a core has more than one logical processor (we assume 2) and we
|
| 561 |
-
// have still threads to allocate, then spread them evenly across available
|
| 562 |
-
// nodes.
|
| 563 |
-
for (int t = 0; t < threads - cores; t++)
|
| 564 |
-
groups.push_back(t % nodes);
|
| 565 |
-
|
| 566 |
-
// If we still have more threads than the total number of logical processors
|
| 567 |
-
// then return -1 and let the OS to decide what to do.
|
| 568 |
-
return idx < groups.size() ? groups[idx] : -1;
|
| 569 |
-
}
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
/// bindThisThread() set the group affinity of the current thread
|
| 573 |
-
|
| 574 |
-
void bindThisThread(size_t idx) {
|
| 575 |
-
|
| 576 |
-
// Use only local variables to be thread-safe
|
| 577 |
-
int group = best_group(idx);
|
| 578 |
-
|
| 579 |
-
if (group == -1)
|
| 580 |
-
return;
|
| 581 |
-
|
| 582 |
-
// Early exit if the needed API are not available at runtime
|
| 583 |
-
HMODULE k32 = GetModuleHandle("Kernel32.dll");
|
| 584 |
-
auto fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx");
|
| 585 |
-
auto fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity");
|
| 586 |
-
|
| 587 |
-
if (!fun2 || !fun3)
|
| 588 |
-
return;
|
| 589 |
-
|
| 590 |
-
GROUP_AFFINITY affinity;
|
| 591 |
-
if (fun2(group, &affinity))
|
| 592 |
-
fun3(GetCurrentThread(), &affinity, nullptr);
|
| 593 |
-
}
|
| 594 |
-
|
| 595 |
-
#endif
|
| 596 |
-
|
| 597 |
-
} // namespace WinProcGroup
|
| 598 |
-
|
| 599 |
-
#ifdef _WIN32
|
| 600 |
-
#include <direct.h>
|
| 601 |
-
#define GETCWD _getcwd
|
| 602 |
-
#else
|
| 603 |
-
#include <unistd.h>
|
| 604 |
-
#define GETCWD getcwd
|
| 605 |
-
#endif
|
| 606 |
-
|
| 607 |
-
namespace CommandLine {
|
| 608 |
-
|
| 609 |
-
string argv0; // path+name of the executable binary, as given by argv[0]
|
| 610 |
-
string binaryDirectory; // path of the executable directory
|
| 611 |
-
string workingDirectory; // path of the working directory
|
| 612 |
-
|
| 613 |
-
void init(int argc, char* argv[]) {
|
| 614 |
-
(void)argc;
|
| 615 |
-
string pathSeparator;
|
| 616 |
-
|
| 617 |
-
// extract the path+name of the executable binary
|
| 618 |
-
argv0 = argv[0];
|
| 619 |
-
|
| 620 |
-
#ifdef _WIN32
|
| 621 |
-
pathSeparator = "\\";
|
| 622 |
-
#ifdef _MSC_VER
|
| 623 |
-
// Under windows argv[0] may not have the extension. Also _get_pgmptr() had
|
| 624 |
-
// issues in some windows 10 versions, so check returned values carefully.
|
| 625 |
-
char* pgmptr = nullptr;
|
| 626 |
-
if (!_get_pgmptr(&pgmptr) && pgmptr != nullptr && *pgmptr)
|
| 627 |
-
argv0 = pgmptr;
|
| 628 |
-
#endif
|
| 629 |
-
#else
|
| 630 |
-
pathSeparator = "/";
|
| 631 |
-
#endif
|
| 632 |
-
|
| 633 |
-
// extract the working directory
|
| 634 |
-
workingDirectory = "";
|
| 635 |
-
char buff[40000];
|
| 636 |
-
char* cwd = GETCWD(buff, 40000);
|
| 637 |
-
if (cwd)
|
| 638 |
-
workingDirectory = cwd;
|
| 639 |
-
|
| 640 |
-
// extract the binary directory path from argv0
|
| 641 |
-
binaryDirectory = argv0;
|
| 642 |
-
size_t pos = binaryDirectory.find_last_of("\\/");
|
| 643 |
-
if (pos == std::string::npos)
|
| 644 |
-
binaryDirectory = "." + pathSeparator;
|
| 645 |
-
else
|
| 646 |
-
binaryDirectory.resize(pos + 1);
|
| 647 |
-
|
| 648 |
-
// pattern replacement: "./" at the start of path is replaced by the working directory
|
| 649 |
-
if (binaryDirectory.find("." + pathSeparator) == 0)
|
| 650 |
-
binaryDirectory.replace(0, 1, workingDirectory);
|
| 651 |
-
}
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
} // namespace CommandLine
|
| 655 |
-
|
| 656 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/misc.h
DELETED
|
@@ -1,200 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef MISC_H_INCLUDED
|
| 20 |
-
#define MISC_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <cassert>
|
| 23 |
-
#include <chrono>
|
| 24 |
-
#include <ostream>
|
| 25 |
-
#include <string>
|
| 26 |
-
#include <vector>
|
| 27 |
-
#include <cstdint>
|
| 28 |
-
|
| 29 |
-
#include "types.h"
|
| 30 |
-
|
| 31 |
-
namespace Stockfish {
|
| 32 |
-
|
| 33 |
-
std::string engine_info(bool to_uci = false, bool to_xboard = false);
|
| 34 |
-
std::string compiler_info();
|
| 35 |
-
void prefetch(void* addr);
|
| 36 |
-
void start_logger(const std::string& fname);
|
| 37 |
-
void* std_aligned_alloc(size_t alignment, size_t size);
|
| 38 |
-
void std_aligned_free(void* ptr);
|
| 39 |
-
void* aligned_large_pages_alloc(size_t size); // memory aligned by page size, min alignment: 4096 bytes
|
| 40 |
-
void aligned_large_pages_free(void* mem); // nop if mem == nullptr
|
| 41 |
-
|
| 42 |
-
void dbg_hit_on(bool b);
|
| 43 |
-
void dbg_hit_on(bool c, bool b);
|
| 44 |
-
void dbg_mean_of(int v);
|
| 45 |
-
void dbg_print();
|
| 46 |
-
|
| 47 |
-
typedef std::chrono::milliseconds::rep TimePoint; // A value in milliseconds
|
| 48 |
-
static_assert(sizeof(TimePoint) == sizeof(int64_t), "TimePoint should be 64 bits");
|
| 49 |
-
inline TimePoint now() {
|
| 50 |
-
return std::chrono::duration_cast<std::chrono::milliseconds>
|
| 51 |
-
(std::chrono::steady_clock::now().time_since_epoch()).count();
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
template<class Entry, int Size>
|
| 55 |
-
struct HashTable {
|
| 56 |
-
Entry* operator[](Key key) { return &table[(uint32_t)key & (Size - 1)]; }
|
| 57 |
-
|
| 58 |
-
private:
|
| 59 |
-
std::vector<Entry> table = std::vector<Entry>(Size); // Allocate on the heap
|
| 60 |
-
};
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
enum SyncCout { IO_LOCK, IO_UNLOCK };
|
| 64 |
-
std::ostream& operator<<(std::ostream&, SyncCout);
|
| 65 |
-
|
| 66 |
-
#define sync_cout std::cout << IO_LOCK
|
| 67 |
-
#define sync_endl std::endl << IO_UNLOCK
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
// align_ptr_up() : get the first aligned element of an array.
|
| 71 |
-
// ptr must point to an array of size at least `sizeof(T) * N + alignment` bytes,
|
| 72 |
-
// where N is the number of elements in the array.
|
| 73 |
-
template <uintptr_t Alignment, typename T>
|
| 74 |
-
T* align_ptr_up(T* ptr)
|
| 75 |
-
{
|
| 76 |
-
static_assert(alignof(T) < Alignment);
|
| 77 |
-
|
| 78 |
-
const uintptr_t ptrint = reinterpret_cast<uintptr_t>(reinterpret_cast<char*>(ptr));
|
| 79 |
-
return reinterpret_cast<T*>(reinterpret_cast<char*>((ptrint + (Alignment - 1)) / Alignment * Alignment));
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
// IsLittleEndian : true if and only if the binary is compiled on a little endian machine
|
| 84 |
-
static inline const union { uint32_t i; char c[4]; } Le = { 0x01020304 };
|
| 85 |
-
static inline const bool IsLittleEndian = (Le.c[0] == 4);
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
template <typename T>
|
| 89 |
-
class ValueListInserter {
|
| 90 |
-
public:
|
| 91 |
-
ValueListInserter(T* v, std::size_t& s) :
|
| 92 |
-
values(v),
|
| 93 |
-
size(&s)
|
| 94 |
-
{
|
| 95 |
-
}
|
| 96 |
-
|
| 97 |
-
void push_back(const T& value) { values[(*size)++] = value; }
|
| 98 |
-
private:
|
| 99 |
-
T* values;
|
| 100 |
-
std::size_t* size;
|
| 101 |
-
};
|
| 102 |
-
|
| 103 |
-
template <typename T, std::size_t MaxSize>
|
| 104 |
-
class ValueList {
|
| 105 |
-
|
| 106 |
-
public:
|
| 107 |
-
std::size_t size() const { return size_; }
|
| 108 |
-
void resize(std::size_t newSize) { size_ = newSize; }
|
| 109 |
-
void push_back(const T& value) { values_[size_++] = value; }
|
| 110 |
-
T& operator[](std::size_t index) { return values_[index]; }
|
| 111 |
-
T* begin() { return values_; }
|
| 112 |
-
T* end() { return values_ + size_; }
|
| 113 |
-
const T& operator[](std::size_t index) const { return values_[index]; }
|
| 114 |
-
const T* begin() const { return values_; }
|
| 115 |
-
const T* end() const { return values_ + size_; }
|
| 116 |
-
operator ValueListInserter<T>() { return ValueListInserter(values_, size_); }
|
| 117 |
-
|
| 118 |
-
void swap(ValueList& other) {
|
| 119 |
-
const std::size_t maxSize = std::max(size_, other.size_);
|
| 120 |
-
for (std::size_t i = 0; i < maxSize; ++i) {
|
| 121 |
-
std::swap(values_[i], other.values_[i]);
|
| 122 |
-
}
|
| 123 |
-
std::swap(size_, other.size_);
|
| 124 |
-
}
|
| 125 |
-
|
| 126 |
-
private:
|
| 127 |
-
T values_[MaxSize];
|
| 128 |
-
std::size_t size_ = 0;
|
| 129 |
-
};
|
| 130 |
-
|
| 131 |
-
/// xorshift64star Pseudo-Random Number Generator
|
| 132 |
-
/// This class is based on original code written and dedicated
|
| 133 |
-
/// to the public domain by Sebastiano Vigna (2014).
|
| 134 |
-
/// It has the following characteristics:
|
| 135 |
-
///
|
| 136 |
-
/// - Outputs 64-bit numbers
|
| 137 |
-
/// - Passes Dieharder and SmallCrush test batteries
|
| 138 |
-
/// - Does not require warm-up, no zeroland to escape
|
| 139 |
-
/// - Internal state is a single 64-bit integer
|
| 140 |
-
/// - Period is 2^64 - 1
|
| 141 |
-
/// - Speed: 1.60 ns/call (Core i7 @3.40GHz)
|
| 142 |
-
///
|
| 143 |
-
/// For further analysis see
|
| 144 |
-
/// <http://vigna.di.unimi.it/ftp/papers/xorshift.pdf>
|
| 145 |
-
|
| 146 |
-
class PRNG {
|
| 147 |
-
|
| 148 |
-
uint64_t s;
|
| 149 |
-
|
| 150 |
-
uint64_t rand64() {
|
| 151 |
-
|
| 152 |
-
s ^= s >> 12, s ^= s << 25, s ^= s >> 27;
|
| 153 |
-
return s * 2685821657736338717LL;
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
public:
|
| 157 |
-
PRNG(uint64_t seed) : s(seed) { assert(seed); }
|
| 158 |
-
|
| 159 |
-
template<typename T> T rand() { return T(rand64()); }
|
| 160 |
-
|
| 161 |
-
/// Special generator used to fast init magic numbers.
|
| 162 |
-
/// Output values only have 1/8th of their bits set on average.
|
| 163 |
-
template<typename T> T sparse_rand()
|
| 164 |
-
{ return T(rand64() & rand64() & rand64()); }
|
| 165 |
-
};
|
| 166 |
-
|
| 167 |
-
inline uint64_t mul_hi64(uint64_t a, uint64_t b) {
|
| 168 |
-
#if defined(__GNUC__) && defined(IS_64BIT)
|
| 169 |
-
__extension__ typedef unsigned __int128 uint128;
|
| 170 |
-
return ((uint128)a * (uint128)b) >> 64;
|
| 171 |
-
#else
|
| 172 |
-
uint64_t aL = (uint32_t)a, aH = a >> 32;
|
| 173 |
-
uint64_t bL = (uint32_t)b, bH = b >> 32;
|
| 174 |
-
uint64_t c1 = (aL * bL) >> 32;
|
| 175 |
-
uint64_t c2 = aH * bL + c1;
|
| 176 |
-
uint64_t c3 = aL * bH + (uint32_t)c2;
|
| 177 |
-
return aH * bH + (c2 >> 32) + (c3 >> 32);
|
| 178 |
-
#endif
|
| 179 |
-
}
|
| 180 |
-
|
| 181 |
-
/// Under Windows it is not possible for a process to run on more than one
|
| 182 |
-
/// logical processor group. This usually means to be limited to use max 64
|
| 183 |
-
/// cores. To overcome this, some special platform specific API should be
|
| 184 |
-
/// called to set group affinity for each thread. Original code from Texel by
|
| 185 |
-
/// Peter Österlund.
|
| 186 |
-
|
| 187 |
-
namespace WinProcGroup {
|
| 188 |
-
void bindThisThread(size_t idx);
|
| 189 |
-
}
|
| 190 |
-
|
| 191 |
-
namespace CommandLine {
|
| 192 |
-
void init(int argc, char* argv[]);
|
| 193 |
-
|
| 194 |
-
extern std::string binaryDirectory; // path of the executable directory
|
| 195 |
-
extern std::string workingDirectory; // path of the working directory
|
| 196 |
-
}
|
| 197 |
-
|
| 198 |
-
} // namespace Stockfish
|
| 199 |
-
|
| 200 |
-
#endif // #ifndef MISC_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/movegen.cpp
DELETED
|
@@ -1,528 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <cassert>
|
| 20 |
-
|
| 21 |
-
#include "movegen.h"
|
| 22 |
-
#include "position.h"
|
| 23 |
-
|
| 24 |
-
namespace Stockfish {
|
| 25 |
-
|
| 26 |
-
namespace {
|
| 27 |
-
|
| 28 |
-
template<MoveType T>
|
| 29 |
-
ExtMove* make_move_and_gating(const Position& pos, ExtMove* moveList, Color us, Square from, Square to, PieceType pt = NO_PIECE_TYPE) {
|
| 30 |
-
|
| 31 |
-
// Wall placing moves
|
| 32 |
-
//if it's "wall or move", and they chose non-null move, skip even generating wall move
|
| 33 |
-
if (pos.walling() && !(pos.wall_or_move() && (from!=to)))
|
| 34 |
-
{
|
| 35 |
-
Bitboard b = pos.board_bb() & ~((pos.pieces() ^ from) | to);
|
| 36 |
-
if (T == CASTLING)
|
| 37 |
-
{
|
| 38 |
-
Square kto = make_square(to > from ? pos.castling_kingside_file() : pos.castling_queenside_file(), pos.castling_rank(us));
|
| 39 |
-
Direction step = kto > from ? EAST : WEST;
|
| 40 |
-
Square rto = kto - step;
|
| 41 |
-
b ^= square_bb(to) ^ kto ^ rto;
|
| 42 |
-
}
|
| 43 |
-
if (T == EN_PASSANT)
|
| 44 |
-
b ^= pos.capture_square(to);
|
| 45 |
-
|
| 46 |
-
if (pos.walling_rule() == ARROW)
|
| 47 |
-
b &= moves_bb(us, type_of(pos.piece_on(from)), to, pos.pieces() ^ from);
|
| 48 |
-
|
| 49 |
-
//Any current or future wall variant must follow the walling region rule if set:
|
| 50 |
-
b &= pos.walling_region(us);
|
| 51 |
-
|
| 52 |
-
if (pos.walling_rule() == PAST)
|
| 53 |
-
b &= square_bb(from);
|
| 54 |
-
if (pos.walling_rule() == EDGE)
|
| 55 |
-
{
|
| 56 |
-
Bitboard wallsquares = pos.state()->wallSquares;
|
| 57 |
-
|
| 58 |
-
b &= (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) |
|
| 59 |
-
( shift<NORTH >(wallsquares) | shift<SOUTH >(wallsquares)
|
| 60 |
-
| shift<EAST >(wallsquares) | shift<WEST >(wallsquares));
|
| 61 |
-
}
|
| 62 |
-
while (b)
|
| 63 |
-
*moveList++ = make_gating<T>(from, to, pt, pop_lsb(b));
|
| 64 |
-
return moveList;
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
*moveList++ = make<T>(from, to, pt);
|
| 68 |
-
|
| 69 |
-
// Gating moves
|
| 70 |
-
if (pos.seirawan_gating() && (pos.gates(us) & from))
|
| 71 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 72 |
-
{
|
| 73 |
-
PieceType pt_gating = pop_lsb(ps);
|
| 74 |
-
if (pos.can_drop(us, pt_gating) && (pos.drop_region(us, pt_gating) & from))
|
| 75 |
-
*moveList++ = make_gating<T>(from, to, pt_gating, from);
|
| 76 |
-
}
|
| 77 |
-
if (pos.seirawan_gating() && T == CASTLING && (pos.gates(us) & to))
|
| 78 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 79 |
-
{
|
| 80 |
-
PieceType pt_gating = pop_lsb(ps);
|
| 81 |
-
if (pos.can_drop(us, pt_gating) && (pos.drop_region(us, pt_gating) & to))
|
| 82 |
-
*moveList++ = make_gating<T>(from, to, pt_gating, to);
|
| 83 |
-
}
|
| 84 |
-
|
| 85 |
-
return moveList;
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
template<Color c, GenType Type, Direction D>
|
| 89 |
-
ExtMove* make_promotions(const Position& pos, ExtMove* moveList, Square to) {
|
| 90 |
-
|
| 91 |
-
if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
|
| 92 |
-
{
|
| 93 |
-
for (PieceSet promotions = pos.promotion_piece_types(c); promotions;)
|
| 94 |
-
{
|
| 95 |
-
PieceType pt = pop_msb(promotions);
|
| 96 |
-
if (!pos.promotion_limit(pt) || pos.promotion_limit(pt) > pos.count(c, pt))
|
| 97 |
-
moveList = make_move_and_gating<PROMOTION>(pos, moveList, pos.side_to_move(), to - D, to, pt);
|
| 98 |
-
}
|
| 99 |
-
PieceType pt = pos.promoted_piece_type(PAWN);
|
| 100 |
-
if (pt && !(pos.piece_promotion_on_capture() && pos.empty(to)))
|
| 101 |
-
moveList = make_move_and_gating<PIECE_PROMOTION>(pos, moveList, pos.side_to_move(), to - D, to);
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
return moveList;
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
-
template<Color Us, GenType Type>
|
| 108 |
-
ExtMove* generate_drops(const Position& pos, ExtMove* moveList, PieceType pt, Bitboard b) {
|
| 109 |
-
assert(Type != CAPTURES);
|
| 110 |
-
// Do not generate virtual drops for perft and at root
|
| 111 |
-
if (pos.can_drop(Us, pt) || (Type != NON_EVASIONS && pos.two_boards() && pos.allow_virtual_drop(Us, pt)))
|
| 112 |
-
{
|
| 113 |
-
// Restrict to valid target
|
| 114 |
-
b &= pos.drop_region(Us, pt);
|
| 115 |
-
|
| 116 |
-
// Add to move list
|
| 117 |
-
if (pos.drop_promoted() && pos.promoted_piece_type(pt))
|
| 118 |
-
{
|
| 119 |
-
Bitboard b2 = b;
|
| 120 |
-
if (Type == QUIET_CHECKS)
|
| 121 |
-
b2 &= pos.check_squares(pos.promoted_piece_type(pt));
|
| 122 |
-
while (b2)
|
| 123 |
-
*moveList++ = make_drop(pop_lsb(b2), pt, pos.promoted_piece_type(pt));
|
| 124 |
-
}
|
| 125 |
-
if (Type == QUIET_CHECKS || !pos.can_drop(Us, pt))
|
| 126 |
-
b &= pos.check_squares(pt);
|
| 127 |
-
while (b)
|
| 128 |
-
*moveList++ = make_drop(pop_lsb(b), pt, pt);
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
return moveList;
|
| 132 |
-
}
|
| 133 |
-
|
| 134 |
-
template<Color Us, GenType Type>
|
| 135 |
-
ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard target) {
|
| 136 |
-
|
| 137 |
-
if (!pos.pieces(Us, PAWN))
|
| 138 |
-
return moveList;
|
| 139 |
-
|
| 140 |
-
constexpr Color Them = ~Us;
|
| 141 |
-
constexpr Direction Up = pawn_push(Us);
|
| 142 |
-
constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
|
| 143 |
-
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
|
| 144 |
-
|
| 145 |
-
const Bitboard promotionZone = pos.promotion_zone(Us);
|
| 146 |
-
const Bitboard standardPromotionZone = pos.sittuyin_promotion() ? Bitboard(0) : promotionZone;
|
| 147 |
-
const Bitboard doubleStepRegion = pos.double_step_region(Us);
|
| 148 |
-
const Bitboard tripleStepRegion = pos.triple_step_region(Us);
|
| 149 |
-
|
| 150 |
-
const Bitboard pawns = pos.pieces(Us, PAWN);
|
| 151 |
-
const Bitboard movable = pos.board_bb(Us, PAWN) & ~pos.pieces();
|
| 152 |
-
const Bitboard capturable = pos.board_bb(Us, PAWN) & pos.pieces(Them);
|
| 153 |
-
|
| 154 |
-
target = Type == EVASIONS ? target : AllSquares;
|
| 155 |
-
|
| 156 |
-
// Define single and double push, left and right capture, as well as respective promotion moves
|
| 157 |
-
Bitboard b1 = shift<Up>(pawns) & movable & target;
|
| 158 |
-
Bitboard b2 = shift<Up>(shift<Up>(pawns & doubleStepRegion) & movable) & movable & target;
|
| 159 |
-
Bitboard b3 = shift<Up>(shift<Up>(shift<Up>(pawns & tripleStepRegion) & movable) & movable) & movable & target;
|
| 160 |
-
Bitboard brc = shift<UpRight>(pawns) & capturable & target;
|
| 161 |
-
Bitboard blc = shift<UpLeft >(pawns) & capturable & target;
|
| 162 |
-
|
| 163 |
-
Bitboard b1p = b1 & standardPromotionZone;
|
| 164 |
-
Bitboard b2p = b2 & standardPromotionZone;
|
| 165 |
-
Bitboard b3p = b3 & standardPromotionZone;
|
| 166 |
-
Bitboard brcp = brc & standardPromotionZone;
|
| 167 |
-
Bitboard blcp = blc & standardPromotionZone;
|
| 168 |
-
|
| 169 |
-
// Restrict regions based on rules and move generation type
|
| 170 |
-
if (pos.mandatory_pawn_promotion())
|
| 171 |
-
{
|
| 172 |
-
b1 &= ~standardPromotionZone;
|
| 173 |
-
b2 &= ~standardPromotionZone;
|
| 174 |
-
b3 &= ~standardPromotionZone;
|
| 175 |
-
brc &= ~standardPromotionZone;
|
| 176 |
-
blc &= ~standardPromotionZone;
|
| 177 |
-
}
|
| 178 |
-
|
| 179 |
-
if (Type == QUIET_CHECKS && pos.count<KING>(Them))
|
| 180 |
-
{
|
| 181 |
-
// To make a quiet check, you either make a direct check by pushing a pawn
|
| 182 |
-
// or push a blocker pawn that is not on the same file as the enemy king.
|
| 183 |
-
// Discovered check promotion has been already generated amongst the captures.
|
| 184 |
-
Square ksq = pos.square<KING>(Them);
|
| 185 |
-
Bitboard dcCandidatePawns = pos.blockers_for_king(Them) & ~file_bb(ksq);
|
| 186 |
-
b1 &= pawn_attacks_bb(Them, ksq) | shift< Up>(dcCandidatePawns);
|
| 187 |
-
b2 &= pawn_attacks_bb(Them, ksq) | shift<Up+Up>(dcCandidatePawns);
|
| 188 |
-
}
|
| 189 |
-
|
| 190 |
-
// Single and double pawn pushes, no promotions
|
| 191 |
-
if (Type != CAPTURES)
|
| 192 |
-
{
|
| 193 |
-
while (b1)
|
| 194 |
-
{
|
| 195 |
-
Square to = pop_lsb(b1);
|
| 196 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, to - Up, to);
|
| 197 |
-
}
|
| 198 |
-
|
| 199 |
-
while (b2)
|
| 200 |
-
{
|
| 201 |
-
Square to = pop_lsb(b2);
|
| 202 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, to - Up - Up, to);
|
| 203 |
-
}
|
| 204 |
-
|
| 205 |
-
while (b3)
|
| 206 |
-
{
|
| 207 |
-
Square to = pop_lsb(b3);
|
| 208 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, to - Up - Up - Up, to);
|
| 209 |
-
}
|
| 210 |
-
}
|
| 211 |
-
|
| 212 |
-
// Promotions and underpromotions
|
| 213 |
-
while (brcp)
|
| 214 |
-
moveList = make_promotions<Us, Type, UpRight>(pos, moveList, pop_lsb(brcp));
|
| 215 |
-
|
| 216 |
-
while (blcp)
|
| 217 |
-
moveList = make_promotions<Us, Type, UpLeft >(pos, moveList, pop_lsb(blcp));
|
| 218 |
-
|
| 219 |
-
while (b1p)
|
| 220 |
-
moveList = make_promotions<Us, Type, Up >(pos, moveList, pop_lsb(b1p));
|
| 221 |
-
|
| 222 |
-
while (b2p)
|
| 223 |
-
moveList = make_promotions<Us, Type, Up+Up >(pos, moveList, pop_lsb(b2p));
|
| 224 |
-
|
| 225 |
-
while (b3p)
|
| 226 |
-
moveList = make_promotions<Us, Type, Up+Up+Up>(pos, moveList, pop_lsb(b3p));
|
| 227 |
-
|
| 228 |
-
// Sittuyin promotions
|
| 229 |
-
if (pos.sittuyin_promotion() && (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS))
|
| 230 |
-
{
|
| 231 |
-
// Pawns need to be in promotion zone if there is more than one pawn
|
| 232 |
-
Bitboard promotionPawns = pos.count<PAWN>(Us) > 1 ? pawns & promotionZone : pawns;
|
| 233 |
-
while (promotionPawns)
|
| 234 |
-
{
|
| 235 |
-
Square from = pop_lsb(promotionPawns);
|
| 236 |
-
for (PieceSet ps = pos.promotion_piece_types(Us); ps;)
|
| 237 |
-
{
|
| 238 |
-
PieceType pt = pop_msb(ps);
|
| 239 |
-
if (pos.promotion_limit(pt) && pos.promotion_limit(pt) <= pos.count(Us, pt))
|
| 240 |
-
continue;
|
| 241 |
-
Bitboard b = ((pos.attacks_from(Us, pt, from) & ~pos.pieces()) | from) & target;
|
| 242 |
-
while (b)
|
| 243 |
-
{
|
| 244 |
-
Square to = pop_lsb(b);
|
| 245 |
-
if (!(attacks_bb(Us, pt, to, pos.pieces() ^ from) & pos.pieces(Them)))
|
| 246 |
-
*moveList++ = make<PROMOTION>(from, to, pt);
|
| 247 |
-
}
|
| 248 |
-
}
|
| 249 |
-
}
|
| 250 |
-
}
|
| 251 |
-
|
| 252 |
-
// Standard and en passant captures
|
| 253 |
-
if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
|
| 254 |
-
{
|
| 255 |
-
while (brc)
|
| 256 |
-
{
|
| 257 |
-
Square to = pop_lsb(brc);
|
| 258 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, to - UpRight, to);
|
| 259 |
-
}
|
| 260 |
-
|
| 261 |
-
while (blc)
|
| 262 |
-
{
|
| 263 |
-
Square to = pop_lsb(blc);
|
| 264 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, to - UpLeft, to);
|
| 265 |
-
}
|
| 266 |
-
|
| 267 |
-
for (Bitboard epSquares = pos.ep_squares() & ~pos.pieces(); epSquares; )
|
| 268 |
-
{
|
| 269 |
-
Square epSquare = pop_lsb(epSquares);
|
| 270 |
-
|
| 271 |
-
// An en passant capture cannot resolve a discovered check (unless there non-sliding riders)
|
| 272 |
-
if (Type == EVASIONS && (target & (epSquare + Up)) && !pos.non_sliding_riders())
|
| 273 |
-
return moveList;
|
| 274 |
-
|
| 275 |
-
Bitboard b = pawns & pawn_attacks_bb(Them, epSquare);
|
| 276 |
-
|
| 277 |
-
// En passant square is already disabled for non-fairy variants if there is no attacker
|
| 278 |
-
assert(b || !pos.fast_attacks());
|
| 279 |
-
|
| 280 |
-
while (b)
|
| 281 |
-
moveList = make_move_and_gating<EN_PASSANT>(pos, moveList, Us, pop_lsb(b), epSquare);
|
| 282 |
-
}
|
| 283 |
-
}
|
| 284 |
-
|
| 285 |
-
return moveList;
|
| 286 |
-
}
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
template<Color Us, GenType Type>
|
| 290 |
-
ExtMove* generate_moves(const Position& pos, ExtMove* moveList, PieceType Pt, Bitboard target) {
|
| 291 |
-
|
| 292 |
-
assert(Pt != KING && Pt != PAWN);
|
| 293 |
-
|
| 294 |
-
Bitboard bb = pos.pieces(Us, Pt);
|
| 295 |
-
|
| 296 |
-
while (bb)
|
| 297 |
-
{
|
| 298 |
-
Square from = pop_lsb(bb);
|
| 299 |
-
|
| 300 |
-
Bitboard attacks = pos.attacks_from(Us, Pt, from);
|
| 301 |
-
Bitboard quiets = pos.moves_from(Us, Pt, from);
|
| 302 |
-
Bitboard b = ( (attacks & pos.pieces())
|
| 303 |
-
| (quiets & ~pos.pieces()));
|
| 304 |
-
Bitboard b1 = b & target;
|
| 305 |
-
Bitboard promotion_zone = pos.promotion_zone(Us);
|
| 306 |
-
PieceType promPt = pos.promoted_piece_type(Pt);
|
| 307 |
-
Bitboard b2 = promPt && (!pos.promotion_limit(promPt) || pos.promotion_limit(promPt) > pos.count(Us, promPt)) ? b1 : Bitboard(0);
|
| 308 |
-
Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : Bitboard(0);
|
| 309 |
-
Bitboard pawnPromotions = (pos.promotion_pawn_types(Us) & Pt) ? (b & (Type == EVASIONS ? target : ~pos.pieces(Us)) & promotion_zone) : Bitboard(0);
|
| 310 |
-
Bitboard epSquares = (pos.en_passant_types(Us) & Pt) ? (attacks & ~quiets & pos.ep_squares() & ~pos.pieces()) : Bitboard(0);
|
| 311 |
-
|
| 312 |
-
// target squares considering pawn promotions
|
| 313 |
-
if (pawnPromotions && pos.mandatory_pawn_promotion())
|
| 314 |
-
b1 &= ~pawnPromotions;
|
| 315 |
-
|
| 316 |
-
// Restrict target squares considering promotion zone
|
| 317 |
-
if (b2 | b3)
|
| 318 |
-
{
|
| 319 |
-
if (pos.mandatory_piece_promotion())
|
| 320 |
-
b1 &= (promotion_zone & from ? Bitboard(0) : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : Bitboard(0));
|
| 321 |
-
// Exclude quiet promotions/demotions
|
| 322 |
-
if (pos.piece_promotion_on_capture())
|
| 323 |
-
{
|
| 324 |
-
b2 &= pos.pieces();
|
| 325 |
-
b3 &= pos.pieces();
|
| 326 |
-
}
|
| 327 |
-
// Consider promotions/demotions into promotion zone
|
| 328 |
-
if (!(promotion_zone & from))
|
| 329 |
-
{
|
| 330 |
-
b2 &= promotion_zone;
|
| 331 |
-
b3 &= promotion_zone;
|
| 332 |
-
}
|
| 333 |
-
}
|
| 334 |
-
|
| 335 |
-
if (Type == QUIET_CHECKS)
|
| 336 |
-
{
|
| 337 |
-
b1 &= pos.check_squares(Pt);
|
| 338 |
-
if (b2)
|
| 339 |
-
b2 &= pos.check_squares(pos.promoted_piece_type(Pt));
|
| 340 |
-
if (b3)
|
| 341 |
-
b3 &= pos.check_squares(type_of(pos.unpromoted_piece_on(from)));
|
| 342 |
-
}
|
| 343 |
-
|
| 344 |
-
while (b1)
|
| 345 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, from, pop_lsb(b1));
|
| 346 |
-
|
| 347 |
-
// Shogi-style piece promotions
|
| 348 |
-
while (b2)
|
| 349 |
-
*moveList++ = make<PIECE_PROMOTION>(from, pop_lsb(b2));
|
| 350 |
-
|
| 351 |
-
// Piece demotions
|
| 352 |
-
while (b3)
|
| 353 |
-
*moveList++ = make<PIECE_DEMOTION>(from, pop_lsb(b3));
|
| 354 |
-
|
| 355 |
-
// Pawn-style promotions
|
| 356 |
-
if ((Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS) && pawnPromotions)
|
| 357 |
-
for (PieceSet ps = pos.promotion_piece_types(Us); ps;)
|
| 358 |
-
{
|
| 359 |
-
PieceType ptP = pop_msb(ps);
|
| 360 |
-
if (!pos.promotion_limit(ptP) || pos.promotion_limit(ptP) > pos.count(Us, ptP))
|
| 361 |
-
for (Bitboard promotions = pawnPromotions; promotions; )
|
| 362 |
-
moveList = make_move_and_gating<PROMOTION>(pos, moveList, pos.side_to_move(), from, pop_lsb(promotions), ptP);
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
// En passant captures
|
| 366 |
-
if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
|
| 367 |
-
while (epSquares)
|
| 368 |
-
moveList = make_move_and_gating<EN_PASSANT>(pos, moveList, Us, from, pop_lsb(epSquares));
|
| 369 |
-
}
|
| 370 |
-
|
| 371 |
-
return moveList;
|
| 372 |
-
}
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
template<Color Us, GenType Type>
|
| 376 |
-
ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
|
| 377 |
-
|
| 378 |
-
static_assert(Type != LEGAL, "Unsupported type in generate_all()");
|
| 379 |
-
|
| 380 |
-
constexpr bool Checks = Type == QUIET_CHECKS; // Reduce template instantiations
|
| 381 |
-
const Square ksq = pos.count<KING>(Us) ? pos.square<KING>(Us) : SQ_NONE;
|
| 382 |
-
Bitboard target;
|
| 383 |
-
|
| 384 |
-
// Skip generating non-king moves when in double check
|
| 385 |
-
if (Type != EVASIONS || !more_than_one(pos.checkers() & ~pos.non_sliding_riders()))
|
| 386 |
-
{
|
| 387 |
-
target = Type == EVASIONS ? between_bb(ksq, lsb(pos.checkers()))
|
| 388 |
-
: Type == NON_EVASIONS ? ~pos.pieces( Us)
|
| 389 |
-
: Type == CAPTURES ? pos.pieces(~Us)
|
| 390 |
-
: ~pos.pieces( ); // QUIETS || QUIET_CHECKS
|
| 391 |
-
|
| 392 |
-
if (Type == EVASIONS)
|
| 393 |
-
{
|
| 394 |
-
if (pos.checkers() & pos.non_sliding_riders())
|
| 395 |
-
target = ~pos.pieces(Us);
|
| 396 |
-
// Leaper attacks can not be blocked
|
| 397 |
-
Square checksq = lsb(pos.checkers());
|
| 398 |
-
if (LeaperAttacks[~Us][type_of(pos.piece_on(checksq))][checksq] & pos.square<KING>(Us))
|
| 399 |
-
target = pos.checkers();
|
| 400 |
-
}
|
| 401 |
-
|
| 402 |
-
// Remove inaccessible squares (outside board + wall squares)
|
| 403 |
-
target &= pos.board_bb();
|
| 404 |
-
|
| 405 |
-
moveList = generate_pawn_moves<Us, Type>(pos, moveList, target);
|
| 406 |
-
for (PieceSet ps = pos.piece_types() & ~(piece_set(PAWN) | KING); ps;)
|
| 407 |
-
moveList = generate_moves<Us, Type>(pos, moveList, pop_lsb(ps), target);
|
| 408 |
-
// generate drops
|
| 409 |
-
if (pos.piece_drops() && Type != CAPTURES && (pos.can_drop(Us, ALL_PIECES) || pos.two_boards()))
|
| 410 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 411 |
-
moveList = generate_drops<Us, Type>(pos, moveList, pop_lsb(ps), target & ~pos.pieces(~Us));
|
| 412 |
-
|
| 413 |
-
// Castling with non-king piece
|
| 414 |
-
if (!pos.count<KING>(Us) && Type != CAPTURES && pos.can_castle(Us & ANY_CASTLING))
|
| 415 |
-
{
|
| 416 |
-
Square from = pos.castling_king_square(Us);
|
| 417 |
-
for(CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } )
|
| 418 |
-
if (!pos.castling_impeded(cr) && pos.can_castle(cr))
|
| 419 |
-
moveList = make_move_and_gating<CASTLING>(pos, moveList, Us, from, pos.castling_rook_square(cr));
|
| 420 |
-
}
|
| 421 |
-
|
| 422 |
-
// Special moves
|
| 423 |
-
if (pos.cambodian_moves() && pos.gates(Us) && Type != CAPTURES)
|
| 424 |
-
{
|
| 425 |
-
if (Type != EVASIONS && (pos.pieces(Us, KING) & pos.gates(Us)))
|
| 426 |
-
{
|
| 427 |
-
Square from = pos.square<KING>(Us);
|
| 428 |
-
Bitboard b = PseudoAttacks[WHITE][KNIGHT][from] & rank_bb(rank_of(from + (Us == WHITE ? NORTH : SOUTH)))
|
| 429 |
-
& target & ~pos.pieces();
|
| 430 |
-
while (b)
|
| 431 |
-
moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, from, pop_lsb(b));
|
| 432 |
-
}
|
| 433 |
-
|
| 434 |
-
Bitboard b = pos.pieces(Us, FERS) & pos.gates(Us);
|
| 435 |
-
while (b)
|
| 436 |
-
{
|
| 437 |
-
Square from = pop_lsb(b);
|
| 438 |
-
Square to = from + 2 * (Us == WHITE ? NORTH : SOUTH);
|
| 439 |
-
if (is_ok(to) && (target & to & ~pos.pieces()))
|
| 440 |
-
moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, from, to);
|
| 441 |
-
}
|
| 442 |
-
}
|
| 443 |
-
|
| 444 |
-
// Workaround for passing: Execute a non-move with any piece
|
| 445 |
-
if (pos.pass(Us) && !pos.count<KING>(Us) && pos.pieces(Us))
|
| 446 |
-
*moveList++ = make<SPECIAL>(lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
|
| 447 |
-
|
| 448 |
-
//if "wall or move", generate walling action with null move
|
| 449 |
-
if (pos.wall_or_move())
|
| 450 |
-
{
|
| 451 |
-
moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
|
| 452 |
-
}
|
| 453 |
-
}
|
| 454 |
-
|
| 455 |
-
// King moves
|
| 456 |
-
if (pos.count<KING>(Us) && (!Checks || pos.blockers_for_king(~Us) & ksq))
|
| 457 |
-
{
|
| 458 |
-
Bitboard b = ( (pos.attacks_from(Us, KING, ksq) & pos.pieces())
|
| 459 |
-
| (pos.moves_from(Us, KING, ksq) & ~pos.pieces())) & (Type == EVASIONS ? ~pos.pieces(Us) : target);
|
| 460 |
-
while (b)
|
| 461 |
-
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, ksq, pop_lsb(b));
|
| 462 |
-
|
| 463 |
-
// Passing move by king
|
| 464 |
-
if (pos.pass(Us))
|
| 465 |
-
*moveList++ = make<SPECIAL>(ksq, ksq);
|
| 466 |
-
|
| 467 |
-
if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
|
| 468 |
-
for (CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } )
|
| 469 |
-
if (!pos.castling_impeded(cr) && pos.can_castle(cr))
|
| 470 |
-
moveList = make_move_and_gating<CASTLING>(pos, moveList, Us,ksq, pos.castling_rook_square(cr));
|
| 471 |
-
}
|
| 472 |
-
|
| 473 |
-
return moveList;
|
| 474 |
-
}
|
| 475 |
-
|
| 476 |
-
} // namespace
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
/// <CAPTURES> Generates all pseudo-legal captures plus queen promotions
|
| 480 |
-
/// <QUIETS> Generates all pseudo-legal non-captures and underpromotions
|
| 481 |
-
/// <EVASIONS> Generates all pseudo-legal check evasions when the side to move is in check
|
| 482 |
-
/// <QUIET_CHECKS> Generates all pseudo-legal non-captures giving check, except castling and promotions
|
| 483 |
-
/// <NON_EVASIONS> Generates all pseudo-legal captures and non-captures
|
| 484 |
-
///
|
| 485 |
-
/// Returns a pointer to the end of the move list.
|
| 486 |
-
|
| 487 |
-
template<GenType Type>
|
| 488 |
-
ExtMove* generate(const Position& pos, ExtMove* moveList) {
|
| 489 |
-
|
| 490 |
-
static_assert(Type != LEGAL, "Unsupported type in generate()");
|
| 491 |
-
assert((Type == EVASIONS) == (bool)pos.checkers());
|
| 492 |
-
|
| 493 |
-
Color us = pos.side_to_move();
|
| 494 |
-
|
| 495 |
-
return us == WHITE ? generate_all<WHITE, Type>(pos, moveList)
|
| 496 |
-
: generate_all<BLACK, Type>(pos, moveList);
|
| 497 |
-
}
|
| 498 |
-
|
| 499 |
-
// Explicit template instantiations
|
| 500 |
-
template ExtMove* generate<CAPTURES>(const Position&, ExtMove*);
|
| 501 |
-
template ExtMove* generate<QUIETS>(const Position&, ExtMove*);
|
| 502 |
-
template ExtMove* generate<EVASIONS>(const Position&, ExtMove*);
|
| 503 |
-
template ExtMove* generate<QUIET_CHECKS>(const Position&, ExtMove*);
|
| 504 |
-
template ExtMove* generate<NON_EVASIONS>(const Position&, ExtMove*);
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
/// generate<LEGAL> generates all the legal moves in the given position
|
| 508 |
-
|
| 509 |
-
template<>
|
| 510 |
-
ExtMove* generate<LEGAL>(const Position& pos, ExtMove* moveList) {
|
| 511 |
-
|
| 512 |
-
if (pos.is_immediate_game_end())
|
| 513 |
-
return moveList;
|
| 514 |
-
|
| 515 |
-
ExtMove* cur = moveList;
|
| 516 |
-
|
| 517 |
-
moveList = pos.checkers() ? generate<EVASIONS >(pos, moveList)
|
| 518 |
-
: generate<NON_EVASIONS>(pos, moveList);
|
| 519 |
-
while (cur != moveList)
|
| 520 |
-
if (!pos.legal(*cur) || pos.virtual_drop(*cur))
|
| 521 |
-
*cur = (--moveList)->move;
|
| 522 |
-
else
|
| 523 |
-
++cur;
|
| 524 |
-
|
| 525 |
-
return moveList;
|
| 526 |
-
}
|
| 527 |
-
|
| 528 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/movegen.h
DELETED
|
@@ -1,107 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef MOVEGEN_H_INCLUDED
|
| 20 |
-
#define MOVEGEN_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <algorithm>
|
| 23 |
-
|
| 24 |
-
#include "types.h"
|
| 25 |
-
|
| 26 |
-
namespace Stockfish {
|
| 27 |
-
|
| 28 |
-
class Position;
|
| 29 |
-
|
| 30 |
-
enum GenType {
|
| 31 |
-
CAPTURES,
|
| 32 |
-
QUIETS,
|
| 33 |
-
QUIET_CHECKS,
|
| 34 |
-
EVASIONS,
|
| 35 |
-
NON_EVASIONS,
|
| 36 |
-
LEGAL
|
| 37 |
-
};
|
| 38 |
-
|
| 39 |
-
struct ExtMove {
|
| 40 |
-
Move move;
|
| 41 |
-
int value;
|
| 42 |
-
|
| 43 |
-
operator Move() const { return move; }
|
| 44 |
-
void operator=(Move m) { move = m; }
|
| 45 |
-
|
| 46 |
-
// Inhibit unwanted implicit conversions to Move
|
| 47 |
-
// with an ambiguity that yields to a compile error.
|
| 48 |
-
operator float() const = delete;
|
| 49 |
-
};
|
| 50 |
-
|
| 51 |
-
inline bool operator<(const ExtMove& f, const ExtMove& s) {
|
| 52 |
-
return f.value < s.value;
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
template<GenType>
|
| 56 |
-
ExtMove* generate(const Position& pos, ExtMove* moveList);
|
| 57 |
-
|
| 58 |
-
constexpr size_t moveListSize = sizeof(ExtMove) * MAX_MOVES;
|
| 59 |
-
|
| 60 |
-
/// The MoveList struct is a simple wrapper around generate(). It sometimes comes
|
| 61 |
-
/// in handy to use this class instead of the low level generate() function.
|
| 62 |
-
template<GenType T>
|
| 63 |
-
struct MoveList {
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
#ifdef USE_HEAP_INSTEAD_OF_STACK_FOR_MOVE_LIST
|
| 67 |
-
explicit MoveList(const Position& pos)
|
| 68 |
-
{
|
| 69 |
-
this->moveList = (ExtMove*)malloc(moveListSize);
|
| 70 |
-
if (this->moveList == 0)
|
| 71 |
-
{
|
| 72 |
-
printf("Error: Failed to allocate memory in heap.");
|
| 73 |
-
exit(1);
|
| 74 |
-
}
|
| 75 |
-
this->last = generate<T>(pos, this->moveList);
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
~MoveList()
|
| 79 |
-
{
|
| 80 |
-
free(this->moveList);
|
| 81 |
-
}
|
| 82 |
-
#else
|
| 83 |
-
explicit MoveList(const Position& pos) : last(generate<T>(pos, moveList))
|
| 84 |
-
{
|
| 85 |
-
;
|
| 86 |
-
}
|
| 87 |
-
#endif
|
| 88 |
-
|
| 89 |
-
const ExtMove* begin() const { return moveList; }
|
| 90 |
-
const ExtMove* end() const { return last; }
|
| 91 |
-
size_t size() const { return last - moveList; }
|
| 92 |
-
bool contains(Move move) const {
|
| 93 |
-
return std::find(begin(), end(), move) != end();
|
| 94 |
-
}
|
| 95 |
-
|
| 96 |
-
private:
|
| 97 |
-
ExtMove* last;
|
| 98 |
-
#ifdef USE_HEAP_INSTEAD_OF_STACK_FOR_MOVE_LIST
|
| 99 |
-
ExtMove* moveList = 0;
|
| 100 |
-
#else
|
| 101 |
-
ExtMove moveList[MAX_MOVES];
|
| 102 |
-
#endif
|
| 103 |
-
};
|
| 104 |
-
|
| 105 |
-
} // namespace Stockfish
|
| 106 |
-
|
| 107 |
-
#endif // #ifndef MOVEGEN_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/movepick.cpp
DELETED
|
@@ -1,279 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#include <cassert>
|
| 20 |
-
|
| 21 |
-
#include "movepick.h"
|
| 22 |
-
|
| 23 |
-
namespace Stockfish {
|
| 24 |
-
|
| 25 |
-
// Since continuation history grows quadratically with the number of piece types,
|
| 26 |
-
// we need to reserve a limited number of slots and map piece types to these slots
|
| 27 |
-
// in order to reduce memory consumption to a reasonable level.
|
| 28 |
-
int history_slot(Piece pc) {
|
| 29 |
-
return pc == NO_PIECE ? 0 : (type_of(pc) == KING ? PIECE_SLOTS - 1 : type_of(pc) % (PIECE_SLOTS - 1)) + color_of(pc) * PIECE_SLOTS;
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
namespace {
|
| 33 |
-
|
| 34 |
-
enum Stages {
|
| 35 |
-
MAIN_TT, CAPTURE_INIT, GOOD_CAPTURE, REFUTATION, QUIET_INIT, QUIET, BAD_CAPTURE,
|
| 36 |
-
EVASION_TT, EVASION_INIT, EVASION,
|
| 37 |
-
PROBCUT_TT, PROBCUT_INIT, PROBCUT,
|
| 38 |
-
QSEARCH_TT, QCAPTURE_INIT, QCAPTURE, QCHECK_INIT, QCHECK
|
| 39 |
-
};
|
| 40 |
-
|
| 41 |
-
// partial_insertion_sort() sorts moves in descending order up to and including
|
| 42 |
-
// a given limit. The order of moves smaller than the limit is left unspecified.
|
| 43 |
-
void partial_insertion_sort(ExtMove* begin, ExtMove* end, int limit) {
|
| 44 |
-
|
| 45 |
-
for (ExtMove *sortedEnd = begin, *p = begin + 1; p < end; ++p)
|
| 46 |
-
if (p->value >= limit)
|
| 47 |
-
{
|
| 48 |
-
ExtMove tmp = *p, *q;
|
| 49 |
-
*p = *++sortedEnd;
|
| 50 |
-
for (q = sortedEnd; q != begin && *(q - 1) < tmp; --q)
|
| 51 |
-
*q = *(q - 1);
|
| 52 |
-
*q = tmp;
|
| 53 |
-
}
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
} // namespace
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
/// Constructors of the MovePicker class. As arguments we pass information
|
| 60 |
-
/// to help it to return the (presumably) good moves first, to decide which
|
| 61 |
-
/// moves to return (in the quiescence search, for instance, we only want to
|
| 62 |
-
/// search captures, promotions, and some checks) and how important good move
|
| 63 |
-
/// ordering is at the current node.
|
| 64 |
-
|
| 65 |
-
/// MovePicker constructor for the main search
|
| 66 |
-
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, const GateHistory* dh, const LowPlyHistory* lp,
|
| 67 |
-
const CapturePieceToHistory* cph, const PieceToHistory** ch, Move cm, const Move* killers, int pl)
|
| 68 |
-
: pos(p), mainHistory(mh), gateHistory(dh), lowPlyHistory(lp), captureHistory(cph), continuationHistory(ch),
|
| 69 |
-
ttMove(ttm), refutations{{killers[0], 0}, {killers[1], 0}, {cm, 0}}, depth(d), ply(pl) {
|
| 70 |
-
|
| 71 |
-
assert(d > 0);
|
| 72 |
-
|
| 73 |
-
stage = (pos.checkers() ? EVASION_TT : MAIN_TT) +
|
| 74 |
-
!(ttm && pos.pseudo_legal(ttm));
|
| 75 |
-
}
|
| 76 |
-
|
| 77 |
-
/// MovePicker constructor for quiescence search
|
| 78 |
-
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, const GateHistory* dh,
|
| 79 |
-
const CapturePieceToHistory* cph, const PieceToHistory** ch, Square rs)
|
| 80 |
-
: pos(p), mainHistory(mh), gateHistory(dh), captureHistory(cph), continuationHistory(ch), ttMove(ttm), recaptureSquare(rs), depth(d) {
|
| 81 |
-
|
| 82 |
-
assert(d <= 0);
|
| 83 |
-
|
| 84 |
-
stage = (pos.checkers() ? EVASION_TT : QSEARCH_TT) +
|
| 85 |
-
!( ttm
|
| 86 |
-
&& (pos.checkers() || depth > DEPTH_QS_RECAPTURES || to_sq(ttm) == recaptureSquare)
|
| 87 |
-
&& pos.pseudo_legal(ttm));
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
-
/// MovePicker constructor for ProbCut: we generate captures with SEE greater
|
| 91 |
-
/// than or equal to the given threshold.
|
| 92 |
-
MovePicker::MovePicker(const Position& p, Move ttm, Value th, const GateHistory* dh, const CapturePieceToHistory* cph)
|
| 93 |
-
: pos(p), gateHistory(dh), captureHistory(cph), ttMove(ttm), threshold(th) {
|
| 94 |
-
|
| 95 |
-
assert(!pos.checkers());
|
| 96 |
-
|
| 97 |
-
stage = PROBCUT_TT + !(ttm && pos.capture(ttm)
|
| 98 |
-
&& pos.pseudo_legal(ttm)
|
| 99 |
-
&& pos.see_ge(ttm, threshold));
|
| 100 |
-
}
|
| 101 |
-
|
| 102 |
-
/// MovePicker::score() assigns a numerical value to each move in a list, used
|
| 103 |
-
/// for sorting. Captures are ordered by Most Valuable Victim (MVV), preferring
|
| 104 |
-
/// captures with a good history. Quiets moves are ordered using the histories.
|
| 105 |
-
template<GenType Type>
|
| 106 |
-
void MovePicker::score() {
|
| 107 |
-
|
| 108 |
-
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
|
| 109 |
-
|
| 110 |
-
for (auto& m : *this)
|
| 111 |
-
if constexpr (Type == CAPTURES)
|
| 112 |
-
m.value = int(PieceValue[MG][pos.piece_on(to_sq(m))]) * 6
|
| 113 |
-
+ (*gateHistory)[pos.side_to_move()][gating_square(m)]
|
| 114 |
-
+ (*captureHistory)[pos.moved_piece(m)][to_sq(m)][type_of(pos.piece_on(to_sq(m)))];
|
| 115 |
-
|
| 116 |
-
else if constexpr (Type == QUIETS)
|
| 117 |
-
m.value = (*mainHistory)[pos.side_to_move()][from_to(m)]
|
| 118 |
-
+ (*gateHistory)[pos.side_to_move()][gating_square(m)]
|
| 119 |
-
+ 2 * (*continuationHistory[0])[history_slot(pos.moved_piece(m))][to_sq(m)]
|
| 120 |
-
+ (*continuationHistory[1])[history_slot(pos.moved_piece(m))][to_sq(m)]
|
| 121 |
-
+ (*continuationHistory[3])[history_slot(pos.moved_piece(m))][to_sq(m)]
|
| 122 |
-
+ (*continuationHistory[5])[history_slot(pos.moved_piece(m))][to_sq(m)]
|
| 123 |
-
+ (ply < MAX_LPH ? std::min(4, depth / 3) * (*lowPlyHistory)[ply][from_to(m)] : 0);
|
| 124 |
-
|
| 125 |
-
else // Type == EVASIONS
|
| 126 |
-
{
|
| 127 |
-
if (pos.capture(m))
|
| 128 |
-
m.value = PieceValue[MG][pos.piece_on(to_sq(m))]
|
| 129 |
-
- Value(type_of(pos.moved_piece(m)));
|
| 130 |
-
else
|
| 131 |
-
m.value = (*mainHistory)[pos.side_to_move()][from_to(m)]
|
| 132 |
-
+ 2 * (*continuationHistory[0])[history_slot(pos.moved_piece(m))][to_sq(m)]
|
| 133 |
-
- (1 << 28);
|
| 134 |
-
}
|
| 135 |
-
}
|
| 136 |
-
|
| 137 |
-
/// MovePicker::select() returns the next move satisfying a predicate function.
|
| 138 |
-
/// It never returns the TT move.
|
| 139 |
-
template<MovePicker::PickType T, typename Pred>
|
| 140 |
-
Move MovePicker::select(Pred filter) {
|
| 141 |
-
|
| 142 |
-
while (cur < endMoves)
|
| 143 |
-
{
|
| 144 |
-
if (T == Best)
|
| 145 |
-
std::swap(*cur, *std::max_element(cur, endMoves));
|
| 146 |
-
|
| 147 |
-
if (*cur != ttMove && filter())
|
| 148 |
-
return *cur++;
|
| 149 |
-
|
| 150 |
-
cur++;
|
| 151 |
-
}
|
| 152 |
-
return MOVE_NONE;
|
| 153 |
-
}
|
| 154 |
-
|
| 155 |
-
/// MovePicker::next_move() is the most important method of the MovePicker class. It
|
| 156 |
-
/// returns a new pseudo-legal move every time it is called until there are no more
|
| 157 |
-
/// moves left, picking the move with the highest score from a list of generated moves.
|
| 158 |
-
Move MovePicker::next_move(bool skipQuiets) {
|
| 159 |
-
|
| 160 |
-
top:
|
| 161 |
-
switch (stage) {
|
| 162 |
-
|
| 163 |
-
case MAIN_TT:
|
| 164 |
-
case EVASION_TT:
|
| 165 |
-
case QSEARCH_TT:
|
| 166 |
-
case PROBCUT_TT:
|
| 167 |
-
++stage;
|
| 168 |
-
assert(pos.legal(ttMove) == MoveList<LEGAL>(pos).contains(ttMove) || pos.virtual_drop(ttMove));
|
| 169 |
-
return ttMove;
|
| 170 |
-
|
| 171 |
-
case CAPTURE_INIT:
|
| 172 |
-
case PROBCUT_INIT:
|
| 173 |
-
case QCAPTURE_INIT:
|
| 174 |
-
cur = endBadCaptures = moves;
|
| 175 |
-
endMoves = generate<CAPTURES>(pos, cur);
|
| 176 |
-
|
| 177 |
-
score<CAPTURES>();
|
| 178 |
-
++stage;
|
| 179 |
-
goto top;
|
| 180 |
-
|
| 181 |
-
case GOOD_CAPTURE:
|
| 182 |
-
if (select<Best>([&](){
|
| 183 |
-
return pos.see_ge(*cur, Value(-69 * cur->value / 1024 - 500 * (pos.captures_to_hand() && pos.gives_check(*cur))))?
|
| 184 |
-
// Move losing capture to endBadCaptures to be tried later
|
| 185 |
-
true : (*endBadCaptures++ = *cur, false); }))
|
| 186 |
-
return *(cur - 1);
|
| 187 |
-
|
| 188 |
-
// Prepare the pointers to loop over the refutations array
|
| 189 |
-
cur = std::begin(refutations);
|
| 190 |
-
endMoves = std::end(refutations);
|
| 191 |
-
|
| 192 |
-
// If the countermove is the same as a killer, skip it
|
| 193 |
-
if ( refutations[0].move == refutations[2].move
|
| 194 |
-
|| refutations[1].move == refutations[2].move)
|
| 195 |
-
--endMoves;
|
| 196 |
-
|
| 197 |
-
++stage;
|
| 198 |
-
[[fallthrough]];
|
| 199 |
-
|
| 200 |
-
case REFUTATION:
|
| 201 |
-
if (select<Next>([&](){ return *cur != MOVE_NONE
|
| 202 |
-
&& !pos.capture(*cur)
|
| 203 |
-
&& pos.pseudo_legal(*cur); }))
|
| 204 |
-
return *(cur - 1);
|
| 205 |
-
++stage;
|
| 206 |
-
[[fallthrough]];
|
| 207 |
-
|
| 208 |
-
case QUIET_INIT:
|
| 209 |
-
if (!skipQuiets && !(pos.must_capture() && pos.has_capture()))
|
| 210 |
-
{
|
| 211 |
-
cur = endBadCaptures;
|
| 212 |
-
endMoves = generate<QUIETS>(pos, cur);
|
| 213 |
-
|
| 214 |
-
score<QUIETS>();
|
| 215 |
-
partial_insertion_sort(cur, endMoves, -3000 * depth);
|
| 216 |
-
}
|
| 217 |
-
|
| 218 |
-
++stage;
|
| 219 |
-
[[fallthrough]];
|
| 220 |
-
|
| 221 |
-
case QUIET:
|
| 222 |
-
if ( !skipQuiets
|
| 223 |
-
&& select<Next>([&](){return *cur != refutations[0].move
|
| 224 |
-
&& *cur != refutations[1].move
|
| 225 |
-
&& *cur != refutations[2].move;}))
|
| 226 |
-
return *(cur - 1);
|
| 227 |
-
|
| 228 |
-
// Prepare the pointers to loop over the bad captures
|
| 229 |
-
cur = moves;
|
| 230 |
-
endMoves = endBadCaptures;
|
| 231 |
-
|
| 232 |
-
++stage;
|
| 233 |
-
[[fallthrough]];
|
| 234 |
-
|
| 235 |
-
case BAD_CAPTURE:
|
| 236 |
-
return select<Next>([](){ return true; });
|
| 237 |
-
|
| 238 |
-
case EVASION_INIT:
|
| 239 |
-
cur = moves;
|
| 240 |
-
endMoves = generate<EVASIONS>(pos, cur);
|
| 241 |
-
|
| 242 |
-
score<EVASIONS>();
|
| 243 |
-
++stage;
|
| 244 |
-
[[fallthrough]];
|
| 245 |
-
|
| 246 |
-
case EVASION:
|
| 247 |
-
return select<Best>([](){ return true; });
|
| 248 |
-
|
| 249 |
-
case PROBCUT:
|
| 250 |
-
return select<Best>([&](){ return pos.see_ge(*cur, threshold); });
|
| 251 |
-
|
| 252 |
-
case QCAPTURE:
|
| 253 |
-
if (select<Best>([&](){ return depth > DEPTH_QS_RECAPTURES
|
| 254 |
-
|| to_sq(*cur) == recaptureSquare; }))
|
| 255 |
-
return *(cur - 1);
|
| 256 |
-
|
| 257 |
-
// If we did not find any move and we do not try checks, we have finished
|
| 258 |
-
if (depth != DEPTH_QS_CHECKS)
|
| 259 |
-
return MOVE_NONE;
|
| 260 |
-
|
| 261 |
-
++stage;
|
| 262 |
-
[[fallthrough]];
|
| 263 |
-
|
| 264 |
-
case QCHECK_INIT:
|
| 265 |
-
cur = moves;
|
| 266 |
-
endMoves = generate<QUIET_CHECKS>(pos, cur);
|
| 267 |
-
|
| 268 |
-
++stage;
|
| 269 |
-
[[fallthrough]];
|
| 270 |
-
|
| 271 |
-
case QCHECK:
|
| 272 |
-
return select<Next>([](){ return true; });
|
| 273 |
-
}
|
| 274 |
-
|
| 275 |
-
assert(false);
|
| 276 |
-
return MOVE_NONE; // Silence warning
|
| 277 |
-
}
|
| 278 |
-
|
| 279 |
-
} // namespace Stockfish
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/movepick.h
DELETED
|
@@ -1,169 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
#ifndef MOVEPICK_H_INCLUDED
|
| 20 |
-
#define MOVEPICK_H_INCLUDED
|
| 21 |
-
|
| 22 |
-
#include <array>
|
| 23 |
-
#include <limits>
|
| 24 |
-
#include <type_traits>
|
| 25 |
-
|
| 26 |
-
#include "movegen.h"
|
| 27 |
-
#include "position.h"
|
| 28 |
-
#include "types.h"
|
| 29 |
-
|
| 30 |
-
namespace Stockfish {
|
| 31 |
-
|
| 32 |
-
/// StatsEntry stores the stat table value. It is usually a number but could
|
| 33 |
-
/// be a move or even a nested history. We use a class instead of naked value
|
| 34 |
-
/// to directly call history update operator<<() on the entry so to use stats
|
| 35 |
-
/// tables at caller sites as simple multi-dim arrays.
|
| 36 |
-
template<typename T, int D>
|
| 37 |
-
class StatsEntry {
|
| 38 |
-
|
| 39 |
-
T entry;
|
| 40 |
-
|
| 41 |
-
public:
|
| 42 |
-
void operator=(const T& v) { entry = v; }
|
| 43 |
-
T* operator&() { return &entry; }
|
| 44 |
-
T* operator->() { return &entry; }
|
| 45 |
-
operator const T&() const { return entry; }
|
| 46 |
-
|
| 47 |
-
void operator<<(int bonus) {
|
| 48 |
-
assert(abs(bonus) <= D); // Ensure range is [-D, D]
|
| 49 |
-
static_assert(D <= std::numeric_limits<T>::max(), "D overflows T");
|
| 50 |
-
|
| 51 |
-
entry += bonus - entry * abs(bonus) / D;
|
| 52 |
-
|
| 53 |
-
assert(abs(entry) <= D);
|
| 54 |
-
}
|
| 55 |
-
};
|
| 56 |
-
|
| 57 |
-
/// Stats is a generic N-dimensional array used to store various statistics.
|
| 58 |
-
/// The first template parameter T is the base type of the array, the second
|
| 59 |
-
/// template parameter D limits the range of updates in [-D, D] when we update
|
| 60 |
-
/// values with the << operator, while the last parameters (Size and Sizes)
|
| 61 |
-
/// encode the dimensions of the array.
|
| 62 |
-
template <typename T, int D, int Size, int... Sizes>
|
| 63 |
-
struct Stats : public std::array<Stats<T, D, Sizes...>, Size>
|
| 64 |
-
{
|
| 65 |
-
typedef Stats<T, D, Size, Sizes...> stats;
|
| 66 |
-
|
| 67 |
-
void fill(const T& v) {
|
| 68 |
-
|
| 69 |
-
// For standard-layout 'this' points to first struct member
|
| 70 |
-
assert(std::is_standard_layout<stats>::value);
|
| 71 |
-
|
| 72 |
-
typedef StatsEntry<T, D> entry;
|
| 73 |
-
entry* p = reinterpret_cast<entry*>(this);
|
| 74 |
-
std::fill(p, p + sizeof(*this) / sizeof(entry), v);
|
| 75 |
-
}
|
| 76 |
-
};
|
| 77 |
-
|
| 78 |
-
template <typename T, int D, int Size>
|
| 79 |
-
struct Stats<T, D, Size> : public std::array<StatsEntry<T, D>, Size> {};
|
| 80 |
-
|
| 81 |
-
/// In stats table, D=0 means that the template parameter is not used
|
| 82 |
-
enum StatsParams { NOT_USED = 0, PIECE_SLOTS = 8 };
|
| 83 |
-
enum StatsType { NoCaptures, Captures };
|
| 84 |
-
|
| 85 |
-
/// ButterflyHistory records how often quiet moves have been successful or
|
| 86 |
-
/// unsuccessful during the current search, and is used for reduction and move
|
| 87 |
-
/// ordering decisions. It uses 2 tables (one for each color) indexed by
|
| 88 |
-
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
|
| 89 |
-
typedef Stats<int16_t, 13365, COLOR_NB, int(SQUARE_NB + 1) * int(1 << SQUARE_BITS)> ButterflyHistory;
|
| 90 |
-
|
| 91 |
-
typedef Stats<int16_t, 13365, COLOR_NB, SQUARE_NB> GateHistory;
|
| 92 |
-
|
| 93 |
-
/// At higher depths LowPlyHistory records successful quiet moves near the root
|
| 94 |
-
/// and quiet moves which are/were in the PV (ttPv). It is cleared with each new
|
| 95 |
-
/// search and filled during iterative deepening.
|
| 96 |
-
constexpr int MAX_LPH = 4;
|
| 97 |
-
typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB + 1) * int(1 << SQUARE_BITS)> LowPlyHistory;
|
| 98 |
-
|
| 99 |
-
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
|
| 100 |
-
/// move, see www.chessprogramming.org/Countermove_Heuristic
|
| 101 |
-
typedef Stats<Move, NOT_USED, PIECE_NB, SQUARE_NB> CounterMoveHistory;
|
| 102 |
-
|
| 103 |
-
/// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
|
| 104 |
-
typedef Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB> CapturePieceToHistory;
|
| 105 |
-
|
| 106 |
-
/// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
|
| 107 |
-
typedef Stats<int16_t, 29952, 2 * PIECE_SLOTS, SQUARE_NB> PieceToHistory;
|
| 108 |
-
|
| 109 |
-
/// ContinuationHistory is the combined history of a given pair of moves, usually
|
| 110 |
-
/// the current one given a previous one. The nested history table is based on
|
| 111 |
-
/// PieceToHistory instead of ButterflyBoards.
|
| 112 |
-
typedef Stats<PieceToHistory, NOT_USED, 2 * PIECE_SLOTS, SQUARE_NB> ContinuationHistory;
|
| 113 |
-
|
| 114 |
-
int history_slot(Piece pc);
|
| 115 |
-
|
| 116 |
-
/// MovePicker class is used to pick one pseudo-legal move at a time from the
|
| 117 |
-
/// current position. The most important method is next_move(), which returns a
|
| 118 |
-
/// new pseudo-legal move each time it is called, until there are no moves left,
|
| 119 |
-
/// when MOVE_NONE is returned. In order to improve the efficiency of the
|
| 120 |
-
/// alpha-beta algorithm, MovePicker attempts to return the moves which are most
|
| 121 |
-
/// likely to get a cut-off first.
|
| 122 |
-
class MovePicker {
|
| 123 |
-
|
| 124 |
-
enum PickType { Next, Best };
|
| 125 |
-
|
| 126 |
-
public:
|
| 127 |
-
MovePicker(const MovePicker&) = delete;
|
| 128 |
-
MovePicker& operator=(const MovePicker&) = delete;
|
| 129 |
-
MovePicker(const Position&, Move, Value, const GateHistory*, const CapturePieceToHistory*);
|
| 130 |
-
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
| 131 |
-
const GateHistory*,
|
| 132 |
-
const CapturePieceToHistory*,
|
| 133 |
-
const PieceToHistory**,
|
| 134 |
-
Square);
|
| 135 |
-
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
| 136 |
-
const GateHistory*,
|
| 137 |
-
const LowPlyHistory*,
|
| 138 |
-
const CapturePieceToHistory*,
|
| 139 |
-
const PieceToHistory**,
|
| 140 |
-
Move,
|
| 141 |
-
const Move*,
|
| 142 |
-
int);
|
| 143 |
-
Move next_move(bool skipQuiets = false);
|
| 144 |
-
|
| 145 |
-
private:
|
| 146 |
-
template<PickType T, typename Pred> Move select(Pred);
|
| 147 |
-
template<GenType> void score();
|
| 148 |
-
ExtMove* begin() { return cur; }
|
| 149 |
-
ExtMove* end() { return endMoves; }
|
| 150 |
-
|
| 151 |
-
const Position& pos;
|
| 152 |
-
const ButterflyHistory* mainHistory;
|
| 153 |
-
const GateHistory* gateHistory;
|
| 154 |
-
const LowPlyHistory* lowPlyHistory;
|
| 155 |
-
const CapturePieceToHistory* captureHistory;
|
| 156 |
-
const PieceToHistory** continuationHistory;
|
| 157 |
-
Move ttMove;
|
| 158 |
-
ExtMove refutations[3], *cur, *endMoves, *endBadCaptures;
|
| 159 |
-
int stage;
|
| 160 |
-
Square recaptureSquare;
|
| 161 |
-
Value threshold;
|
| 162 |
-
Depth depth;
|
| 163 |
-
int ply;
|
| 164 |
-
ExtMove moves[MAX_MOVES];
|
| 165 |
-
};
|
| 166 |
-
|
| 167 |
-
} // namespace Stockfish
|
| 168 |
-
|
| 169 |
-
#endif // #ifndef MOVEPICK_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/evaluate_nnue.cpp
DELETED
|
@@ -1,443 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
// Code for calculating NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#include <iostream>
|
| 22 |
-
#include <set>
|
| 23 |
-
#include <sstream>
|
| 24 |
-
#include <iomanip>
|
| 25 |
-
#include <fstream>
|
| 26 |
-
|
| 27 |
-
#include "../evaluate.h"
|
| 28 |
-
#include "../position.h"
|
| 29 |
-
#include "../misc.h"
|
| 30 |
-
#include "../uci.h"
|
| 31 |
-
#include "../types.h"
|
| 32 |
-
|
| 33 |
-
#include "evaluate_nnue.h"
|
| 34 |
-
|
| 35 |
-
namespace Stockfish::Eval::NNUE {
|
| 36 |
-
|
| 37 |
-
// Input feature converter
|
| 38 |
-
LargePagePtr<FeatureTransformer> featureTransformer;
|
| 39 |
-
|
| 40 |
-
// Evaluation function
|
| 41 |
-
AlignedPtr<Network> network[LayerStacks];
|
| 42 |
-
|
| 43 |
-
// Evaluation function file name
|
| 44 |
-
std::string fileName;
|
| 45 |
-
std::string netDescription;
|
| 46 |
-
|
| 47 |
-
namespace Detail {
|
| 48 |
-
|
| 49 |
-
// Initialize the evaluation function parameters
|
| 50 |
-
template <typename T>
|
| 51 |
-
void initialize(AlignedPtr<T>& pointer) {
|
| 52 |
-
|
| 53 |
-
pointer.reset(reinterpret_cast<T*>(std_aligned_alloc(alignof(T), sizeof(T))));
|
| 54 |
-
std::memset(pointer.get(), 0, sizeof(T));
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
template <typename T>
|
| 58 |
-
void initialize(LargePagePtr<T>& pointer) {
|
| 59 |
-
|
| 60 |
-
static_assert(alignof(T) <= 4096, "aligned_large_pages_alloc() may fail for such a big alignment requirement of T");
|
| 61 |
-
pointer.reset(reinterpret_cast<T*>(aligned_large_pages_alloc(sizeof(T))));
|
| 62 |
-
std::memset(pointer.get(), 0, sizeof(T));
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
// Read evaluation function parameters
|
| 66 |
-
template <typename T>
|
| 67 |
-
bool read_parameters(std::istream& stream, T& reference) {
|
| 68 |
-
|
| 69 |
-
std::uint32_t header;
|
| 70 |
-
header = read_little_endian<std::uint32_t>(stream);
|
| 71 |
-
if (!stream || header != T::get_hash_value()) return false;
|
| 72 |
-
return reference.read_parameters(stream);
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
// Write evaluation function parameters
|
| 76 |
-
template <typename T>
|
| 77 |
-
bool write_parameters(std::ostream& stream, const T& reference) {
|
| 78 |
-
|
| 79 |
-
write_little_endian<std::uint32_t>(stream, T::get_hash_value());
|
| 80 |
-
return reference.write_parameters(stream);
|
| 81 |
-
}
|
| 82 |
-
|
| 83 |
-
} // namespace Detail
|
| 84 |
-
|
| 85 |
-
// Initialize the evaluation function parameters
|
| 86 |
-
void initialize() {
|
| 87 |
-
|
| 88 |
-
Detail::initialize(featureTransformer);
|
| 89 |
-
for (std::size_t i = 0; i < LayerStacks; ++i)
|
| 90 |
-
Detail::initialize(network[i]);
|
| 91 |
-
}
|
| 92 |
-
|
| 93 |
-
// Read network header
|
| 94 |
-
bool read_header(std::istream& stream, std::uint32_t* hashValue, std::string* desc)
|
| 95 |
-
{
|
| 96 |
-
std::uint32_t version, size;
|
| 97 |
-
|
| 98 |
-
version = read_little_endian<std::uint32_t>(stream);
|
| 99 |
-
*hashValue = read_little_endian<std::uint32_t>(stream);
|
| 100 |
-
size = read_little_endian<std::uint32_t>(stream);
|
| 101 |
-
if (!stream || version != Version) return false;
|
| 102 |
-
desc->resize(size);
|
| 103 |
-
stream.read(&(*desc)[0], size);
|
| 104 |
-
return !stream.fail();
|
| 105 |
-
}
|
| 106 |
-
|
| 107 |
-
// Write network header
|
| 108 |
-
bool write_header(std::ostream& stream, std::uint32_t hashValue, const std::string& desc)
|
| 109 |
-
{
|
| 110 |
-
write_little_endian<std::uint32_t>(stream, Version);
|
| 111 |
-
write_little_endian<std::uint32_t>(stream, hashValue);
|
| 112 |
-
write_little_endian<std::uint32_t>(stream, desc.size());
|
| 113 |
-
stream.write(&desc[0], desc.size());
|
| 114 |
-
return !stream.fail();
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
// Read network parameters
|
| 118 |
-
bool read_parameters(std::istream& stream) {
|
| 119 |
-
|
| 120 |
-
std::uint32_t hashValue;
|
| 121 |
-
if (!read_header(stream, &hashValue, &netDescription)) return false;
|
| 122 |
-
if (hashValue != HashValue) return false;
|
| 123 |
-
if (!Detail::read_parameters(stream, *featureTransformer)) return false;
|
| 124 |
-
for (std::size_t i = 0; i < LayerStacks; ++i)
|
| 125 |
-
if (!Detail::read_parameters(stream, *(network[i]))) return false;
|
| 126 |
-
return stream && stream.peek() == std::ios::traits_type::eof();
|
| 127 |
-
}
|
| 128 |
-
|
| 129 |
-
// Write network parameters
|
| 130 |
-
bool write_parameters(std::ostream& stream) {
|
| 131 |
-
|
| 132 |
-
if (!write_header(stream, HashValue, netDescription)) return false;
|
| 133 |
-
if (!Detail::write_parameters(stream, *featureTransformer)) return false;
|
| 134 |
-
for (std::size_t i = 0; i < LayerStacks; ++i)
|
| 135 |
-
if (!Detail::write_parameters(stream, *(network[i]))) return false;
|
| 136 |
-
return (bool)stream;
|
| 137 |
-
}
|
| 138 |
-
|
| 139 |
-
// Evaluation function. Perform differential calculation.
|
| 140 |
-
Value evaluate(const Position& pos, bool adjusted) {
|
| 141 |
-
|
| 142 |
-
// We manually align the arrays on the stack because with gcc < 9.3
|
| 143 |
-
// overaligning stack variables with alignas() doesn't work correctly.
|
| 144 |
-
|
| 145 |
-
constexpr uint64_t alignment = CacheLineSize;
|
| 146 |
-
|
| 147 |
-
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
| 148 |
-
TransformedFeatureType transformedFeaturesUnaligned[
|
| 149 |
-
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
| 150 |
-
char bufferUnaligned[Network::BufferSize + alignment];
|
| 151 |
-
|
| 152 |
-
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
| 153 |
-
auto* buffer = align_ptr_up<alignment>(&bufferUnaligned[0]);
|
| 154 |
-
#else
|
| 155 |
-
alignas(alignment)
|
| 156 |
-
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
| 157 |
-
alignas(alignment) char buffer[Network::BufferSize];
|
| 158 |
-
#endif
|
| 159 |
-
|
| 160 |
-
ASSERT_ALIGNED(transformedFeatures, alignment);
|
| 161 |
-
ASSERT_ALIGNED(buffer, alignment);
|
| 162 |
-
|
| 163 |
-
const std::size_t bucket = std::min((pos.count<ALL_PIECES>() - 1) * 8 / currentNnueVariant->nnueMaxPieces, 7);
|
| 164 |
-
const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
|
| 165 |
-
const auto output = network[bucket]->propagate(transformedFeatures, buffer);
|
| 166 |
-
|
| 167 |
-
int materialist = psqt;
|
| 168 |
-
int positional = output[0];
|
| 169 |
-
|
| 170 |
-
int delta_npm = abs(pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK));
|
| 171 |
-
int entertainment = (adjusted && delta_npm <= BishopValueMg - KnightValueMg ? 7 : 0);
|
| 172 |
-
|
| 173 |
-
int A = 128 - entertainment;
|
| 174 |
-
int B = 128 + entertainment;
|
| 175 |
-
|
| 176 |
-
int sum = (A * materialist + B * positional) / 128;
|
| 177 |
-
|
| 178 |
-
return static_cast<Value>( sum / OutputScale );
|
| 179 |
-
}
|
| 180 |
-
|
| 181 |
-
struct NnueEvalTrace {
|
| 182 |
-
static_assert(LayerStacks == PSQTBuckets);
|
| 183 |
-
|
| 184 |
-
Value psqt[LayerStacks];
|
| 185 |
-
Value positional[LayerStacks];
|
| 186 |
-
std::size_t correctBucket;
|
| 187 |
-
};
|
| 188 |
-
|
| 189 |
-
static NnueEvalTrace trace_evaluate(const Position& pos) {
|
| 190 |
-
|
| 191 |
-
// We manually align the arrays on the stack because with gcc < 9.3
|
| 192 |
-
// overaligning stack variables with alignas() doesn't work correctly.
|
| 193 |
-
|
| 194 |
-
constexpr uint64_t alignment = CacheLineSize;
|
| 195 |
-
|
| 196 |
-
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
| 197 |
-
TransformedFeatureType transformedFeaturesUnaligned[
|
| 198 |
-
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
| 199 |
-
char bufferUnaligned[Network::BufferSize + alignment];
|
| 200 |
-
|
| 201 |
-
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
| 202 |
-
auto* buffer = align_ptr_up<alignment>(&bufferUnaligned[0]);
|
| 203 |
-
#else
|
| 204 |
-
alignas(alignment)
|
| 205 |
-
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
| 206 |
-
alignas(alignment) char buffer[Network::BufferSize];
|
| 207 |
-
#endif
|
| 208 |
-
|
| 209 |
-
ASSERT_ALIGNED(transformedFeatures, alignment);
|
| 210 |
-
ASSERT_ALIGNED(buffer, alignment);
|
| 211 |
-
|
| 212 |
-
NnueEvalTrace t{};
|
| 213 |
-
t.correctBucket = std::min((pos.count<ALL_PIECES>() - 1) * 8 / currentNnueVariant->nnueMaxPieces, 7);
|
| 214 |
-
for (std::size_t bucket = 0; bucket < LayerStacks; ++bucket) {
|
| 215 |
-
const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
|
| 216 |
-
const auto output = network[bucket]->propagate(transformedFeatures, buffer);
|
| 217 |
-
|
| 218 |
-
int materialist = psqt;
|
| 219 |
-
int positional = output[0];
|
| 220 |
-
|
| 221 |
-
t.psqt[bucket] = static_cast<Value>( materialist / OutputScale );
|
| 222 |
-
t.positional[bucket] = static_cast<Value>( positional / OutputScale );
|
| 223 |
-
}
|
| 224 |
-
|
| 225 |
-
return t;
|
| 226 |
-
}
|
| 227 |
-
|
| 228 |
-
// Requires the buffer to have capacity for at least 5 values
|
| 229 |
-
static void format_cp_compact(Value v, char* buffer) {
|
| 230 |
-
|
| 231 |
-
buffer[0] = (v < 0 ? '-' : v > 0 ? '+' : ' ');
|
| 232 |
-
|
| 233 |
-
int cp = std::abs(100 * v / PawnValueEg);
|
| 234 |
-
|
| 235 |
-
if (cp >= 10000)
|
| 236 |
-
{
|
| 237 |
-
buffer[1] = '0' + cp / 10000; cp %= 10000;
|
| 238 |
-
buffer[2] = '0' + cp / 1000; cp %= 1000;
|
| 239 |
-
buffer[3] = '0' + cp / 100; cp %= 100;
|
| 240 |
-
buffer[4] = ' ';
|
| 241 |
-
}
|
| 242 |
-
else if (cp >= 1000)
|
| 243 |
-
{
|
| 244 |
-
buffer[1] = '0' + cp / 1000; cp %= 1000;
|
| 245 |
-
buffer[2] = '0' + cp / 100; cp %= 100;
|
| 246 |
-
buffer[3] = '.';
|
| 247 |
-
buffer[4] = '0' + cp / 10;
|
| 248 |
-
}
|
| 249 |
-
else
|
| 250 |
-
{
|
| 251 |
-
buffer[1] = '0' + cp / 100; cp %= 100;
|
| 252 |
-
buffer[2] = '.';
|
| 253 |
-
buffer[3] = '0' + cp / 10; cp %= 10;
|
| 254 |
-
buffer[4] = '0' + cp / 1;
|
| 255 |
-
}
|
| 256 |
-
}
|
| 257 |
-
|
| 258 |
-
// Requires the buffer to have capacity for at least 7 values
|
| 259 |
-
static void format_cp_aligned_dot(Value v, char* buffer) {
|
| 260 |
-
buffer[0] = (v < 0 ? '-' : v > 0 ? '+' : ' ');
|
| 261 |
-
|
| 262 |
-
int cp = std::abs(100 * v / PawnValueEg);
|
| 263 |
-
|
| 264 |
-
if (cp >= 10000)
|
| 265 |
-
{
|
| 266 |
-
buffer[1] = '0' + cp / 10000; cp %= 10000;
|
| 267 |
-
buffer[2] = '0' + cp / 1000; cp %= 1000;
|
| 268 |
-
buffer[3] = '0' + cp / 100; cp %= 100;
|
| 269 |
-
buffer[4] = '.';
|
| 270 |
-
buffer[5] = '0' + cp / 10; cp %= 10;
|
| 271 |
-
buffer[6] = '0' + cp;
|
| 272 |
-
}
|
| 273 |
-
else if (cp >= 1000)
|
| 274 |
-
{
|
| 275 |
-
buffer[1] = ' ';
|
| 276 |
-
buffer[2] = '0' + cp / 1000; cp %= 1000;
|
| 277 |
-
buffer[3] = '0' + cp / 100; cp %= 100;
|
| 278 |
-
buffer[4] = '.';
|
| 279 |
-
buffer[5] = '0' + cp / 10; cp %= 10;
|
| 280 |
-
buffer[6] = '0' + cp;
|
| 281 |
-
}
|
| 282 |
-
else
|
| 283 |
-
{
|
| 284 |
-
buffer[1] = ' ';
|
| 285 |
-
buffer[2] = ' ';
|
| 286 |
-
buffer[3] = '0' + cp / 100; cp %= 100;
|
| 287 |
-
buffer[4] = '.';
|
| 288 |
-
buffer[5] = '0' + cp / 10; cp %= 10;
|
| 289 |
-
buffer[6] = '0' + cp / 1;
|
| 290 |
-
}
|
| 291 |
-
}
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
// trace() returns a string with the value of each piece on a board,
|
| 295 |
-
// and a table for (PSQT, Layers) values bucket by bucket.
|
| 296 |
-
|
| 297 |
-
std::string trace(Position& pos) {
|
| 298 |
-
|
| 299 |
-
std::stringstream ss;
|
| 300 |
-
|
| 301 |
-
char board[3*RANK_NB+1][8*FILE_NB+2];
|
| 302 |
-
std::memset(board, ' ', sizeof(board));
|
| 303 |
-
for (int row = 0; row < 3*pos.ranks()+1; ++row)
|
| 304 |
-
board[row][8*FILE_NB+1] = '\0';
|
| 305 |
-
|
| 306 |
-
// A lambda to output one box of the board
|
| 307 |
-
auto writeSquare = [&board, &pos](File file, Rank rank, Piece pc, Value value) {
|
| 308 |
-
|
| 309 |
-
const int x = ((int)file) * 8;
|
| 310 |
-
const int y = (pos.max_rank() - (int)rank) * 3;
|
| 311 |
-
for (int i = 1; i < 8; ++i)
|
| 312 |
-
board[y][x+i] = board[y+3][x+i] = '-';
|
| 313 |
-
for (int i = 1; i < 3; ++i)
|
| 314 |
-
board[y+i][x] = board[y+i][x+8] = '|';
|
| 315 |
-
board[y][x] = board[y][x+8] = board[y+3][x+8] = board[y+3][x] = '+';
|
| 316 |
-
if (pc != NO_PIECE)
|
| 317 |
-
board[y+1][x+4] = pos.piece_to_char()[pc];
|
| 318 |
-
if (value != VALUE_NONE)
|
| 319 |
-
format_cp_compact(value, &board[y+2][x+2]);
|
| 320 |
-
};
|
| 321 |
-
|
| 322 |
-
// We estimate the value of each piece by doing a differential evaluation from
|
| 323 |
-
// the current base eval, simulating the removal of the piece from its square.
|
| 324 |
-
Value base = evaluate(pos);
|
| 325 |
-
base = pos.side_to_move() == WHITE ? base : -base;
|
| 326 |
-
|
| 327 |
-
for (File f = FILE_A; f <= pos.max_file(); ++f)
|
| 328 |
-
for (Rank r = RANK_1; r <= pos.max_rank(); ++r)
|
| 329 |
-
{
|
| 330 |
-
Square sq = make_square(f, r);
|
| 331 |
-
Piece pc = pos.piece_on(sq);
|
| 332 |
-
Piece unpromotedPc = pos.unpromoted_piece_on(sq);
|
| 333 |
-
bool isPromoted = pos.is_promoted(sq);
|
| 334 |
-
Value v = VALUE_NONE;
|
| 335 |
-
|
| 336 |
-
if (pc != NO_PIECE && type_of(pc) != pos.nnue_king())
|
| 337 |
-
{
|
| 338 |
-
auto st = pos.state();
|
| 339 |
-
|
| 340 |
-
pos.remove_piece(sq);
|
| 341 |
-
st->accumulator.computed[WHITE] = false;
|
| 342 |
-
st->accumulator.computed[BLACK] = false;
|
| 343 |
-
|
| 344 |
-
Value eval = evaluate(pos);
|
| 345 |
-
eval = pos.side_to_move() == WHITE ? eval : -eval;
|
| 346 |
-
v = base - eval;
|
| 347 |
-
|
| 348 |
-
pos.put_piece(pc, sq, isPromoted, unpromotedPc);
|
| 349 |
-
st->accumulator.computed[WHITE] = false;
|
| 350 |
-
st->accumulator.computed[BLACK] = false;
|
| 351 |
-
}
|
| 352 |
-
|
| 353 |
-
writeSquare(f, r, pc, v);
|
| 354 |
-
}
|
| 355 |
-
|
| 356 |
-
ss << " NNUE derived piece values:\n";
|
| 357 |
-
for (int row = 0; row < 3*pos.ranks()+1; ++row)
|
| 358 |
-
ss << board[row] << '\n';
|
| 359 |
-
ss << '\n';
|
| 360 |
-
|
| 361 |
-
auto t = trace_evaluate(pos);
|
| 362 |
-
|
| 363 |
-
ss << " NNUE network contributions "
|
| 364 |
-
<< (pos.side_to_move() == WHITE ? "(White to move)" : "(Black to move)") << std::endl
|
| 365 |
-
<< "+------------+------------+------------+------------+\n"
|
| 366 |
-
<< "| Bucket | Material | Positional | Total |\n"
|
| 367 |
-
<< "| | (PSQT) | (Layers) | |\n"
|
| 368 |
-
<< "+------------+------------+------------+------------+\n";
|
| 369 |
-
|
| 370 |
-
for (std::size_t bucket = 0; bucket < LayerStacks; ++bucket)
|
| 371 |
-
{
|
| 372 |
-
char buffer[3][8];
|
| 373 |
-
std::memset(buffer, '\0', sizeof(buffer));
|
| 374 |
-
|
| 375 |
-
format_cp_aligned_dot(t.psqt[bucket], buffer[0]);
|
| 376 |
-
format_cp_aligned_dot(t.positional[bucket], buffer[1]);
|
| 377 |
-
format_cp_aligned_dot(t.psqt[bucket] + t.positional[bucket], buffer[2]);
|
| 378 |
-
|
| 379 |
-
ss << "| " << bucket << " "
|
| 380 |
-
<< " | " << buffer[0] << " "
|
| 381 |
-
<< " | " << buffer[1] << " "
|
| 382 |
-
<< " | " << buffer[2] << " "
|
| 383 |
-
<< " |";
|
| 384 |
-
if (bucket == t.correctBucket)
|
| 385 |
-
ss << " <-- this bucket is used";
|
| 386 |
-
ss << '\n';
|
| 387 |
-
}
|
| 388 |
-
|
| 389 |
-
ss << "+------------+------------+------------+------------+\n";
|
| 390 |
-
|
| 391 |
-
return ss.str();
|
| 392 |
-
}
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
// Load eval, from a file stream or a memory stream
|
| 396 |
-
bool load_eval(std::string name, std::istream& stream) {
|
| 397 |
-
|
| 398 |
-
initialize();
|
| 399 |
-
fileName = name;
|
| 400 |
-
return read_parameters(stream);
|
| 401 |
-
}
|
| 402 |
-
|
| 403 |
-
// Save eval, to a file stream or a memory stream
|
| 404 |
-
bool save_eval(std::ostream& stream) {
|
| 405 |
-
|
| 406 |
-
if (fileName.empty())
|
| 407 |
-
return false;
|
| 408 |
-
|
| 409 |
-
return write_parameters(stream);
|
| 410 |
-
}
|
| 411 |
-
|
| 412 |
-
/// Save eval, to a file given by its name
|
| 413 |
-
bool save_eval(const std::optional<std::string>& filename) {
|
| 414 |
-
|
| 415 |
-
std::string actualFilename;
|
| 416 |
-
std::string msg;
|
| 417 |
-
|
| 418 |
-
if (filename.has_value())
|
| 419 |
-
actualFilename = filename.value();
|
| 420 |
-
else
|
| 421 |
-
{
|
| 422 |
-
if (eval_file_loaded != EvalFileDefaultName)
|
| 423 |
-
{
|
| 424 |
-
msg = "Failed to export a net. A non-embedded net can only be saved if the filename is specified";
|
| 425 |
-
|
| 426 |
-
sync_cout << msg << sync_endl;
|
| 427 |
-
return false;
|
| 428 |
-
}
|
| 429 |
-
actualFilename = EvalFileDefaultName;
|
| 430 |
-
}
|
| 431 |
-
|
| 432 |
-
std::ofstream stream(actualFilename, std::ios_base::binary);
|
| 433 |
-
bool saved = save_eval(stream);
|
| 434 |
-
|
| 435 |
-
msg = saved ? "Network saved successfully to " + actualFilename
|
| 436 |
-
: "Failed to export a net";
|
| 437 |
-
|
| 438 |
-
sync_cout << msg << sync_endl;
|
| 439 |
-
return saved;
|
| 440 |
-
}
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
} // namespace Stockfish::Eval::NNUE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/evaluate_nnue.h
DELETED
|
@@ -1,59 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
// header used in NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#ifndef NNUE_EVALUATE_NNUE_H_INCLUDED
|
| 22 |
-
#define NNUE_EVALUATE_NNUE_H_INCLUDED
|
| 23 |
-
|
| 24 |
-
#include "nnue_feature_transformer.h"
|
| 25 |
-
|
| 26 |
-
#include <memory>
|
| 27 |
-
|
| 28 |
-
namespace Stockfish::Eval::NNUE {
|
| 29 |
-
|
| 30 |
-
// Hash value of evaluation function structure
|
| 31 |
-
constexpr std::uint32_t HashValue =
|
| 32 |
-
FeatureTransformer::get_hash_value() ^ Network::get_hash_value();
|
| 33 |
-
|
| 34 |
-
// Deleter for automating release of memory area
|
| 35 |
-
template <typename T>
|
| 36 |
-
struct AlignedDeleter {
|
| 37 |
-
void operator()(T* ptr) const {
|
| 38 |
-
ptr->~T();
|
| 39 |
-
std_aligned_free(ptr);
|
| 40 |
-
}
|
| 41 |
-
};
|
| 42 |
-
|
| 43 |
-
template <typename T>
|
| 44 |
-
struct LargePageDeleter {
|
| 45 |
-
void operator()(T* ptr) const {
|
| 46 |
-
ptr->~T();
|
| 47 |
-
aligned_large_pages_free(ptr);
|
| 48 |
-
}
|
| 49 |
-
};
|
| 50 |
-
|
| 51 |
-
template <typename T>
|
| 52 |
-
using AlignedPtr = std::unique_ptr<T, AlignedDeleter<T>>;
|
| 53 |
-
|
| 54 |
-
template <typename T>
|
| 55 |
-
using LargePagePtr = std::unique_ptr<T, LargePageDeleter<T>>;
|
| 56 |
-
|
| 57 |
-
} // namespace Stockfish::Eval::NNUE
|
| 58 |
-
|
| 59 |
-
#endif // #ifndef NNUE_EVALUATE_NNUE_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/features/half_ka_v2.cpp
DELETED
|
@@ -1,90 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
//Definition of input features HalfKAv2 of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#include "half_ka_v2.h"
|
| 22 |
-
|
| 23 |
-
#include "../../position.h"
|
| 24 |
-
|
| 25 |
-
namespace Stockfish::Eval::NNUE::Features {
|
| 26 |
-
|
| 27 |
-
// Map square to numbering on 8x8 board
|
| 28 |
-
constexpr Square to_chess_square(Square s) {
|
| 29 |
-
return Square(s - rank_of(s) * (FILE_MAX - FILE_H));
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
// Orient a square according to perspective (rotates by 180 for black)
|
| 33 |
-
inline Square HalfKAv2::orient(Color perspective, Square s) {
|
| 34 |
-
return Square(int(to_chess_square(s)) ^ (bool(perspective) * 56));
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
// Index of a feature for a given king position and another piece on some square
|
| 38 |
-
inline IndexType HalfKAv2::make_index(Color perspective, Square s, Piece pc, Square ksq) {
|
| 39 |
-
return IndexType(orient(perspective, s) + PieceSquareIndex[perspective][pc] + PS_NB * ksq);
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
// Get a list of indices for active features
|
| 43 |
-
void HalfKAv2::append_active_indices(
|
| 44 |
-
const Position& pos,
|
| 45 |
-
Color perspective,
|
| 46 |
-
ValueListInserter<IndexType> active
|
| 47 |
-
) {
|
| 48 |
-
Square ksq = orient(perspective, pos.square<KING>(perspective));
|
| 49 |
-
Bitboard bb = pos.pieces();
|
| 50 |
-
while (bb)
|
| 51 |
-
{
|
| 52 |
-
Square s = pop_lsb(bb);
|
| 53 |
-
active.push_back(make_index(perspective, s, pos.piece_on(s), ksq));
|
| 54 |
-
}
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
// append_changed_indices() : get a list of indices for recently changed features
|
| 59 |
-
|
| 60 |
-
void HalfKAv2::append_changed_indices(
|
| 61 |
-
Square ksq,
|
| 62 |
-
StateInfo* st,
|
| 63 |
-
Color perspective,
|
| 64 |
-
ValueListInserter<IndexType> removed,
|
| 65 |
-
ValueListInserter<IndexType> added
|
| 66 |
-
) {
|
| 67 |
-
const auto& dp = st->dirtyPiece;
|
| 68 |
-
Square oriented_ksq = orient(perspective, ksq);
|
| 69 |
-
for (int i = 0; i < dp.dirty_num; ++i) {
|
| 70 |
-
Piece pc = dp.piece[i];
|
| 71 |
-
if (dp.from[i] != SQ_NONE)
|
| 72 |
-
removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq));
|
| 73 |
-
if (dp.to[i] != SQ_NONE)
|
| 74 |
-
added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq));
|
| 75 |
-
}
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
int HalfKAv2::update_cost(StateInfo* st) {
|
| 79 |
-
return st->dirtyPiece.dirty_num;
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
int HalfKAv2::refresh_cost(const Position& pos) {
|
| 83 |
-
return pos.count<ALL_PIECES>();
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
bool HalfKAv2::requires_refresh(StateInfo* st, Color perspective) {
|
| 87 |
-
return st->dirtyPiece.piece[0] == make_piece(perspective, KING);
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
-
} // namespace Stockfish::Eval::NNUE::Features
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/features/half_ka_v2.h
DELETED
|
@@ -1,152 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
//Definition of input features HalfKAv2 of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#ifndef NNUE_FEATURES_HALF_KA_V2_H_INCLUDED
|
| 22 |
-
#define NNUE_FEATURES_HALF_KA_V2_H_INCLUDED
|
| 23 |
-
|
| 24 |
-
#include "../nnue_common.h"
|
| 25 |
-
|
| 26 |
-
#include "../../evaluate.h"
|
| 27 |
-
#include "../../misc.h"
|
| 28 |
-
|
| 29 |
-
namespace Stockfish {
|
| 30 |
-
struct StateInfo;
|
| 31 |
-
}
|
| 32 |
-
|
| 33 |
-
namespace Stockfish::Eval::NNUE::Features {
|
| 34 |
-
|
| 35 |
-
// Feature HalfKAv2: Combination of the position of own king
|
| 36 |
-
// and the position of pieces
|
| 37 |
-
class HalfKAv2 {
|
| 38 |
-
|
| 39 |
-
// unique number for each piece type on each square
|
| 40 |
-
enum {
|
| 41 |
-
PS_NONE = 0,
|
| 42 |
-
PS_W_PAWN = 0,
|
| 43 |
-
PS_B_PAWN = 1 * SQUARE_NB_CHESS,
|
| 44 |
-
PS_W_KNIGHT = 2 * SQUARE_NB_CHESS,
|
| 45 |
-
PS_B_KNIGHT = 3 * SQUARE_NB_CHESS,
|
| 46 |
-
PS_W_BISHOP = 4 * SQUARE_NB_CHESS,
|
| 47 |
-
PS_B_BISHOP = 5 * SQUARE_NB_CHESS,
|
| 48 |
-
PS_W_ROOK = 6 * SQUARE_NB_CHESS,
|
| 49 |
-
PS_B_ROOK = 7 * SQUARE_NB_CHESS,
|
| 50 |
-
PS_W_QUEEN = 8 * SQUARE_NB_CHESS,
|
| 51 |
-
PS_B_QUEEN = 9 * SQUARE_NB_CHESS,
|
| 52 |
-
PS_KING = 10 * SQUARE_NB_CHESS,
|
| 53 |
-
PS_NB = 11 * SQUARE_NB_CHESS
|
| 54 |
-
};
|
| 55 |
-
|
| 56 |
-
static constexpr uint32_t PieceSquareIndex[COLOR_NB][PIECE_NB] = {
|
| 57 |
-
// convention: W - us, B - them
|
| 58 |
-
// viewed from other side, W and B are reversed
|
| 59 |
-
{
|
| 60 |
-
PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_NONE, PS_NONE,
|
| 61 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 62 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 63 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 64 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 65 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 66 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 67 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
|
| 68 |
-
|
| 69 |
-
PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_NONE, PS_NONE,
|
| 70 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 71 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 72 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 73 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 74 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 75 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 76 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
|
| 77 |
-
},
|
| 78 |
-
|
| 79 |
-
{
|
| 80 |
-
PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_NONE, PS_NONE,
|
| 81 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 82 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 83 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 84 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 85 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 86 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 87 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
|
| 88 |
-
|
| 89 |
-
PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_NONE, PS_NONE,
|
| 90 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 91 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 92 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 93 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 94 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 95 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
|
| 96 |
-
PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
|
| 97 |
-
}
|
| 98 |
-
};
|
| 99 |
-
// Check that the fragile array definition is correct
|
| 100 |
-
static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, PAWN)] == PS_W_PAWN);
|
| 101 |
-
static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, KING)] == PS_KING);
|
| 102 |
-
static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, PAWN)] == PS_B_PAWN);
|
| 103 |
-
static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, KING)] == PS_KING);
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
// Orient a square according to perspective (rotates by 180 for black)
|
| 107 |
-
static Square orient(Color perspective, Square s);
|
| 108 |
-
|
| 109 |
-
// Index of a feature for a given king position and another piece on some square
|
| 110 |
-
static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq);
|
| 111 |
-
|
| 112 |
-
public:
|
| 113 |
-
// Feature name
|
| 114 |
-
static constexpr const char* Name = "HalfKAv2(Friend)";
|
| 115 |
-
|
| 116 |
-
// Hash value embedded in the evaluation file
|
| 117 |
-
static constexpr std::uint32_t HashValue = 0x5f234cb8u;
|
| 118 |
-
|
| 119 |
-
// Number of feature dimensions
|
| 120 |
-
static constexpr IndexType Dimensions =
|
| 121 |
-
static_cast<IndexType>(SQUARE_NB_CHESS) * static_cast<IndexType>(PS_NB);
|
| 122 |
-
|
| 123 |
-
// Maximum number of simultaneously active features.
|
| 124 |
-
static constexpr IndexType MaxActiveDimensions = 32;
|
| 125 |
-
|
| 126 |
-
// Get a list of indices for active features
|
| 127 |
-
static void append_active_indices(
|
| 128 |
-
const Position& pos,
|
| 129 |
-
Color perspective,
|
| 130 |
-
ValueListInserter<IndexType> active);
|
| 131 |
-
|
| 132 |
-
// Get a list of indices for recently changed features
|
| 133 |
-
static void append_changed_indices(
|
| 134 |
-
Square ksq,
|
| 135 |
-
StateInfo* st,
|
| 136 |
-
Color perspective,
|
| 137 |
-
ValueListInserter<IndexType> removed,
|
| 138 |
-
ValueListInserter<IndexType> added);
|
| 139 |
-
|
| 140 |
-
// Returns the cost of updating one perspective, the most costly one.
|
| 141 |
-
// Assumes no refresh needed.
|
| 142 |
-
static int update_cost(StateInfo* st);
|
| 143 |
-
static int refresh_cost(const Position& pos);
|
| 144 |
-
|
| 145 |
-
// Returns whether the change stored in this StateInfo means that
|
| 146 |
-
// a full accumulator refresh is required.
|
| 147 |
-
static bool requires_refresh(StateInfo* st, Color perspective);
|
| 148 |
-
};
|
| 149 |
-
|
| 150 |
-
} // namespace Stockfish::Eval::NNUE::Features
|
| 151 |
-
|
| 152 |
-
#endif // #ifndef NNUE_FEATURES_HALF_KA_V2_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/features/half_ka_v2_variants.cpp
DELETED
|
@@ -1,112 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
//Definition of input features HalfKAv2 of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#include "half_ka_v2_variants.h"
|
| 22 |
-
|
| 23 |
-
#include "../../position.h"
|
| 24 |
-
|
| 25 |
-
namespace Stockfish::Eval::NNUE::Features {
|
| 26 |
-
|
| 27 |
-
// Map square to numbering on variant board
|
| 28 |
-
inline Square to_variant_square(Square s, const Position& pos) {
|
| 29 |
-
return Square(s - rank_of(s) * (FILE_MAX - pos.max_file()));
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
// Orient a square according to perspective (rotates by 180 for black)
|
| 33 |
-
// Missing kings map to index 0 (SQ_A1)
|
| 34 |
-
inline Square HalfKAv2Variants::orient(Color perspective, Square s, const Position& pos) {
|
| 35 |
-
return s != SQ_NONE ? to_variant_square( perspective == WHITE || (pos.flag_region(BLACK) & Rank8BB) ? s
|
| 36 |
-
: flip_rank(s, pos.max_rank()), pos) : SQ_A1;
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
// Index of a feature for a given king position and another piece on some square
|
| 40 |
-
inline IndexType HalfKAv2Variants::make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos) {
|
| 41 |
-
return IndexType(orient(perspective, s, pos) + pos.nnue_piece_square_index(perspective, pc) + pos.nnue_king_square_index(ksq));
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
// Index of a feature for a given king position and another piece on some square
|
| 45 |
-
inline IndexType HalfKAv2Variants::make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos) {
|
| 46 |
-
return IndexType(handCount + pos.nnue_piece_hand_index(perspective, pc) + pos.nnue_king_square_index(ksq));
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
// Get a list of indices for active features
|
| 50 |
-
void HalfKAv2Variants::append_active_indices(
|
| 51 |
-
const Position& pos,
|
| 52 |
-
Color perspective,
|
| 53 |
-
ValueListInserter<IndexType> active
|
| 54 |
-
) {
|
| 55 |
-
Square oriented_ksq = orient(perspective, pos.nnue_king_square(perspective), pos);
|
| 56 |
-
Bitboard bb = pos.pieces(WHITE) | pos.pieces(BLACK);
|
| 57 |
-
while (bb)
|
| 58 |
-
{
|
| 59 |
-
Square s = pop_lsb(bb);
|
| 60 |
-
active.push_back(make_index(perspective, s, pos.piece_on(s), oriented_ksq, pos));
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
// Indices for pieces in hand
|
| 64 |
-
if (pos.nnue_use_pockets())
|
| 65 |
-
for (Color c : {WHITE, BLACK})
|
| 66 |
-
for (PieceSet ps = pos.piece_types(); ps;)
|
| 67 |
-
{
|
| 68 |
-
PieceType pt = pop_lsb(ps);
|
| 69 |
-
for (int i = 0; i < pos.count_in_hand(c, pt); i++)
|
| 70 |
-
active.push_back(make_index(perspective, i, make_piece(c, pt), oriented_ksq, pos));
|
| 71 |
-
}
|
| 72 |
-
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
// append_changed_indices() : get a list of indices for recently changed features
|
| 76 |
-
|
| 77 |
-
void HalfKAv2Variants::append_changed_indices(
|
| 78 |
-
Square ksq,
|
| 79 |
-
StateInfo* st,
|
| 80 |
-
Color perspective,
|
| 81 |
-
ValueListInserter<IndexType> removed,
|
| 82 |
-
ValueListInserter<IndexType> added,
|
| 83 |
-
const Position& pos
|
| 84 |
-
) {
|
| 85 |
-
const auto& dp = st->dirtyPiece;
|
| 86 |
-
Square oriented_ksq = orient(perspective, ksq, pos);
|
| 87 |
-
for (int i = 0; i < dp.dirty_num; ++i) {
|
| 88 |
-
Piece pc = dp.piece[i];
|
| 89 |
-
if (dp.from[i] != SQ_NONE)
|
| 90 |
-
removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq, pos));
|
| 91 |
-
else if (dp.handPiece[i] != NO_PIECE)
|
| 92 |
-
removed.push_back(make_index(perspective, dp.handCount[i] - 1, dp.handPiece[i], oriented_ksq, pos));
|
| 93 |
-
if (dp.to[i] != SQ_NONE)
|
| 94 |
-
added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq, pos));
|
| 95 |
-
else if (dp.handPiece[i] != NO_PIECE)
|
| 96 |
-
added.push_back(make_index(perspective, dp.handCount[i] - 1, dp.handPiece[i], oriented_ksq, pos));
|
| 97 |
-
}
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
int HalfKAv2Variants::update_cost(StateInfo* st) {
|
| 101 |
-
return st->dirtyPiece.dirty_num;
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
int HalfKAv2Variants::refresh_cost(const Position& pos) {
|
| 105 |
-
return pos.count<ALL_PIECES>();
|
| 106 |
-
}
|
| 107 |
-
|
| 108 |
-
bool HalfKAv2Variants::requires_refresh(StateInfo* st, Color perspective, const Position& pos) {
|
| 109 |
-
return st->dirtyPiece.piece[0] == make_piece(perspective, pos.nnue_king()) || pos.flip_enclosed_pieces();
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
} // namespace Stockfish::Eval::NNUE::Features
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/features/half_ka_v2_variants.h
DELETED
|
@@ -1,94 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
//Definition of input features HalfKAv2 of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#ifndef NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
|
| 22 |
-
#define NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
|
| 23 |
-
|
| 24 |
-
#include "../nnue_common.h"
|
| 25 |
-
|
| 26 |
-
#include "../../evaluate.h"
|
| 27 |
-
#include "../../misc.h"
|
| 28 |
-
|
| 29 |
-
#include "half_ka_v2.h"
|
| 30 |
-
|
| 31 |
-
namespace Stockfish {
|
| 32 |
-
struct StateInfo;
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
namespace Stockfish::Eval::NNUE::Features {
|
| 36 |
-
|
| 37 |
-
// Feature HalfKAv2: Combination of the position of own king
|
| 38 |
-
// and the position of pieces
|
| 39 |
-
class HalfKAv2Variants {
|
| 40 |
-
|
| 41 |
-
// Orient a square according to perspective (rotates by 180 for black)
|
| 42 |
-
static Square orient(Color perspective, Square s, const Position& pos);
|
| 43 |
-
|
| 44 |
-
// Index of a feature for a given king position and another piece on some square
|
| 45 |
-
static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos);
|
| 46 |
-
|
| 47 |
-
// Index of a feature for a given king position and another piece in hand
|
| 48 |
-
static IndexType make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos);
|
| 49 |
-
|
| 50 |
-
public:
|
| 51 |
-
// Feature name
|
| 52 |
-
static constexpr const char* Name = "HalfKAv2(Friend)";
|
| 53 |
-
|
| 54 |
-
// Hash value embedded in the evaluation file
|
| 55 |
-
static constexpr std::uint32_t HashValue = 0x5f234cb8u;
|
| 56 |
-
|
| 57 |
-
// Number of feature dimensions
|
| 58 |
-
static constexpr IndexType Dimensions = static_cast<IndexType>(SQUARE_NB) * static_cast<IndexType>(SQUARE_NB) * 19;
|
| 59 |
-
|
| 60 |
-
static IndexType get_dimensions() {
|
| 61 |
-
return currentNnueVariant->nnueDimensions;
|
| 62 |
-
}
|
| 63 |
-
|
| 64 |
-
// Maximum number of simultaneously active features.
|
| 65 |
-
static constexpr IndexType MaxActiveDimensions = 128;
|
| 66 |
-
|
| 67 |
-
// Get a list of indices for active features
|
| 68 |
-
static void append_active_indices(
|
| 69 |
-
const Position& pos,
|
| 70 |
-
Color perspective,
|
| 71 |
-
ValueListInserter<IndexType> active);
|
| 72 |
-
|
| 73 |
-
// Get a list of indices for recently changed features
|
| 74 |
-
static void append_changed_indices(
|
| 75 |
-
Square ksq,
|
| 76 |
-
StateInfo* st,
|
| 77 |
-
Color perspective,
|
| 78 |
-
ValueListInserter<IndexType> removed,
|
| 79 |
-
ValueListInserter<IndexType> added,
|
| 80 |
-
const Position& pos);
|
| 81 |
-
|
| 82 |
-
// Returns the cost of updating one perspective, the most costly one.
|
| 83 |
-
// Assumes no refresh needed.
|
| 84 |
-
static int update_cost(StateInfo* st);
|
| 85 |
-
static int refresh_cost(const Position& pos);
|
| 86 |
-
|
| 87 |
-
// Returns whether the change stored in this StateInfo means that
|
| 88 |
-
// a full accumulator refresh is required.
|
| 89 |
-
static bool requires_refresh(StateInfo* st, Color perspective, const Position& pos);
|
| 90 |
-
};
|
| 91 |
-
|
| 92 |
-
} // namespace Stockfish::Eval::NNUE::Features
|
| 93 |
-
|
| 94 |
-
#endif // #ifndef NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/layers/affine_transform.h
DELETED
|
@@ -1,435 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
// Definition of layer AffineTransform of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED
|
| 22 |
-
#define NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED
|
| 23 |
-
|
| 24 |
-
#include <iostream>
|
| 25 |
-
#include "../nnue_common.h"
|
| 26 |
-
|
| 27 |
-
namespace Stockfish::Eval::NNUE::Layers {
|
| 28 |
-
|
| 29 |
-
// Affine transformation layer
|
| 30 |
-
template <typename PreviousLayer, IndexType OutDims>
|
| 31 |
-
class AffineTransform {
|
| 32 |
-
public:
|
| 33 |
-
// Input/output type
|
| 34 |
-
using InputType = typename PreviousLayer::OutputType;
|
| 35 |
-
using OutputType = std::int32_t;
|
| 36 |
-
static_assert(std::is_same<InputType, std::uint8_t>::value, "");
|
| 37 |
-
|
| 38 |
-
// Number of input/output dimensions
|
| 39 |
-
static constexpr IndexType InputDimensions =
|
| 40 |
-
PreviousLayer::OutputDimensions;
|
| 41 |
-
static constexpr IndexType OutputDimensions = OutDims;
|
| 42 |
-
static constexpr IndexType PaddedInputDimensions =
|
| 43 |
-
ceil_to_multiple<IndexType>(InputDimensions, MaxSimdWidth);
|
| 44 |
-
#if defined (USE_AVX512)
|
| 45 |
-
static constexpr const IndexType OutputSimdWidth = SimdWidth / 2;
|
| 46 |
-
#elif defined (USE_SSSE3)
|
| 47 |
-
static constexpr const IndexType OutputSimdWidth = SimdWidth / 4;
|
| 48 |
-
#endif
|
| 49 |
-
|
| 50 |
-
// Size of forward propagation buffer used in this layer
|
| 51 |
-
static constexpr std::size_t SelfBufferSize =
|
| 52 |
-
ceil_to_multiple(OutputDimensions * sizeof(OutputType), CacheLineSize);
|
| 53 |
-
|
| 54 |
-
// Size of the forward propagation buffer used from the input layer to this layer
|
| 55 |
-
static constexpr std::size_t BufferSize =
|
| 56 |
-
PreviousLayer::BufferSize + SelfBufferSize;
|
| 57 |
-
|
| 58 |
-
// Hash value embedded in the evaluation file
|
| 59 |
-
static constexpr std::uint32_t get_hash_value() {
|
| 60 |
-
std::uint32_t hashValue = 0xCC03DAE4u;
|
| 61 |
-
hashValue += OutputDimensions;
|
| 62 |
-
hashValue ^= PreviousLayer::get_hash_value() >> 1;
|
| 63 |
-
hashValue ^= PreviousLayer::get_hash_value() << 31;
|
| 64 |
-
return hashValue;
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
// Read network parameters
|
| 68 |
-
bool read_parameters(std::istream& stream) {
|
| 69 |
-
if (!previousLayer.read_parameters(stream)) return false;
|
| 70 |
-
for (std::size_t i = 0; i < OutputDimensions; ++i)
|
| 71 |
-
biases[i] = read_little_endian<BiasType>(stream);
|
| 72 |
-
for (std::size_t i = 0; i < OutputDimensions * PaddedInputDimensions; ++i)
|
| 73 |
-
#if !defined (USE_SSSE3)
|
| 74 |
-
weights[i] = read_little_endian<WeightType>(stream);
|
| 75 |
-
#else
|
| 76 |
-
weights[
|
| 77 |
-
(i / 4) % (PaddedInputDimensions / 4) * OutputDimensions * 4 +
|
| 78 |
-
i / PaddedInputDimensions * 4 +
|
| 79 |
-
i % 4
|
| 80 |
-
] = read_little_endian<WeightType>(stream);
|
| 81 |
-
#endif
|
| 82 |
-
|
| 83 |
-
return !stream.fail();
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
// Write network parameters
|
| 87 |
-
bool write_parameters(std::ostream& stream) const {
|
| 88 |
-
if (!previousLayer.write_parameters(stream)) return false;
|
| 89 |
-
for (std::size_t i = 0; i < OutputDimensions; ++i)
|
| 90 |
-
write_little_endian<BiasType>(stream, biases[i]);
|
| 91 |
-
#if !defined (USE_SSSE3)
|
| 92 |
-
for (std::size_t i = 0; i < OutputDimensions * PaddedInputDimensions; ++i)
|
| 93 |
-
write_little_endian<WeightType>(stream, weights[i]);
|
| 94 |
-
#else
|
| 95 |
-
std::unique_ptr<WeightType[]> unscrambledWeights = std::make_unique<WeightType[]>(OutputDimensions * PaddedInputDimensions);
|
| 96 |
-
for (std::size_t i = 0; i < OutputDimensions * PaddedInputDimensions; ++i) {
|
| 97 |
-
unscrambledWeights[i] =
|
| 98 |
-
weights[
|
| 99 |
-
(i / 4) % (PaddedInputDimensions / 4) * OutputDimensions * 4 +
|
| 100 |
-
i / PaddedInputDimensions * 4 +
|
| 101 |
-
i % 4
|
| 102 |
-
];
|
| 103 |
-
}
|
| 104 |
-
|
| 105 |
-
for (std::size_t i = 0; i < OutputDimensions * PaddedInputDimensions; ++i)
|
| 106 |
-
write_little_endian<WeightType>(stream, unscrambledWeights[i]);
|
| 107 |
-
#endif
|
| 108 |
-
|
| 109 |
-
return !stream.fail();
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
// Forward propagation
|
| 113 |
-
const OutputType* propagate(
|
| 114 |
-
const TransformedFeatureType* transformedFeatures, char* buffer) const {
|
| 115 |
-
const auto input = previousLayer.propagate(
|
| 116 |
-
transformedFeatures, buffer + SelfBufferSize);
|
| 117 |
-
|
| 118 |
-
#if defined (USE_AVX512)
|
| 119 |
-
|
| 120 |
-
[[maybe_unused]] const __m512i Ones512 = _mm512_set1_epi16(1);
|
| 121 |
-
|
| 122 |
-
[[maybe_unused]] auto m512_hadd = [](__m512i sum, int bias) -> int {
|
| 123 |
-
return _mm512_reduce_add_epi32(sum) + bias;
|
| 124 |
-
};
|
| 125 |
-
|
| 126 |
-
[[maybe_unused]] auto m512_add_dpbusd_epi32 = [=](__m512i& acc, __m512i a, __m512i b) {
|
| 127 |
-
#if defined (USE_VNNI)
|
| 128 |
-
acc = _mm512_dpbusd_epi32(acc, a, b);
|
| 129 |
-
#else
|
| 130 |
-
__m512i product0 = _mm512_maddubs_epi16(a, b);
|
| 131 |
-
product0 = _mm512_madd_epi16(product0, Ones512);
|
| 132 |
-
acc = _mm512_add_epi32(acc, product0);
|
| 133 |
-
#endif
|
| 134 |
-
};
|
| 135 |
-
|
| 136 |
-
[[maybe_unused]] auto m512_add_dpbusd_epi32x4 = [=](__m512i& acc, __m512i a0, __m512i b0, __m512i a1, __m512i b1,
|
| 137 |
-
__m512i a2, __m512i b2, __m512i a3, __m512i b3) {
|
| 138 |
-
#if defined (USE_VNNI)
|
| 139 |
-
acc = _mm512_dpbusd_epi32(acc, a0, b0);
|
| 140 |
-
acc = _mm512_dpbusd_epi32(acc, a1, b1);
|
| 141 |
-
acc = _mm512_dpbusd_epi32(acc, a2, b2);
|
| 142 |
-
acc = _mm512_dpbusd_epi32(acc, a3, b3);
|
| 143 |
-
#else
|
| 144 |
-
__m512i product0 = _mm512_maddubs_epi16(a0, b0);
|
| 145 |
-
__m512i product1 = _mm512_maddubs_epi16(a1, b1);
|
| 146 |
-
__m512i product2 = _mm512_maddubs_epi16(a2, b2);
|
| 147 |
-
__m512i product3 = _mm512_maddubs_epi16(a3, b3);
|
| 148 |
-
product0 = _mm512_adds_epi16(product0, product1);
|
| 149 |
-
product0 = _mm512_madd_epi16(product0, Ones512);
|
| 150 |
-
product2 = _mm512_adds_epi16(product2, product3);
|
| 151 |
-
product2 = _mm512_madd_epi16(product2, Ones512);
|
| 152 |
-
acc = _mm512_add_epi32(acc, _mm512_add_epi32(product0, product2));
|
| 153 |
-
#endif
|
| 154 |
-
};
|
| 155 |
-
|
| 156 |
-
#endif
|
| 157 |
-
#if defined (USE_AVX2)
|
| 158 |
-
|
| 159 |
-
[[maybe_unused]] const __m256i Ones256 = _mm256_set1_epi16(1);
|
| 160 |
-
|
| 161 |
-
[[maybe_unused]] auto m256_hadd = [](__m256i sum, int bias) -> int {
|
| 162 |
-
__m128i sum128 = _mm_add_epi32(_mm256_castsi256_si128(sum), _mm256_extracti128_si256(sum, 1));
|
| 163 |
-
sum128 = _mm_add_epi32(sum128, _mm_shuffle_epi32(sum128, _MM_PERM_BADC));
|
| 164 |
-
sum128 = _mm_add_epi32(sum128, _mm_shuffle_epi32(sum128, _MM_PERM_CDAB));
|
| 165 |
-
return _mm_cvtsi128_si32(sum128) + bias;
|
| 166 |
-
};
|
| 167 |
-
|
| 168 |
-
[[maybe_unused]] auto m256_add_dpbusd_epi32 = [=](__m256i& acc, __m256i a, __m256i b) {
|
| 169 |
-
#if defined (USE_VNNI)
|
| 170 |
-
acc = _mm256_dpbusd_epi32(acc, a, b);
|
| 171 |
-
#else
|
| 172 |
-
__m256i product0 = _mm256_maddubs_epi16(a, b);
|
| 173 |
-
product0 = _mm256_madd_epi16(product0, Ones256);
|
| 174 |
-
acc = _mm256_add_epi32(acc, product0);
|
| 175 |
-
#endif
|
| 176 |
-
};
|
| 177 |
-
|
| 178 |
-
[[maybe_unused]] auto m256_add_dpbusd_epi32x4 = [=](__m256i& acc, __m256i a0, __m256i b0, __m256i a1, __m256i b1,
|
| 179 |
-
__m256i a2, __m256i b2, __m256i a3, __m256i b3) {
|
| 180 |
-
#if defined (USE_VNNI)
|
| 181 |
-
acc = _mm256_dpbusd_epi32(acc, a0, b0);
|
| 182 |
-
acc = _mm256_dpbusd_epi32(acc, a1, b1);
|
| 183 |
-
acc = _mm256_dpbusd_epi32(acc, a2, b2);
|
| 184 |
-
acc = _mm256_dpbusd_epi32(acc, a3, b3);
|
| 185 |
-
#else
|
| 186 |
-
__m256i product0 = _mm256_maddubs_epi16(a0, b0);
|
| 187 |
-
__m256i product1 = _mm256_maddubs_epi16(a1, b1);
|
| 188 |
-
__m256i product2 = _mm256_maddubs_epi16(a2, b2);
|
| 189 |
-
__m256i product3 = _mm256_maddubs_epi16(a3, b3);
|
| 190 |
-
product0 = _mm256_adds_epi16(product0, product1);
|
| 191 |
-
product0 = _mm256_madd_epi16(product0, Ones256);
|
| 192 |
-
product2 = _mm256_adds_epi16(product2, product3);
|
| 193 |
-
product2 = _mm256_madd_epi16(product2, Ones256);
|
| 194 |
-
acc = _mm256_add_epi32(acc, _mm256_add_epi32(product0, product2));
|
| 195 |
-
#endif
|
| 196 |
-
};
|
| 197 |
-
|
| 198 |
-
#endif
|
| 199 |
-
#if defined (USE_SSSE3)
|
| 200 |
-
|
| 201 |
-
[[maybe_unused]] const __m128i Ones128 = _mm_set1_epi16(1);
|
| 202 |
-
|
| 203 |
-
[[maybe_unused]] auto m128_hadd = [](__m128i sum, int bias) -> int {
|
| 204 |
-
sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0x4E)); //_MM_PERM_BADC
|
| 205 |
-
sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0xB1)); //_MM_PERM_CDAB
|
| 206 |
-
return _mm_cvtsi128_si32(sum) + bias;
|
| 207 |
-
};
|
| 208 |
-
|
| 209 |
-
[[maybe_unused]] auto m128_add_dpbusd_epi32 = [=](__m128i& acc, __m128i a, __m128i b) {
|
| 210 |
-
__m128i product0 = _mm_maddubs_epi16(a, b);
|
| 211 |
-
product0 = _mm_madd_epi16(product0, Ones128);
|
| 212 |
-
acc = _mm_add_epi32(acc, product0);
|
| 213 |
-
};
|
| 214 |
-
|
| 215 |
-
[[maybe_unused]] auto m128_add_dpbusd_epi32x4 = [=](__m128i& acc, __m128i a0, __m128i b0, __m128i a1, __m128i b1,
|
| 216 |
-
__m128i a2, __m128i b2, __m128i a3, __m128i b3) {
|
| 217 |
-
__m128i product0 = _mm_maddubs_epi16(a0, b0);
|
| 218 |
-
__m128i product1 = _mm_maddubs_epi16(a1, b1);
|
| 219 |
-
__m128i product2 = _mm_maddubs_epi16(a2, b2);
|
| 220 |
-
__m128i product3 = _mm_maddubs_epi16(a3, b3);
|
| 221 |
-
product0 = _mm_adds_epi16(product0, product1);
|
| 222 |
-
product0 = _mm_madd_epi16(product0, Ones128);
|
| 223 |
-
product2 = _mm_adds_epi16(product2, product3);
|
| 224 |
-
product2 = _mm_madd_epi16(product2, Ones128);
|
| 225 |
-
acc = _mm_add_epi32(acc, _mm_add_epi32(product0, product2));
|
| 226 |
-
};
|
| 227 |
-
|
| 228 |
-
#endif
|
| 229 |
-
|
| 230 |
-
#if defined (USE_AVX512)
|
| 231 |
-
using vec_t = __m512i;
|
| 232 |
-
#define vec_setzero _mm512_setzero_si512
|
| 233 |
-
#define vec_set_32 _mm512_set1_epi32
|
| 234 |
-
auto& vec_add_dpbusd_32 = m512_add_dpbusd_epi32;
|
| 235 |
-
auto& vec_add_dpbusd_32x4 = m512_add_dpbusd_epi32x4;
|
| 236 |
-
auto& vec_hadd = m512_hadd;
|
| 237 |
-
#elif defined (USE_AVX2)
|
| 238 |
-
using vec_t = __m256i;
|
| 239 |
-
#define vec_setzero _mm256_setzero_si256
|
| 240 |
-
#define vec_set_32 _mm256_set1_epi32
|
| 241 |
-
auto& vec_add_dpbusd_32 = m256_add_dpbusd_epi32;
|
| 242 |
-
auto& vec_add_dpbusd_32x4 = m256_add_dpbusd_epi32x4;
|
| 243 |
-
auto& vec_hadd = m256_hadd;
|
| 244 |
-
#elif defined (USE_SSSE3)
|
| 245 |
-
using vec_t = __m128i;
|
| 246 |
-
#define vec_setzero _mm_setzero_si128
|
| 247 |
-
#define vec_set_32 _mm_set1_epi32
|
| 248 |
-
auto& vec_add_dpbusd_32 = m128_add_dpbusd_epi32;
|
| 249 |
-
auto& vec_add_dpbusd_32x4 = m128_add_dpbusd_epi32x4;
|
| 250 |
-
auto& vec_hadd = m128_hadd;
|
| 251 |
-
#endif
|
| 252 |
-
|
| 253 |
-
#if defined (USE_SSSE3)
|
| 254 |
-
// Different layout, we process 4 inputs at a time, always.
|
| 255 |
-
static_assert(InputDimensions % 4 == 0);
|
| 256 |
-
|
| 257 |
-
const auto output = reinterpret_cast<OutputType*>(buffer);
|
| 258 |
-
const auto inputVector = reinterpret_cast<const vec_t*>(input);
|
| 259 |
-
|
| 260 |
-
static_assert(OutputDimensions % OutputSimdWidth == 0 || OutputDimensions == 1);
|
| 261 |
-
|
| 262 |
-
// OutputDimensions is either 1 or a multiple of SimdWidth
|
| 263 |
-
// because then it is also an input dimension.
|
| 264 |
-
if constexpr (OutputDimensions % OutputSimdWidth == 0)
|
| 265 |
-
{
|
| 266 |
-
constexpr IndexType NumChunks = InputDimensions / 4;
|
| 267 |
-
|
| 268 |
-
const auto input32 = reinterpret_cast<const std::int32_t*>(input);
|
| 269 |
-
vec_t* outptr = reinterpret_cast<vec_t*>(output);
|
| 270 |
-
std::memcpy(output, biases, OutputDimensions * sizeof(OutputType));
|
| 271 |
-
|
| 272 |
-
for (int i = 0; i < (int)NumChunks - 3; i += 4)
|
| 273 |
-
{
|
| 274 |
-
const vec_t in0 = vec_set_32(input32[i + 0]);
|
| 275 |
-
const vec_t in1 = vec_set_32(input32[i + 1]);
|
| 276 |
-
const vec_t in2 = vec_set_32(input32[i + 2]);
|
| 277 |
-
const vec_t in3 = vec_set_32(input32[i + 3]);
|
| 278 |
-
const auto col0 = reinterpret_cast<const vec_t*>(&weights[(i + 0) * OutputDimensions * 4]);
|
| 279 |
-
const auto col1 = reinterpret_cast<const vec_t*>(&weights[(i + 1) * OutputDimensions * 4]);
|
| 280 |
-
const auto col2 = reinterpret_cast<const vec_t*>(&weights[(i + 2) * OutputDimensions * 4]);
|
| 281 |
-
const auto col3 = reinterpret_cast<const vec_t*>(&weights[(i + 3) * OutputDimensions * 4]);
|
| 282 |
-
for (int j = 0; j * OutputSimdWidth < OutputDimensions; ++j)
|
| 283 |
-
vec_add_dpbusd_32x4(outptr[j], in0, col0[j], in1, col1[j], in2, col2[j], in3, col3[j]);
|
| 284 |
-
}
|
| 285 |
-
}
|
| 286 |
-
else if constexpr (OutputDimensions == 1)
|
| 287 |
-
{
|
| 288 |
-
#if defined (USE_AVX512)
|
| 289 |
-
if constexpr (PaddedInputDimensions % (SimdWidth * 2) != 0)
|
| 290 |
-
{
|
| 291 |
-
constexpr IndexType NumChunks = PaddedInputDimensions / SimdWidth;
|
| 292 |
-
const auto inputVector256 = reinterpret_cast<const __m256i*>(input);
|
| 293 |
-
|
| 294 |
-
__m256i sum0 = _mm256_setzero_si256();
|
| 295 |
-
const auto row0 = reinterpret_cast<const __m256i*>(&weights[0]);
|
| 296 |
-
|
| 297 |
-
for (int j = 0; j < (int)NumChunks; ++j)
|
| 298 |
-
{
|
| 299 |
-
const __m256i in = inputVector256[j];
|
| 300 |
-
m256_add_dpbusd_epi32(sum0, in, row0[j]);
|
| 301 |
-
}
|
| 302 |
-
output[0] = m256_hadd(sum0, biases[0]);
|
| 303 |
-
}
|
| 304 |
-
else
|
| 305 |
-
#endif
|
| 306 |
-
{
|
| 307 |
-
#if defined (USE_AVX512)
|
| 308 |
-
constexpr IndexType NumChunks = PaddedInputDimensions / (SimdWidth * 2);
|
| 309 |
-
#else
|
| 310 |
-
constexpr IndexType NumChunks = PaddedInputDimensions / SimdWidth;
|
| 311 |
-
#endif
|
| 312 |
-
vec_t sum0 = vec_setzero();
|
| 313 |
-
const auto row0 = reinterpret_cast<const vec_t*>(&weights[0]);
|
| 314 |
-
|
| 315 |
-
for (int j = 0; j < (int)NumChunks; ++j)
|
| 316 |
-
{
|
| 317 |
-
const vec_t in = inputVector[j];
|
| 318 |
-
vec_add_dpbusd_32(sum0, in, row0[j]);
|
| 319 |
-
}
|
| 320 |
-
output[0] = vec_hadd(sum0, biases[0]);
|
| 321 |
-
}
|
| 322 |
-
}
|
| 323 |
-
|
| 324 |
-
#else
|
| 325 |
-
|
| 326 |
-
// Use old implementation for the other architectures.
|
| 327 |
-
|
| 328 |
-
auto output = reinterpret_cast<OutputType*>(buffer);
|
| 329 |
-
|
| 330 |
-
#if defined(USE_SSE2)
|
| 331 |
-
// At least a multiple of 16, with SSE2.
|
| 332 |
-
static_assert(InputDimensions % SimdWidth == 0);
|
| 333 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 334 |
-
const __m128i Zeros = _mm_setzero_si128();
|
| 335 |
-
const auto inputVector = reinterpret_cast<const __m128i*>(input);
|
| 336 |
-
|
| 337 |
-
#elif defined(USE_MMX)
|
| 338 |
-
static_assert(InputDimensions % SimdWidth == 0);
|
| 339 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 340 |
-
const __m64 Zeros = _mm_setzero_si64();
|
| 341 |
-
const auto inputVector = reinterpret_cast<const __m64*>(input);
|
| 342 |
-
|
| 343 |
-
#elif defined(USE_NEON)
|
| 344 |
-
static_assert(InputDimensions % SimdWidth == 0);
|
| 345 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 346 |
-
const auto inputVector = reinterpret_cast<const int8x8_t*>(input);
|
| 347 |
-
#endif
|
| 348 |
-
|
| 349 |
-
for (IndexType i = 0; i < OutputDimensions; ++i) {
|
| 350 |
-
const IndexType offset = i * PaddedInputDimensions;
|
| 351 |
-
|
| 352 |
-
#if defined(USE_SSE2)
|
| 353 |
-
__m128i sumLo = _mm_cvtsi32_si128(biases[i]);
|
| 354 |
-
__m128i sumHi = Zeros;
|
| 355 |
-
const auto row = reinterpret_cast<const __m128i*>(&weights[offset]);
|
| 356 |
-
for (IndexType j = 0; j < NumChunks; ++j) {
|
| 357 |
-
__m128i row_j = _mm_load_si128(&row[j]);
|
| 358 |
-
__m128i input_j = _mm_load_si128(&inputVector[j]);
|
| 359 |
-
__m128i extendedRowLo = _mm_srai_epi16(_mm_unpacklo_epi8(row_j, row_j), 8);
|
| 360 |
-
__m128i extendedRowHi = _mm_srai_epi16(_mm_unpackhi_epi8(row_j, row_j), 8);
|
| 361 |
-
__m128i extendedInputLo = _mm_unpacklo_epi8(input_j, Zeros);
|
| 362 |
-
__m128i extendedInputHi = _mm_unpackhi_epi8(input_j, Zeros);
|
| 363 |
-
__m128i productLo = _mm_madd_epi16(extendedRowLo, extendedInputLo);
|
| 364 |
-
__m128i productHi = _mm_madd_epi16(extendedRowHi, extendedInputHi);
|
| 365 |
-
sumLo = _mm_add_epi32(sumLo, productLo);
|
| 366 |
-
sumHi = _mm_add_epi32(sumHi, productHi);
|
| 367 |
-
}
|
| 368 |
-
__m128i sum = _mm_add_epi32(sumLo, sumHi);
|
| 369 |
-
__m128i sumHigh_64 = _mm_shuffle_epi32(sum, _MM_SHUFFLE(1, 0, 3, 2));
|
| 370 |
-
sum = _mm_add_epi32(sum, sumHigh_64);
|
| 371 |
-
__m128i sum_second_32 = _mm_shufflelo_epi16(sum, _MM_SHUFFLE(1, 0, 3, 2));
|
| 372 |
-
sum = _mm_add_epi32(sum, sum_second_32);
|
| 373 |
-
output[i] = _mm_cvtsi128_si32(sum);
|
| 374 |
-
|
| 375 |
-
#elif defined(USE_MMX)
|
| 376 |
-
__m64 sumLo = _mm_cvtsi32_si64(biases[i]);
|
| 377 |
-
__m64 sumHi = Zeros;
|
| 378 |
-
const auto row = reinterpret_cast<const __m64*>(&weights[offset]);
|
| 379 |
-
for (IndexType j = 0; j < NumChunks; ++j) {
|
| 380 |
-
__m64 row_j = row[j];
|
| 381 |
-
__m64 input_j = inputVector[j];
|
| 382 |
-
__m64 extendedRowLo = _mm_srai_pi16(_mm_unpacklo_pi8(row_j, row_j), 8);
|
| 383 |
-
__m64 extendedRowHi = _mm_srai_pi16(_mm_unpackhi_pi8(row_j, row_j), 8);
|
| 384 |
-
__m64 extendedInputLo = _mm_unpacklo_pi8(input_j, Zeros);
|
| 385 |
-
__m64 extendedInputHi = _mm_unpackhi_pi8(input_j, Zeros);
|
| 386 |
-
__m64 productLo = _mm_madd_pi16(extendedRowLo, extendedInputLo);
|
| 387 |
-
__m64 productHi = _mm_madd_pi16(extendedRowHi, extendedInputHi);
|
| 388 |
-
sumLo = _mm_add_pi32(sumLo, productLo);
|
| 389 |
-
sumHi = _mm_add_pi32(sumHi, productHi);
|
| 390 |
-
}
|
| 391 |
-
__m64 sum = _mm_add_pi32(sumLo, sumHi);
|
| 392 |
-
sum = _mm_add_pi32(sum, _mm_unpackhi_pi32(sum, sum));
|
| 393 |
-
output[i] = _mm_cvtsi64_si32(sum);
|
| 394 |
-
|
| 395 |
-
#elif defined(USE_NEON)
|
| 396 |
-
int32x4_t sum = {biases[i]};
|
| 397 |
-
const auto row = reinterpret_cast<const int8x8_t*>(&weights[offset]);
|
| 398 |
-
for (IndexType j = 0; j < NumChunks; ++j) {
|
| 399 |
-
int16x8_t product = vmull_s8(inputVector[j * 2], row[j * 2]);
|
| 400 |
-
product = vmlal_s8(product, inputVector[j * 2 + 1], row[j * 2 + 1]);
|
| 401 |
-
sum = vpadalq_s16(sum, product);
|
| 402 |
-
}
|
| 403 |
-
output[i] = sum[0] + sum[1] + sum[2] + sum[3];
|
| 404 |
-
|
| 405 |
-
#else
|
| 406 |
-
OutputType sum = biases[i];
|
| 407 |
-
for (IndexType j = 0; j < InputDimensions; ++j) {
|
| 408 |
-
sum += weights[offset + j] * input[j];
|
| 409 |
-
}
|
| 410 |
-
output[i] = sum;
|
| 411 |
-
#endif
|
| 412 |
-
|
| 413 |
-
}
|
| 414 |
-
#if defined(USE_MMX)
|
| 415 |
-
_mm_empty();
|
| 416 |
-
#endif
|
| 417 |
-
|
| 418 |
-
#endif
|
| 419 |
-
|
| 420 |
-
return output;
|
| 421 |
-
}
|
| 422 |
-
|
| 423 |
-
private:
|
| 424 |
-
using BiasType = OutputType;
|
| 425 |
-
using WeightType = std::int8_t;
|
| 426 |
-
|
| 427 |
-
PreviousLayer previousLayer;
|
| 428 |
-
|
| 429 |
-
alignas(CacheLineSize) BiasType biases[OutputDimensions];
|
| 430 |
-
alignas(CacheLineSize) WeightType weights[OutputDimensions * PaddedInputDimensions];
|
| 431 |
-
};
|
| 432 |
-
|
| 433 |
-
} // namespace Stockfish::Eval::NNUE::Layers
|
| 434 |
-
|
| 435 |
-
#endif // #ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fairy-Stockfish-master/src/nnue/layers/clipped_relu.h
DELETED
|
@@ -1,191 +0,0 @@
|
|
| 1 |
-
/*
|
| 2 |
-
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
| 3 |
-
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
| 4 |
-
|
| 5 |
-
Stockfish is free software: you can redistribute it and/or modify
|
| 6 |
-
it under the terms of the GNU General Public License as published by
|
| 7 |
-
the Free Software Foundation, either version 3 of the License, or
|
| 8 |
-
(at your option) any later version.
|
| 9 |
-
|
| 10 |
-
Stockfish is distributed in the hope that it will be useful,
|
| 11 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 |
-
GNU General Public License for more details.
|
| 14 |
-
|
| 15 |
-
You should have received a copy of the GNU General Public License
|
| 16 |
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 17 |
-
*/
|
| 18 |
-
|
| 19 |
-
// Definition of layer ClippedReLU of NNUE evaluation function
|
| 20 |
-
|
| 21 |
-
#ifndef NNUE_LAYERS_CLIPPED_RELU_H_INCLUDED
|
| 22 |
-
#define NNUE_LAYERS_CLIPPED_RELU_H_INCLUDED
|
| 23 |
-
|
| 24 |
-
#include "../nnue_common.h"
|
| 25 |
-
|
| 26 |
-
namespace Stockfish::Eval::NNUE::Layers {
|
| 27 |
-
|
| 28 |
-
// Clipped ReLU
|
| 29 |
-
template <typename PreviousLayer>
|
| 30 |
-
class ClippedReLU {
|
| 31 |
-
public:
|
| 32 |
-
// Input/output type
|
| 33 |
-
using InputType = typename PreviousLayer::OutputType;
|
| 34 |
-
using OutputType = std::uint8_t;
|
| 35 |
-
static_assert(std::is_same<InputType, std::int32_t>::value, "");
|
| 36 |
-
|
| 37 |
-
// Number of input/output dimensions
|
| 38 |
-
static constexpr IndexType InputDimensions =
|
| 39 |
-
PreviousLayer::OutputDimensions;
|
| 40 |
-
static constexpr IndexType OutputDimensions = InputDimensions;
|
| 41 |
-
|
| 42 |
-
// Size of forward propagation buffer used in this layer
|
| 43 |
-
static constexpr std::size_t SelfBufferSize =
|
| 44 |
-
ceil_to_multiple(OutputDimensions * sizeof(OutputType), CacheLineSize);
|
| 45 |
-
|
| 46 |
-
// Size of the forward propagation buffer used from the input layer to this layer
|
| 47 |
-
static constexpr std::size_t BufferSize =
|
| 48 |
-
PreviousLayer::BufferSize + SelfBufferSize;
|
| 49 |
-
|
| 50 |
-
// Hash value embedded in the evaluation file
|
| 51 |
-
static constexpr std::uint32_t get_hash_value() {
|
| 52 |
-
std::uint32_t hashValue = 0x538D24C7u;
|
| 53 |
-
hashValue += PreviousLayer::get_hash_value();
|
| 54 |
-
return hashValue;
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
// Read network parameters
|
| 58 |
-
bool read_parameters(std::istream& stream) {
|
| 59 |
-
return previousLayer.read_parameters(stream);
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
// Write network parameters
|
| 63 |
-
bool write_parameters(std::ostream& stream) const {
|
| 64 |
-
return previousLayer.write_parameters(stream);
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
// Forward propagation
|
| 68 |
-
const OutputType* propagate(
|
| 69 |
-
const TransformedFeatureType* transformedFeatures, char* buffer) const {
|
| 70 |
-
const auto input = previousLayer.propagate(
|
| 71 |
-
transformedFeatures, buffer + SelfBufferSize);
|
| 72 |
-
const auto output = reinterpret_cast<OutputType*>(buffer);
|
| 73 |
-
|
| 74 |
-
#if defined(USE_AVX2)
|
| 75 |
-
if constexpr (InputDimensions % SimdWidth == 0) {
|
| 76 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 77 |
-
const __m256i Zero = _mm256_setzero_si256();
|
| 78 |
-
const __m256i Offsets = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
|
| 79 |
-
const auto in = reinterpret_cast<const __m256i*>(input);
|
| 80 |
-
const auto out = reinterpret_cast<__m256i*>(output);
|
| 81 |
-
for (IndexType i = 0; i < NumChunks; ++i) {
|
| 82 |
-
const __m256i words0 = _mm256_srai_epi16(_mm256_packs_epi32(
|
| 83 |
-
_mm256_load_si256(&in[i * 4 + 0]),
|
| 84 |
-
_mm256_load_si256(&in[i * 4 + 1])), WeightScaleBits);
|
| 85 |
-
const __m256i words1 = _mm256_srai_epi16(_mm256_packs_epi32(
|
| 86 |
-
_mm256_load_si256(&in[i * 4 + 2]),
|
| 87 |
-
_mm256_load_si256(&in[i * 4 + 3])), WeightScaleBits);
|
| 88 |
-
_mm256_store_si256(&out[i], _mm256_permutevar8x32_epi32(_mm256_max_epi8(
|
| 89 |
-
_mm256_packs_epi16(words0, words1), Zero), Offsets));
|
| 90 |
-
}
|
| 91 |
-
} else {
|
| 92 |
-
constexpr IndexType NumChunks = InputDimensions / (SimdWidth / 2);
|
| 93 |
-
const __m128i Zero = _mm_setzero_si128();
|
| 94 |
-
const auto in = reinterpret_cast<const __m128i*>(input);
|
| 95 |
-
const auto out = reinterpret_cast<__m128i*>(output);
|
| 96 |
-
for (IndexType i = 0; i < NumChunks; ++i) {
|
| 97 |
-
const __m128i words0 = _mm_srai_epi16(_mm_packs_epi32(
|
| 98 |
-
_mm_load_si128(&in[i * 4 + 0]),
|
| 99 |
-
_mm_load_si128(&in[i * 4 + 1])), WeightScaleBits);
|
| 100 |
-
const __m128i words1 = _mm_srai_epi16(_mm_packs_epi32(
|
| 101 |
-
_mm_load_si128(&in[i * 4 + 2]),
|
| 102 |
-
_mm_load_si128(&in[i * 4 + 3])), WeightScaleBits);
|
| 103 |
-
const __m128i packedbytes = _mm_packs_epi16(words0, words1);
|
| 104 |
-
_mm_store_si128(&out[i], _mm_max_epi8(packedbytes, Zero));
|
| 105 |
-
}
|
| 106 |
-
}
|
| 107 |
-
constexpr IndexType Start =
|
| 108 |
-
InputDimensions % SimdWidth == 0
|
| 109 |
-
? InputDimensions / SimdWidth * SimdWidth
|
| 110 |
-
: InputDimensions / (SimdWidth / 2) * (SimdWidth / 2);
|
| 111 |
-
|
| 112 |
-
#elif defined(USE_SSE2)
|
| 113 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 114 |
-
|
| 115 |
-
#ifdef USE_SSE41
|
| 116 |
-
const __m128i Zero = _mm_setzero_si128();
|
| 117 |
-
#else
|
| 118 |
-
const __m128i k0x80s = _mm_set1_epi8(-128);
|
| 119 |
-
#endif
|
| 120 |
-
|
| 121 |
-
const auto in = reinterpret_cast<const __m128i*>(input);
|
| 122 |
-
const auto out = reinterpret_cast<__m128i*>(output);
|
| 123 |
-
for (IndexType i = 0; i < NumChunks; ++i) {
|
| 124 |
-
const __m128i words0 = _mm_srai_epi16(_mm_packs_epi32(
|
| 125 |
-
_mm_load_si128(&in[i * 4 + 0]),
|
| 126 |
-
_mm_load_si128(&in[i * 4 + 1])), WeightScaleBits);
|
| 127 |
-
const __m128i words1 = _mm_srai_epi16(_mm_packs_epi32(
|
| 128 |
-
_mm_load_si128(&in[i * 4 + 2]),
|
| 129 |
-
_mm_load_si128(&in[i * 4 + 3])), WeightScaleBits);
|
| 130 |
-
const __m128i packedbytes = _mm_packs_epi16(words0, words1);
|
| 131 |
-
_mm_store_si128(&out[i],
|
| 132 |
-
|
| 133 |
-
#ifdef USE_SSE41
|
| 134 |
-
_mm_max_epi8(packedbytes, Zero)
|
| 135 |
-
#else
|
| 136 |
-
_mm_subs_epi8(_mm_adds_epi8(packedbytes, k0x80s), k0x80s)
|
| 137 |
-
#endif
|
| 138 |
-
|
| 139 |
-
);
|
| 140 |
-
}
|
| 141 |
-
constexpr IndexType Start = NumChunks * SimdWidth;
|
| 142 |
-
|
| 143 |
-
#elif defined(USE_MMX)
|
| 144 |
-
constexpr IndexType NumChunks = InputDimensions / SimdWidth;
|
| 145 |
-
const __m64 k0x80s = _mm_set1_pi8(-128);
|
| 146 |
-
const auto in = reinterpret_cast<const __m64*>(input);
|
| 147 |
-
const auto out = reinterpret_cast<__m64*>(output);
|
| 148 |
-
for (IndexType i = 0; i < NumChunks; ++i) {
|
| 149 |
-
const __m64 words0 = _mm_srai_pi16(
|
| 150 |
-
_mm_packs_pi32(in[i * 4 + 0], in[i * 4 + 1]),
|
| 151 |
-
WeightScaleBits);
|
| 152 |
-
const __m64 words1 = _mm_srai_pi16(
|
| 153 |
-
_mm_packs_pi32(in[i * 4 + 2], in[i * 4 + 3]),
|
| 154 |
-
WeightScaleBits);
|
| 155 |
-
const __m64 packedbytes = _mm_packs_pi16(words0, words1);
|
| 156 |
-
out[i] = _mm_subs_pi8(_mm_adds_pi8(packedbytes, k0x80s), k0x80s);
|
| 157 |
-
}
|
| 158 |
-
_mm_empty();
|
| 159 |
-
constexpr IndexType Start = NumChunks * SimdWidth;
|
| 160 |
-
|
| 161 |
-
#elif defined(USE_NEON)
|
| 162 |
-
constexpr IndexType NumChunks = InputDimensions / (SimdWidth / 2);
|
| 163 |
-
const int8x8_t Zero = {0};
|
| 164 |
-
const auto in = reinterpret_cast<const int32x4_t*>(input);
|
| 165 |
-
const auto out = reinterpret_cast<int8x8_t*>(output);
|
| 166 |
-
for (IndexType i = 0; i < NumChunks; ++i) {
|
| 167 |
-
int16x8_t shifted;
|
| 168 |
-
const auto pack = reinterpret_cast<int16x4_t*>(&shifted);
|
| 169 |
-
pack[0] = vqshrn_n_s32(in[i * 2 + 0], WeightScaleBits);
|
| 170 |
-
pack[1] = vqshrn_n_s32(in[i * 2 + 1], WeightScaleBits);
|
| 171 |
-
out[i] = vmax_s8(vqmovn_s16(shifted), Zero);
|
| 172 |
-
}
|
| 173 |
-
constexpr IndexType Start = NumChunks * (SimdWidth / 2);
|
| 174 |
-
#else
|
| 175 |
-
constexpr IndexType Start = 0;
|
| 176 |
-
#endif
|
| 177 |
-
|
| 178 |
-
for (IndexType i = Start; i < InputDimensions; ++i) {
|
| 179 |
-
output[i] = static_cast<OutputType>(
|
| 180 |
-
std::max(0, std::min(127, input[i] >> WeightScaleBits)));
|
| 181 |
-
}
|
| 182 |
-
return output;
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
private:
|
| 186 |
-
PreviousLayer previousLayer;
|
| 187 |
-
};
|
| 188 |
-
|
| 189 |
-
} // namespace Stockfish::Eval::NNUE::Layers
|
| 190 |
-
|
| 191 |
-
#endif // NNUE_LAYERS_CLIPPED_RELU_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|