Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Fri, 16 Jul 2021 10:11:09 +0000 (12:11 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Fri, 16 Jul 2021 10:11:09 +0000 (12:11 +0200)
bench: 4850077

14 files changed:
1  2 
.github/workflows/fairy.yml
src/Makefile
src/Makefile_js
src/evaluate.cpp
src/evaluate.h
src/nnue/features/half_ka_v2.cpp
src/nnue/features/half_ka_v2.h
src/nnue/features/half_ka_v2_shogi.cpp
src/nnue/features/half_ka_v2_shogi.h
src/nnue/features/half_ka_v2_variants.cpp
src/nnue/features/half_ka_v2_variants.h
src/nnue/nnue_architecture.h
src/nnue/nnue_feature_transformer.h
src/search.cpp

index e260e9e,0000000..7751597
mode 100644,000000..100644
--- /dev/null
@@@ -1,87 -1,0 +1,93 @@@
 +name: fairy
 +on:
 +  push:
 +    branches:
 +      - master
 +  pull_request:
 +    branches:
 +      - master
 +jobs:
 +  fairy:
 +    name: ${{ matrix.config.name }}
 +    runs-on: ${{ matrix.config.os }}
 +    env:
 +      COMPILER: ${{ matrix.config.compiler }}
 +      COMP: ${{ matrix.config.comp }}
 +      CXXFLAGS: "-Werror"
 +    strategy:
 +      matrix:
 +        config:
 +          - {
 +              name: "Ubuntu 20.04 GCC",
 +              os: ubuntu-20.04,
 +              compiler: g++,
 +              comp: gcc,
 +              run_expensive_tests: true
 +            }
 +          - {
 +              name: "Ubuntu 20.04 Clang",
 +              os: ubuntu-20.04,
 +              compiler: clang++,
 +              comp: clang,
 +              run_expensive_tests: false
 +            }
 +
 +    defaults:
 +      run:
 +        working-directory: src
 +    steps:
 +      - uses: actions/checkout@v2
 +        with:
 +          fetch-depth: 0
 +
 +      - name: Download required packages
 +        run: |
 +          sudo apt update
 +          sudo apt install expect valgrind g++-multilib
 +
 +      - name: Download the used network from the fishtest framework
 +        run: |
 +          make net
 +
 +      - name: Test NNUE
 +        run: |
 +          make clean
 +          make -j2 ARCH=x86-64 nnue=yes debug=yes build
 +          ./stockfish bench
 +
++      - name: Test NNUE largeboards
++        run: |
++          make clean
++          make -j2 ARCH=x86-64 largeboards=yes nnue=yes debug=yes build
++          ./stockfish bench
++
 +      - name: Build all variants
 +        run: |
 +          make clean
 +          make -j2 ARCH=x86-64 largeboards=yes all=yes debug=yes build
 +
 +      - name: Test protocols
 +        run: |
 +          ../tests/protocol.sh
 +
 +      - name: Test variants.ini
 +        run: |
 +          ! ./stockfish check variants.ini 2>&1 >/dev/null | grep -v "Parsing variant"
 +
 +      - name: Test variant perft
 +        run: |
 +          ../tests/perft.sh all
 +
 +      - name: Test variant bench
 +        run: |
 +          ./stockfish bench xiangqi
 +          ./stockfish bench shogi
 +          ./stockfish bench capablanca
 +          ./stockfish bench sittuyin
 +
 +      - name: Test 32bit largeboards
 +        run: |
 +          if [[ "$COMP" == "gcc" ]]; then export EXTRACXXFLAGS=-Wno-class-memaccess; fi
 +          make clean
 +          make -j2 ARCH=x86-32 largeboards=yes build
 +          ../tests/perft.sh largeboard
diff --cc src/Makefile
@@@ -41,9 -41,7 +41,9 @@@ endi
  SRCS = benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp main.cpp \
        material.cpp misc.cpp movegen.cpp movepick.cpp pawns.cpp position.cpp psqt.cpp \
        search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \
-       nnue/evaluate_nnue.cpp nnue/features/half_kp.cpp \
 -      nnue/evaluate_nnue.cpp nnue/features/half_ka_v2.cpp
++      nnue/evaluate_nnue.cpp nnue/features/half_ka_v2.cpp \
 +      partner.cpp parser.cpp piece.cpp variant.cpp xboard.cpp \
-       nnue/features/half_kp_shogi.cpp nnue/features/half_kp_variants.cpp
++      nnue/features/half_ka_v2_shogi.cpp nnue/features/half_ka_v2_variants.cpp
  
  OBJS = $(notdir $(SRCS:.cpp=.o))
  
diff --cc src/Makefile_js
index 3cf9f50,0000000..fdc4b15
mode 100644,000000..100644
--- /dev/null
@@@ -1,89 -1,0 +1,89 @@@
 +# ffish.js, a JavaScript chess variant library derived from Fairy-Stockfish
 +# Copyright (C) 2021 Fabian Fichter, Johannes Czech
 +#
 +# ffish.js is free software: you can redistribute it and/or modify
 +# it under the terms of the GNU General Public License as published by
 +# the Free Software Foundation, either version 3 of the License, or
 +# (at your option) any later version.
 +#
 +# ffish.js is distributed in the hope that it will be useful,
 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +# GNU General Public License for more details.
 +#
 +# You should have received a copy of the GNU General Public License
 +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +
 +EXE = ../tests/js/ffish.js
 +
 +SRCS = ffishjs.cpp benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp \
 +      material.cpp misc.cpp movegen.cpp movepick.cpp pawns.cpp position.cpp psqt.cpp \
 +      search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \
-       nnue/evaluate_nnue.cpp nnue/features/half_kp.cpp \
++      nnue/evaluate_nnue.cpp nnue/features/half_ka_v2.cpp \
 +      partner.cpp parser.cpp piece.cpp variant.cpp xboard.cpp \
-       nnue/features/half_kp_shogi.cpp nnue/features/half_kp_variants.cpp
++      nnue/features/half_ka_v2_shogi.cpp nnue/features/half_ka_v2_variants.cpp
 +
 +CXX=emcc
 +CXXFLAGS += --bind -DNNUE_EMBEDDING_OFF -DNO_THREADS -std=c++17 -Wall
 +
 +largeboards = yes
 +optimize = yes
 +debug = no
 +
 +### Debugging
 +ifeq ($(debug),no)
 +      CXXFLAGS += -DNDEBUG -s ASSERTIONS=0 -s SAFE_HEAP=0
 +else
 +      CXXFLAGS += -g -s ASSERTIONS=1 -s SAFE_HEAP=1
 +endif
 +
 +### Optimization
 +ifeq ($(optimize),yes)
 +      CXXFLAGS += -O3
 +endif
 +
 +# Compile version with support for large board variants
 +# Use precomputed magics by default
 +ifneq ($(largeboards),no)
 +      CXXFLAGS += -DLARGEBOARDS -DPRECOMPUTED_MAGICS -s TOTAL_MEMORY=32MB -s ALLOW_MEMORY_GROWTH=1 -s WASM_MEM_MAX=1GB
 +endif
 +
 +### Compile as ES6/ES2015 module
 +ifeq ($(es6),yes)
 +      CXXFLAGS += -s ENVIRONMENT='web,worker' -s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=0
 +endif
 +
 +.PHONY: help objclean clean build deps test serve
 +
 +help:
 +      @echo ""
 +      @echo "To compile ffishjs, type: "
 +      @echo ""
 +      @echo "make -f Makefile_js build"
 +      @echo ""
 +      @echo "Supported targets:"
 +      @echo ""
 +      @echo "help                    > Display this help"
 +      @echo "build                   > Standard build"
 +      @echo "clean                   > Clean up"
 +      @echo "deps                    > Install runtime dependencies using npm"
 +      @echo "test                    > Run tests"
 +      @echo "serve                   > Run example server"
 +      @echo ""
 +
 +objclean:
 +      @rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o
 +
 +clean: objclean
 +
 +build:
 +      $(CXX) $(CXXFLAGS) $(SRCS) -o $(EXE)
 +
 +deps:
 +      cd ../tests/js && npm install
 +
 +test: deps
 +      cd ../tests/js && npm test
 +
 +serve: deps
 +      cd ../tests/js && node index.js
@@@ -1613,13 -1124,6 +1611,13 @@@ Value Eval::evaluate(const Position& po
           if (pos.is_chess960())
               nnue += fix_FRC(pos);
  
 +         if (pos.check_counting())
 +         {
 +             Color us = pos.side_to_move();
-              nnue +=  material / (30 * pos.checks_remaining( us))
-                     - material / (30 * pos.checks_remaining(~us));
++             nnue +=  6 * scale / (5 * pos.checks_remaining( us))
++                    - 6 * scale / (5 * pos.checks_remaining(~us));
 +         }
 +
           return nnue;
        };
  
        // a small probability of using the classical eval when PSQ imbalance is small.
        Value psq = Value(abs(eg_value(pos.psq_score())));
        int   r50 = 16 + pos.rule50_count();
 -      bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
 +      bool  pure = !pos.check_counting();
 +      bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50 && !pure;
-       bool  classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB) && !pure);
+       bool  classical = largePsq;
  
        // Use classical evaluation for really low piece endgames.
        // One critical case is the draw for bishop + A/H file pawn vs naked king.
diff --cc src/evaluate.h
Simple merge
  
  namespace Stockfish::Eval::NNUE::Features {
  
 +  // Map square to numbering on 8x8 board
 +  constexpr Square to_chess_square(Square s) {
 +    return Square(s - rank_of(s) * (FILE_MAX - FILE_H));
 +  }
 +
    // Orient a square according to perspective (rotates by 180 for black)
-   inline Square HalfKPChess::orient(Color perspective, Square s) {
-     return Square(int(to_chess_square(s)) ^ (bool(perspective) * 63));
+   inline Square HalfKAv2::orient(Color perspective, Square s) {
 -    return Square(int(s) ^ (bool(perspective) * 56));
++    return Square(int(to_chess_square(s)) ^ (bool(perspective) * 56));
    }
  
    // Index of a feature for a given king position and another piece on some square
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  
--//Definition of input features HalfKP of NNUE evaluation function
++//Definition of input features HalfKAv2 of NNUE evaluation function
  
- #ifndef NNUE_FEATURES_HALF_KP_H_INCLUDED
- #define NNUE_FEATURES_HALF_KP_H_INCLUDED
+ #ifndef NNUE_FEATURES_HALF_KA_V2_H_INCLUDED
+ #define NNUE_FEATURES_HALF_KA_V2_H_INCLUDED
  
  #include "../nnue_common.h"
  
@@@ -39,68 -39,28 +39,69 @@@ namespace Stockfish::Eval::NNUE::Featur
      // unique number for each piece type on each square
      enum {
        PS_NONE     =  0,
-       PS_W_PAWN   =  1,
-       PS_B_PAWN   =  1 * SQUARE_NB_CHESS + 1,
-       PS_W_KNIGHT =  2 * SQUARE_NB_CHESS + 1,
-       PS_B_KNIGHT =  3 * SQUARE_NB_CHESS + 1,
-       PS_W_BISHOP =  4 * SQUARE_NB_CHESS + 1,
-       PS_B_BISHOP =  5 * SQUARE_NB_CHESS + 1,
-       PS_W_ROOK   =  6 * SQUARE_NB_CHESS + 1,
-       PS_B_ROOK   =  7 * SQUARE_NB_CHESS + 1,
-       PS_W_QUEEN  =  8 * SQUARE_NB_CHESS + 1,
-       PS_B_QUEEN  =  9 * SQUARE_NB_CHESS + 1,
-       PS_NB       = 10 * SQUARE_NB_CHESS + 1,
+       PS_W_PAWN   =  0,
 -      PS_B_PAWN   =  1 * SQUARE_NB,
 -      PS_W_KNIGHT =  2 * SQUARE_NB,
 -      PS_B_KNIGHT =  3 * SQUARE_NB,
 -      PS_W_BISHOP =  4 * SQUARE_NB,
 -      PS_B_BISHOP =  5 * SQUARE_NB,
 -      PS_W_ROOK   =  6 * SQUARE_NB,
 -      PS_B_ROOK   =  7 * SQUARE_NB,
 -      PS_W_QUEEN  =  8 * SQUARE_NB,
 -      PS_B_QUEEN  =  9 * SQUARE_NB,
 -      PS_KING     =  10 * SQUARE_NB,
 -      PS_NB = 11 * SQUARE_NB
++      PS_B_PAWN   =  1 * SQUARE_NB_CHESS,
++      PS_W_KNIGHT =  2 * SQUARE_NB_CHESS,
++      PS_B_KNIGHT =  3 * SQUARE_NB_CHESS,
++      PS_W_BISHOP =  4 * SQUARE_NB_CHESS,
++      PS_B_BISHOP =  5 * SQUARE_NB_CHESS,
++      PS_W_ROOK   =  6 * SQUARE_NB_CHESS,
++      PS_B_ROOK   =  7 * SQUARE_NB_CHESS,
++      PS_W_QUEEN  =  8 * SQUARE_NB_CHESS,
++      PS_B_QUEEN  =  9 * SQUARE_NB_CHESS,
++      PS_KING     =  10 * SQUARE_NB_CHESS,
++      PS_NB = 11 * SQUARE_NB_CHESS
      };
  
 -    static constexpr IndexType PieceSquareIndex[COLOR_NB][PIECE_NB] = {
 +    static constexpr uint32_t PieceSquareIndex[COLOR_NB][PIECE_NB] = {
        // convention: W - us, B - them
        // viewed from other side, W and B are reversed
 -      { PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_KING, PS_NONE,
 -        PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_KING, PS_NONE },
 -      { PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_KING, PS_NONE,
 -        PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_KING, PS_NONE }
 +      {
-         PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_W_QUEEN, PS_W_BISHOP,
-         PS_W_BISHOP, PS_W_BISHOP, PS_W_QUEEN, PS_W_QUEEN, PS_NONE, PS_NONE, PS_W_QUEEN, PS_W_KNIGHT,
-         PS_W_BISHOP, PS_W_KNIGHT, PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_W_BISHOP, PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_NONE,
++        PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +
 +        PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_B_QUEEN, PS_B_BISHOP,
-         PS_B_BISHOP, PS_B_BISHOP, PS_B_QUEEN, PS_B_QUEEN, PS_NONE, PS_NONE, PS_B_QUEEN, PS_B_KNIGHT,
-         PS_B_BISHOP, PS_B_KNIGHT, PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_B_BISHOP, PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +      },
 +
 +      {
 +        PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_B_QUEEN, PS_B_BISHOP,
-         PS_B_BISHOP, PS_B_BISHOP, PS_B_QUEEN, PS_B_QUEEN, PS_NONE, PS_NONE, PS_B_QUEEN, PS_B_KNIGHT,
-         PS_B_BISHOP, PS_B_KNIGHT, PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_B_BISHOP, PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +
-         PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_W_QUEEN, PS_W_BISHOP,
-         PS_W_BISHOP, PS_W_BISHOP, PS_W_QUEEN, PS_W_QUEEN, PS_NONE, PS_NONE, PS_W_QUEEN, PS_W_KNIGHT,
-         PS_W_BISHOP, PS_W_KNIGHT, PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_W_BISHOP, PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_NONE,
++        PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +      }
      };
 +    // Check that the fragile array definition is correct
 +    static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, PAWN)] == PS_W_PAWN);
-     static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, KING)] == PS_NONE);
++    static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, KING)] == PS_KING);
 +    static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, PAWN)] == PS_B_PAWN);
-     static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, KING)] == PS_NONE);
++    static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, KING)] == PS_KING);
 +
  
      // Orient a square according to perspective (rotates by 180 for black)
      static Square orient(Color perspective, Square s);
  
      // Number of feature dimensions
      static constexpr IndexType Dimensions =
 -        static_cast<IndexType>(SQUARE_NB) * static_cast<IndexType>(PS_NB);
 +        static_cast<IndexType>(SQUARE_NB_CHESS) * static_cast<IndexType>(PS_NB);
  
-     // Maximum number of simultaneously active features. 30 because kins are not included.
-     static constexpr IndexType MaxActiveDimensions = 30;
+     // Maximum number of simultaneously active features.
+     static constexpr IndexType MaxActiveDimensions = 32;
  
      // Get a list of indices for active features
      static void append_active_indices(
index 0d7e2fa,0000000..6c58d87
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,115 @@@
 +/*
 +  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
 +  Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
 +
 +  Stockfish is free software: you can redistribute it and/or modify
 +  it under the terms of the GNU General Public License as published by
 +  the Free Software Foundation, either version 3 of the License, or
 +  (at your option) any later version.
 +
 +  Stockfish is distributed in the hope that it will be useful,
 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +  GNU General Public License for more details.
 +
 +  You should have received a copy of the GNU General Public License
 +  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
- //Definition of input features HalfKP of NNUE evaluation function
++//Definition of input features HalfKAv2 of NNUE evaluation function
 +
- #include "half_kp_shogi.h"
++#include "half_ka_v2_shogi.h"
 +
 +#include "../../position.h"
 +
 +namespace Stockfish::Eval::NNUE::Features {
 +
 +  constexpr Square rotate(Square s) {
 +    return Square(SQUARE_NB_SHOGI - 1 - int(s));
 +  }
 +
 +  constexpr Square to_shogi_square(Square s) {
 +    return Square((8 - s % 12) * 9 + 8 - s / 12);
 +  }
 +
 +  // Orient a square according to perspective (rotates by 180 for black)
-   inline Square HalfKPShogi::orient(Color perspective, Square s) {
++  inline Square HalfKAv2Shogi::orient(Color perspective, Square s) {
 +    return perspective == WHITE ? to_shogi_square(s) : rotate(to_shogi_square(s));
 +  }
 +
 +  // Index of a feature for a given king position and another piece on some square
-   inline IndexType HalfKPShogi::make_index(Color perspective, Square s, Piece pc, Square ksq) {
-     return IndexType(orient(perspective, s) + PieceSquareIndexShogi[perspective][pc] + SHOGI_PS_END * ksq);
++  inline IndexType HalfKAv2Shogi::make_index(Color perspective, Square s, Piece pc, Square ksq) {
++    return IndexType(orient(perspective, s) + PieceSquareIndexShogi[perspective][pc] + SHOGI_PS_NB * ksq);
 +  }
 +
 +  // Index of a feature for a given king position and hand piece
-   inline IndexType HalfKPShogi::make_index(Color perspective, Color c, int hand_index, PieceType pt, Square ksq) {
++  inline IndexType HalfKAv2Shogi::make_index(Color perspective, Color c, int hand_index, PieceType pt, Square ksq) {
 +    Color color = (c == perspective) ? WHITE : BLACK;
-     return IndexType(hand_index + PieceSquareIndexShogiHand[color][pt] + SHOGI_PS_END * ksq);
++    return IndexType(hand_index + PieceSquareIndexShogiHand[color][pt] + SHOGI_PS_NB * ksq);
 +  }
 +
 +  // Get a list of indices for active features
-   void HalfKPShogi::append_active_indices(
++  void HalfKAv2Shogi::append_active_indices(
 +    const Position& pos,
 +    Color perspective,
 +    ValueListInserter<IndexType> active
 +  ) {
 +    Square ksq = orient(perspective, pos.square<KING>(perspective));
-     Bitboard bb = pos.pieces() & ~pos.pieces(KING);
-     while (bb) {
++    Bitboard bb = pos.pieces();
++    while (bb)
++    {
 +      Square s = pop_lsb(bb);
 +      active.push_back(make_index(perspective, s, pos.piece_on(s), ksq));
 +    }
 +
 +    // Indices for pieces in hand
 +    for (Color c : {WHITE, BLACK})
 +        for (PieceType pt : pos.piece_types())
 +            for (int i = 0; i < pos.count_in_hand(c, pt); i++)
 +                active.push_back(make_index(perspective, c, i, pt, ksq));
 +  }
 +
 +  // append_changed_indices() : get a list of indices for recently changed features
 +
-   void HalfKPShogi::append_changed_indices(
++  void HalfKAv2Shogi::append_changed_indices(
 +    Square ksq,
 +    StateInfo* st,
 +    Color perspective,
 +    ValueListInserter<IndexType> removed,
-     ValueListInserter<IndexType> added,
-     const Position& pos
++    ValueListInserter<IndexType> added
 +  ) {
 +    const auto& dp = st->dirtyPiece;
 +    Square oriented_ksq = orient(perspective, ksq);
 +    for (int i = 0; i < dp.dirty_num; ++i) {
 +      Piece pc = dp.piece[i];
-       if (type_of(pc) == pos.nnue_king()) continue;
 +      if (dp.from[i] != SQ_NONE)
 +        removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq));
 +      else if (dp.dirty_num == 1)
 +      {
 +        Piece handPc = dp.handPiece[i];
 +        removed.push_back(make_index(perspective, color_of(handPc), dp.handCount[i], type_of(handPc), oriented_ksq));
 +      }
 +      if (dp.to[i] != SQ_NONE)
 +        added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq));
 +      else if (i == 1)
 +      {
 +        Piece handPc = dp.handPiece[i];
 +        added.push_back(make_index(perspective, color_of(handPc), dp.handCount[i] - 1, type_of(handPc), oriented_ksq));
 +      }
 +    }
 +  }
 +
-   int HalfKPShogi::update_cost(StateInfo* st) {
++  int HalfKAv2Shogi::update_cost(StateInfo* st) {
 +    return st->dirtyPiece.dirty_num;
 +  }
 +
-   int HalfKPShogi::refresh_cost(const Position& pos) {
-     return pos.count<ALL_PIECES>() - 2;
++  int HalfKAv2Shogi::refresh_cost(const Position& pos) {
++    return pos.count<ALL_PIECES>();
 +  }
 +
-   bool HalfKPShogi::requires_refresh(StateInfo* st, Color perspective, const Position& pos) {
-     return st->dirtyPiece.piece[0] == make_piece(perspective, pos.nnue_king());
++  bool HalfKAv2Shogi::requires_refresh(StateInfo* st, Color perspective) {
++    return st->dirtyPiece.piece[0] == make_piece(perspective, KING);
 +  }
 +
 +
 +}  // namespace Stockfish::Eval::NNUE::Features
index f6033b0,0000000..17f4c59
mode 100644,000000..100644
--- /dev/null
@@@ -1,209 -1,0 +1,207 @@@
 +/*
 +  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
 +  Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
 +
 +  Stockfish is free software: you can redistribute it and/or modify
 +  it under the terms of the GNU General Public License as published by
 +  the Free Software Foundation, either version 3 of the License, or
 +  (at your option) any later version.
 +
 +  Stockfish is distributed in the hope that it will be useful,
 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +  GNU General Public License for more details.
 +
 +  You should have received a copy of the GNU General Public License
 +  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
- //Definition of input features HalfKP of NNUE evaluation function
++//Definition of input features HalfKAv2 of NNUE evaluation function
 +
- #ifndef NNUE_FEATURES_HALF_KP_SHOGI_H_INCLUDED
- #define NNUE_FEATURES_HALF_KP_SHOGI_H_INCLUDED
++#ifndef NNUE_FEATURES_HALF_KA_V2_SHOGI_H_INCLUDED
++#define NNUE_FEATURES_HALF_KA_V2_SHOGI_H_INCLUDED
 +
 +#include "../nnue_common.h"
 +
 +#include "../../evaluate.h"
 +#include "../../misc.h"
 +
 +namespace Stockfish {
 +  struct StateInfo;
 +}
 +
 +namespace Stockfish::Eval::NNUE::Features {
 +
-   // Feature HalfKP: Combination of the position of own king
-   // and the position of pieces other than kings
-   class HalfKPShogi {
++  // Feature HalfKAv2: Combination of the position of own king
++  // and the position of pieces
++  class HalfKAv2Shogi {
 +
++    // unique number for each piece type on each square
 +    enum {
-       PS_NONE             =  0,
-       SHOGI_HAND_W_PAWN   =   1,
-       SHOGI_HAND_B_PAWN   =  20,
-       SHOGI_HAND_W_LANCE  =  39,
-       SHOGI_HAND_B_LANCE  =  44,
-       SHOGI_HAND_W_KNIGHT =  49,
-       SHOGI_HAND_B_KNIGHT =  54,
-       SHOGI_HAND_W_SILVER =  59,
-       SHOGI_HAND_B_SILVER =  64,
-       SHOGI_HAND_W_GOLD   =  69,
-       SHOGI_HAND_B_GOLD   =  74,
-       SHOGI_HAND_W_BISHOP =  79,
-       SHOGI_HAND_B_BISHOP =  82,
-       SHOGI_HAND_W_ROOK   =  85,
-       SHOGI_HAND_B_ROOK   =  88,
-       SHOGI_HAND_END      =  90,
++      PS_NONE             =   0,
++      SHOGI_HAND_W_PAWN   =   0,
++      SHOGI_HAND_B_PAWN   =  19,
++      SHOGI_HAND_W_LANCE  =  38,
++      SHOGI_HAND_B_LANCE  =  43,
++      SHOGI_HAND_W_KNIGHT =  48,
++      SHOGI_HAND_B_KNIGHT =  53,
++      SHOGI_HAND_W_SILVER =  58,
++      SHOGI_HAND_B_SILVER =  63,
++      SHOGI_HAND_W_GOLD   =  68,
++      SHOGI_HAND_B_GOLD   =  73,
++      SHOGI_HAND_W_BISHOP =  78,
++      SHOGI_HAND_B_BISHOP =  81,
++      SHOGI_HAND_W_ROOK   =  84,
++      SHOGI_HAND_B_ROOK   =  87,
++      SHOGI_HAND_END      =  89,
 +
 +      SHOGI_PS_W_PAWN     =  SHOGI_HAND_END,
 +      SHOGI_PS_B_PAWN     =  1 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_LANCE    =  2 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_LANCE    =  3 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_KNIGHT   =  4 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_KNIGHT   =  5 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_SILVER   =  6 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_SILVER   =  7 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_GOLD     =  8 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_GOLD     =  9 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_BISHOP   = 10 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_BISHOP   = 11 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_HORSE    = 12 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_HORSE    = 13 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_ROOK     = 14 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_ROOK     = 15 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_W_DRAGON   = 16 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +      SHOGI_PS_B_DRAGON   = 17 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
-       SHOGI_PS_W_KING     = 18 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
-       SHOGI_PS_END        = SHOGI_PS_W_KING, // pieces without kings (pawns included)
-       SHOGI_PS_B_KING     = 19 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
-       SHOGI_PS_END2       = 20 * SQUARE_NB_SHOGI + SHOGI_HAND_END
++      SHOGI_PS_KING       = 18 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
++      SHOGI_PS_NB         = 19 * SQUARE_NB_SHOGI + SHOGI_HAND_END,
 +    };
 +
 +    static constexpr uint32_t PieceSquareIndexShogi[COLOR_NB][PIECE_NB] = {
 +      // convention: W - us, B - them
 +      // viewed from other side, W and B are reversed
 +      {
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_BISHOP, SHOGI_PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_PS_W_SILVER, PS_NONE, SHOGI_PS_W_DRAGON, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_PAWN, SHOGI_PS_W_LANCE, SHOGI_PS_W_KNIGHT, SHOGI_PS_W_GOLD, SHOGI_PS_W_HORSE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_KING,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_KING,
 +
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_BISHOP, SHOGI_PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_PS_B_SILVER, PS_NONE, SHOGI_PS_B_DRAGON, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_PAWN, SHOGI_PS_B_LANCE, SHOGI_PS_B_KNIGHT, SHOGI_PS_B_GOLD, SHOGI_PS_B_HORSE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_KING
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_KING
 +      },
 +
 +      {
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_BISHOP, SHOGI_PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_PS_B_SILVER, PS_NONE, SHOGI_PS_B_DRAGON, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_PAWN, SHOGI_PS_B_LANCE, SHOGI_PS_B_KNIGHT, SHOGI_PS_B_GOLD, SHOGI_PS_B_HORSE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_B_KING,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_KING,
 +
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_BISHOP, SHOGI_PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_PS_W_SILVER, PS_NONE, SHOGI_PS_W_DRAGON, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_PAWN, SHOGI_PS_W_LANCE, SHOGI_PS_W_KNIGHT, SHOGI_PS_W_GOLD, SHOGI_PS_W_HORSE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_W_KING
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, SHOGI_PS_KING
 +      }
 +    };
 +    static_assert(PieceSquareIndexShogi[WHITE][make_piece(WHITE, SHOGI_PAWN)] == SHOGI_PS_W_PAWN);
-     static_assert(PieceSquareIndexShogi[WHITE][make_piece(WHITE, KING)] == SHOGI_PS_W_KING);
++    static_assert(PieceSquareIndexShogi[WHITE][make_piece(WHITE, KING)] == SHOGI_PS_KING);
 +    static_assert(PieceSquareIndexShogi[WHITE][make_piece(BLACK, SHOGI_PAWN)] == SHOGI_PS_B_PAWN);
-     static_assert(PieceSquareIndexShogi[WHITE][make_piece(BLACK, KING)] == SHOGI_PS_B_KING);
++    static_assert(PieceSquareIndexShogi[WHITE][make_piece(BLACK, KING)] == SHOGI_PS_KING);
 +
 +    static constexpr uint32_t PieceSquareIndexShogiHand[COLOR_NB][PIECE_TYPE_NB] = {
 +      // convention: W - us, B - them
 +      // viewed from other side, W and B are reversed
 +      {
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_HAND_W_BISHOP, SHOGI_HAND_W_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_HAND_W_SILVER, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_HAND_W_PAWN, SHOGI_HAND_W_LANCE, SHOGI_HAND_W_KNIGHT, SHOGI_HAND_W_GOLD, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE
 +      },
 +
 +      {
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_HAND_B_BISHOP, SHOGI_HAND_B_ROOK, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, SHOGI_HAND_B_SILVER, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, SHOGI_HAND_B_PAWN, SHOGI_HAND_B_LANCE, SHOGI_HAND_B_KNIGHT, SHOGI_HAND_B_GOLD, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE
 +      }
 +    };
 +    static_assert(PieceSquareIndexShogiHand[WHITE][SHOGI_PAWN] == SHOGI_HAND_W_PAWN);
 +    static_assert(PieceSquareIndexShogiHand[WHITE][GOLD] == SHOGI_HAND_W_GOLD);
 +    static_assert(PieceSquareIndexShogiHand[BLACK][SHOGI_PAWN] == SHOGI_HAND_B_PAWN);
 +    static_assert(PieceSquareIndexShogiHand[BLACK][GOLD] == SHOGI_HAND_B_GOLD);
 +
 +    // Orient a square according to perspective (rotates by 180 for black)
 +    static Square orient(Color perspective, Square s);
 +
 +    // Index of a feature for a given king position and another piece on some square
 +    static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq);
 +
 +    // Index of a feature for a given king position and a piece in hand
 +    static IndexType make_index(Color perspective, Color c, int hand_index, PieceType pt, Square ksq);
 +
 +   public:
 +    // Feature name
-     static constexpr const char* Name = "HalfKP(Friend)";
++    static constexpr const char* Name = "HalfKAv2(Friend)";
 +
 +    // Hash value embedded in the evaluation file
-     static constexpr std::uint32_t HashValue = 0x5D69D5B8u;
++    static constexpr std::uint32_t HashValue = 0x5f234cb8u;
 +
 +    // Number of feature dimensions
 +    static constexpr IndexType Dimensions =
-         static_cast<IndexType>(SQUARE_NB_SHOGI) * static_cast<IndexType>(SHOGI_PS_END);
++        static_cast<IndexType>(SQUARE_NB_SHOGI) * static_cast<IndexType>(SHOGI_PS_NB);
 +
-     // Maximum number of simultaneously active features. 38 because kins are not included.
-     static constexpr IndexType MaxActiveDimensions = 38;
++    // Maximum number of simultaneously active features.
++    static constexpr IndexType MaxActiveDimensions = 40;
 +
 +    // Get a list of indices for active features
 +    static void append_active_indices(
 +      const Position& pos,
 +      Color perspective,
 +      ValueListInserter<IndexType> active);
 +
 +    // Get a list of indices for recently changed features
 +    static void append_changed_indices(
 +      Square ksq,
 +      StateInfo* st,
 +      Color perspective,
 +      ValueListInserter<IndexType> removed,
-       ValueListInserter<IndexType> added,
-       const Position& pos);
++      ValueListInserter<IndexType> added);
 +
 +    // Returns the cost of updating one perspective, the most costly one.
 +    // Assumes no refresh needed.
 +    static int update_cost(StateInfo* st);
 +    static int refresh_cost(const Position& pos);
 +
 +    // Returns whether the change stored in this StateInfo means that
 +    // a full accumulator refresh is required.
-     static bool requires_refresh(StateInfo* st, Color perspective, const Position& pos);
++    static bool requires_refresh(StateInfo* st, Color perspective);
 +  };
 +
 +}  // namespace Stockfish::Eval::NNUE::Features
 +
- #endif // #ifndef NNUE_FEATURES_HALF_KP_SHOGI_H_INCLUDED
++#endif // #ifndef NNUE_FEATURES_HALF_KA_V2_SHOGI_H_INCLUDED
index d93107f,0000000..fc07923
mode 100644,000000..100644
--- /dev/null
@@@ -1,112 -1,0 +1,112 @@@
 +/*
 +  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
 +  Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
 +
 +  Stockfish is free software: you can redistribute it and/or modify
 +  it under the terms of the GNU General Public License as published by
 +  the Free Software Foundation, either version 3 of the License, or
 +  (at your option) any later version.
 +
 +  Stockfish is distributed in the hope that it will be useful,
 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +  GNU General Public License for more details.
 +
 +  You should have received a copy of the GNU General Public License
 +  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
- //Definition of input features HalfKP of NNUE evaluation function
++//Definition of input features HalfKAv2 of NNUE evaluation function
 +
- #include "half_kp_variants.h"
++#include "half_ka_v2_variants.h"
 +
 +#ifdef LARGEBOARDS
- #include "half_kp_shogi.h"
++#include "half_ka_v2_shogi.h"
 +#endif
 +
 +#include "../../position.h"
 +
 +namespace Stockfish::Eval::NNUE::Features {
 +
 +  // Map square to numbering on 8x8 board
 +  constexpr Square to_chess_square(Square s) {
 +    return Square(s - rank_of(s) * (FILE_MAX - FILE_H));
 +  }
 +
 +  // Orient a square according to perspective (rotates by 180 for black)
-   inline Square HalfKPVariants::orient(Color perspective, Square s, const Position& pos) {
++  inline Square HalfKAv2Variants::orient(Color perspective, Square s, const Position& pos) {
 +    return to_chess_square(  perspective == WHITE || (pos.capture_the_flag(BLACK) & Rank8BB) ? s
-                            : flip_rank(flip_file(s, pos.max_file()), pos.max_rank()));
++                           : flip_rank(s, pos.max_rank()));
 +  }
 +
 +  // Index of a feature for a given king position and another piece on some square
-   inline IndexType HalfKPVariants::make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos) {
++  inline IndexType HalfKAv2Variants::make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos) {
 +    return IndexType(orient(perspective, s, pos) + PieceSquareIndex[perspective][pc] + PS_NB * ksq);
 +  }
 +
 +  // Get a list of indices for active features
-   void HalfKPVariants::append_active_indices(
++  void HalfKAv2Variants::append_active_indices(
 +    const Position& pos,
 +    Color perspective,
 +    ValueListInserter<IndexType> active
 +  ) {
 +    // Re-route to shogi features
 +#ifdef LARGEBOARDS
 +    if (currentNnueFeatures == NNUE_SHOGI)
 +    {
-         assert(HalfKPShogi::Dimensions <= Dimensions);
-         return HalfKPShogi::append_active_indices(pos, perspective, active);
++        assert(HalfKAv2Shogi::Dimensions <= Dimensions);
++        return HalfKAv2Shogi::append_active_indices(pos, perspective, active);
 +    }
 +#endif
 +
 +    Square oriented_ksq = orient(perspective, pos.square(perspective, pos.nnue_king()), pos);
-     Bitboard bb = pos.pieces() & ~pos.pieces(pos.nnue_king());
-     while (bb) {
++    Bitboard bb = pos.pieces();
++    while (bb)
++    {
 +      Square s = pop_lsb(bb);
 +      active.push_back(make_index(perspective, s, pos.piece_on(s), oriented_ksq, pos));
 +    }
 +  }
 +
 +  // append_changed_indices() : get a list of indices for recently changed features
 +
-   void HalfKPVariants::append_changed_indices(
++  void HalfKAv2Variants::append_changed_indices(
 +    Square ksq,
 +    StateInfo* st,
 +    Color perspective,
 +    ValueListInserter<IndexType> removed,
 +    ValueListInserter<IndexType> added,
 +    const Position& pos
 +  ) {
 +    // Re-route to shogi features
 +#ifdef LARGEBOARDS
 +    if (currentNnueFeatures == NNUE_SHOGI)
 +    {
-         assert(HalfKPShogi::Dimensions <= Dimensions);
-         return HalfKPShogi::append_changed_indices(ksq, st, perspective, removed, added, pos);
++        assert(HalfKAv2Shogi::Dimensions <= Dimensions);
++        return HalfKAv2Shogi::append_changed_indices(ksq, st, perspective, removed, added);
 +    }
 +#endif
 +    const auto& dp = st->dirtyPiece;
 +    Square oriented_ksq = orient(perspective, ksq, pos);
 +    for (int i = 0; i < dp.dirty_num; ++i) {
 +      Piece pc = dp.piece[i];
-       if (type_of(pc) == pos.nnue_king()) continue;
 +      if (dp.from[i] != SQ_NONE)
 +        removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq, pos));
 +      if (dp.to[i] != SQ_NONE)
 +        added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq, pos));
 +    }
 +  }
 +
-   int HalfKPVariants::update_cost(StateInfo* st) {
++  int HalfKAv2Variants::update_cost(StateInfo* st) {
 +    return st->dirtyPiece.dirty_num;
 +  }
 +
-   int HalfKPVariants::refresh_cost(const Position& pos) {
-     return pos.count<ALL_PIECES>() - 2;
++  int HalfKAv2Variants::refresh_cost(const Position& pos) {
++    return pos.count<ALL_PIECES>();
 +  }
 +
-   bool HalfKPVariants::requires_refresh(StateInfo* st, Color perspective, const Position& pos) {
++  bool HalfKAv2Variants::requires_refresh(StateInfo* st, Color perspective, const Position& pos) {
 +    return st->dirtyPiece.piece[0] == make_piece(perspective, pos.nnue_king());
 +  }
 +
 +}  // namespace Stockfish::Eval::NNUE::Features
index f095737,0000000..118e2db
mode 100644,000000..100644
--- /dev/null
@@@ -1,164 -1,0 +1,165 @@@
 +/*
 +  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
 +  Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
 +
 +  Stockfish is free software: you can redistribute it and/or modify
 +  it under the terms of the GNU General Public License as published by
 +  the Free Software Foundation, either version 3 of the License, or
 +  (at your option) any later version.
 +
 +  Stockfish is distributed in the hope that it will be useful,
 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +  GNU General Public License for more details.
 +
 +  You should have received a copy of the GNU General Public License
 +  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +*/
 +
- //Definition of input features HalfKP of NNUE evaluation function
++//Definition of input features HalfKAv2 of NNUE evaluation function
 +
- #ifndef NNUE_FEATURES_HALF_KP_VARIANTS_H_INCLUDED
- #define NNUE_FEATURES_HALF_KP_VARIANTS_H_INCLUDED
++#ifndef NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
++#define NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
 +
 +#include "../nnue_common.h"
 +
 +#include "../../evaluate.h"
 +#include "../../misc.h"
 +
- #include "half_kp_shogi.h"
- #include "half_kp.h"
++#include "half_ka_v2_shogi.h"
++#include "half_ka_v2.h"
 +
 +namespace Stockfish {
 +  struct StateInfo;
 +}
 +
 +namespace Stockfish::Eval::NNUE::Features {
 +
-   // Feature HalfKP: Combination of the position of own king
-   // and the position of pieces other than kings
-   class HalfKPVariants {
++  // Feature HalfKAv2: Combination of the position of own king
++  // and the position of pieces
++  class HalfKAv2Variants {
 +
 +    // unique number for each piece type on each square
 +    enum {
 +      PS_NONE     =  0,
-       PS_W_PAWN   =  1,
-       PS_B_PAWN   =  1 * SQUARE_NB_CHESS + 1,
-       PS_W_KNIGHT =  2 * SQUARE_NB_CHESS + 1,
-       PS_B_KNIGHT =  3 * SQUARE_NB_CHESS + 1,
-       PS_W_BISHOP =  4 * SQUARE_NB_CHESS + 1,
-       PS_B_BISHOP =  5 * SQUARE_NB_CHESS + 1,
-       PS_W_ROOK   =  6 * SQUARE_NB_CHESS + 1,
-       PS_B_ROOK   =  7 * SQUARE_NB_CHESS + 1,
-       PS_W_QUEEN  =  8 * SQUARE_NB_CHESS + 1,
-       PS_B_QUEEN  =  9 * SQUARE_NB_CHESS + 1,
-       PS_NB       = 10 * SQUARE_NB_CHESS + 1,
++      PS_W_PAWN   =  0,
++      PS_B_PAWN   =  1 * SQUARE_NB_CHESS,
++      PS_W_KNIGHT =  2 * SQUARE_NB_CHESS,
++      PS_B_KNIGHT =  3 * SQUARE_NB_CHESS,
++      PS_W_BISHOP =  4 * SQUARE_NB_CHESS,
++      PS_B_BISHOP =  5 * SQUARE_NB_CHESS,
++      PS_W_ROOK   =  6 * SQUARE_NB_CHESS,
++      PS_B_ROOK   =  7 * SQUARE_NB_CHESS,
++      PS_W_QUEEN  =  8 * SQUARE_NB_CHESS,
++      PS_B_QUEEN  =  9 * SQUARE_NB_CHESS,
++      PS_KING     =  10 * SQUARE_NB_CHESS,
++      PS_NB = 11 * SQUARE_NB_CHESS
 +    };
 +
 +    static constexpr uint32_t PieceSquareIndex[COLOR_NB][PIECE_NB] = {
 +      // convention: W - us, B - them
 +      // viewed from other side, W and B are reversed
 +      {
 +        PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_W_QUEEN, PS_W_BISHOP,
 +        PS_W_BISHOP, PS_W_BISHOP, PS_W_QUEEN, PS_W_QUEEN, PS_NONE, PS_NONE, PS_W_QUEEN, PS_W_KNIGHT,
 +        PS_W_BISHOP, PS_W_KNIGHT, PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_W_BISHOP, PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +
 +        PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_B_QUEEN, PS_B_BISHOP,
 +        PS_B_BISHOP, PS_B_BISHOP, PS_B_QUEEN, PS_B_QUEEN, PS_NONE, PS_NONE, PS_B_QUEEN, PS_B_KNIGHT,
 +        PS_B_BISHOP, PS_B_KNIGHT, PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_B_BISHOP, PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +      },
 +
 +      {
 +        PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_B_BISHOP, PS_B_ROOK, PS_B_QUEEN, PS_B_QUEEN, PS_B_BISHOP,
 +        PS_B_BISHOP, PS_B_BISHOP, PS_B_QUEEN, PS_B_QUEEN, PS_NONE, PS_NONE, PS_B_QUEEN, PS_B_KNIGHT,
 +        PS_B_BISHOP, PS_B_KNIGHT, PS_B_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_B_BISHOP, PS_NONE, PS_B_PAWN, PS_B_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +
 +        PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_W_BISHOP, PS_W_ROOK, PS_W_QUEEN, PS_W_QUEEN, PS_W_BISHOP,
 +        PS_W_BISHOP, PS_W_BISHOP, PS_W_QUEEN, PS_W_QUEEN, PS_NONE, PS_NONE, PS_W_QUEEN, PS_W_KNIGHT,
 +        PS_W_BISHOP, PS_W_KNIGHT, PS_W_ROOK, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_W_BISHOP, PS_NONE, PS_W_PAWN, PS_W_KNIGHT, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
 +        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
-         PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE,
++        PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_NONE, PS_KING,
 +      }
 +    };
 +    // Check that the fragile array definition is correct
 +    static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, PAWN)] == PS_W_PAWN);
-     static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, KING)] == PS_NONE);
++    static_assert(PieceSquareIndex[WHITE][make_piece(WHITE, KING)] == PS_KING);
 +    static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, PAWN)] == PS_B_PAWN);
-     static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, KING)] == PS_NONE);
++    static_assert(PieceSquareIndex[WHITE][make_piece(BLACK, KING)] == PS_KING);
 +
 +    // Orient a square according to perspective (rotates by 180 for black)
 +    static Square orient(Color perspective, Square s, const Position& pos);
 +
 +    // Index of a feature for a given king position and another piece on some square
 +    static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos);
 +
 +   public:
 +    // Feature name
-     static constexpr const char* Name = "HalfKP(Friend)";
++    static constexpr const char* Name = "HalfKAv2(Friend)";
 +
 +    // Hash value embedded in the evaluation file
-     static constexpr std::uint32_t HashValue = 0x5D69D5B8u;
++    static constexpr std::uint32_t HashValue = 0x5f234cb8u;
 +
 +    // Number of feature dimensions
 +    static constexpr IndexType Dimensions =
 +#ifdef LARGEBOARDS
-         HalfKPShogi::Dimensions;
++        HalfKAv2Shogi::Dimensions;
 +#else
-         HalfKPChess::Dimensions;
++        HalfKAv2::Dimensions;
 +#endif
 +
 +    static IndexType get_dimensions() {
-       return  currentNnueFeatures == NNUE_SHOGI ? HalfKPShogi::Dimensions
-             : currentNnueFeatures == NNUE_CHESS ? HalfKPChess::Dimensions
++      return  currentNnueFeatures == NNUE_SHOGI ? HalfKAv2Shogi::Dimensions
++            : currentNnueFeatures == NNUE_CHESS ? HalfKAv2::Dimensions
 +                                                : SQUARE_NB_CHESS * PS_NB;
 +    }
 +
-     // Maximum number of simultaneously active features. 30 because kins are not included.
++    // Maximum number of simultaneously active features.
 +    static constexpr IndexType MaxActiveDimensions = 64;
 +
 +    // Get a list of indices for active features
 +    static void append_active_indices(
 +      const Position& pos,
 +      Color perspective,
 +      ValueListInserter<IndexType> active);
 +
 +    // Get a list of indices for recently changed features
 +    static void append_changed_indices(
 +      Square ksq,
 +      StateInfo* st,
 +      Color perspective,
 +      ValueListInserter<IndexType> removed,
 +      ValueListInserter<IndexType> added,
 +      const Position& pos);
 +
 +    // Returns the cost of updating one perspective, the most costly one.
 +    // Assumes no refresh needed.
 +    static int update_cost(StateInfo* st);
 +    static int refresh_cost(const Position& pos);
 +
 +    // Returns whether the change stored in this StateInfo means that
 +    // a full accumulator refresh is required.
 +    static bool requires_refresh(StateInfo* st, Color perspective, const Position& pos);
 +  };
 +
 +}  // namespace Stockfish::Eval::NNUE::Features
 +
- #endif // #ifndef NNUE_FEATURES_HALF_KP_VARIANTS_H_INCLUDED
++#endif // #ifndef NNUE_FEATURES_HALF_KA_V2_VARIANTS_H_INCLUDED
@@@ -23,8 -23,7 +23,7 @@@
  
  #include "nnue_common.h"
  
- //#include "features/half_kp.h"
- #include "features/half_kp_variants.h"
 -#include "features/half_ka_v2.h"
++#include "features/half_ka_v2_variants.h"
  
  #include "layers/input_slice.h"
  #include "layers/affine_transform.h"
  namespace Stockfish::Eval::NNUE {
  
    // Input features used in evaluation function
-   //using FeatureSet = Features::HalfKPChess;
-   using FeatureSet = Features::HalfKPVariants;
 -  using FeatureSet = Features::HalfKAv2;
++  using FeatureSet = Features::HalfKAv2Variants;
  
    // Number of input feature dimensions after conversion
-   constexpr IndexType TransformedFeatureDimensions = 256;
+   constexpr IndexType TransformedFeatureDimensions = 512;
+   constexpr IndexType PSQTBuckets = 8;
+   constexpr IndexType LayerStacks = 8;
  
    namespace Layers {
  
@@@ -87,9 -124,13 +124,13 @@@ namespace Stockfish::Eval::NNUE 
      // Number of output dimensions for one side
      static constexpr IndexType HalfDimensions = TransformedFeatureDimensions;
  
 -    static constexpr int LazyThreshold = 1400;
++    static constexpr int LazyThreshold = 14000; // low lazy threshold is detrimental for variants
      #ifdef VECTOR
      static constexpr IndexType TileHeight = NumRegs * sizeof(vec_t) / 2;
+     static constexpr IndexType PsqtTileHeight = NumPsqtRegs * sizeof(psqt_vec_t) / 4;
      static_assert(HalfDimensions % TileHeight == 0, "TileHeight must divide HalfDimensions");
+     static_assert(PSQTBuckets % PsqtTileHeight == 0, "PsqtTileHeight must divide PSQTBuckets");
      #endif
  
     public:
  
      // Read network parameters
      bool read_parameters(std::istream& stream) {
 +
        for (std::size_t i = 0; i < HalfDimensions; ++i)
          biases[i] = read_little_endian<BiasType>(stream);
 -      for (std::size_t i = 0; i < HalfDimensions * InputDimensions; ++i)
 +      for (std::size_t i = 0; i < HalfDimensions * FeatureSet::get_dimensions(); ++i)
          weights[i] = read_little_endian<WeightType>(stream);
 -      for (std::size_t i = 0; i < PSQTBuckets * InputDimensions; ++i)
++      for (std::size_t i = 0; i < PSQTBuckets * FeatureSet::get_dimensions(); ++i)
+         psqtWeights[i] = read_little_endian<PSQTWeightType>(stream);
        return !stream.fail();
      }
  
      bool write_parameters(std::ostream& stream) const {
        for (std::size_t i = 0; i < HalfDimensions; ++i)
          write_little_endian<BiasType>(stream, biases[i]);
--      for (std::size_t i = 0; i < HalfDimensions * InputDimensions; ++i)
++      for (std::size_t i = 0; i < HalfDimensions * FeatureSet::get_dimensions(); ++i)
          write_little_endian<WeightType>(stream, weights[i]);
        return !stream.fail();
      }
diff --cc src/search.cpp
@@@ -937,11 -801,9 +937,11 @@@ namespace 
          && (ss-1)->statScore < 24185
          &&  eval >= beta
          &&  eval >= ss->staticEval
-         &&  ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ')
 -        &&  ss->staticEval >= beta - 22 * depth - 34 * improving + 162 * ss->ttPv + 159
++        &&  ss->staticEval >= beta - 22 * depth - 34 * improving + 162 * ss->ttPv + 159 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ')
          && !excludedMove
          &&  pos.non_pawn_material(us)
 +        &&  pos.count<ALL_PIECES>(~us) != pos.count<PAWN>(~us)
 +        && !pos.flip_enclosed_pieces()
          && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
      {
          assert(eval - beta >= 0);
@@@ -1317,10 -1169,10 +1317,10 @@@ moves_loop: // When in check, search st
                    r += 2;
  
                ss->statScore =  thisThread->mainHistory[us][from_to(move)]
 -                             + (*contHist[0])[movedPiece][to_sq(move)]
 -                             + (*contHist[1])[movedPiece][to_sq(move)]
 -                             + (*contHist[3])[movedPiece][to_sq(move)]
 +                             + (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
 +                             + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
 +                             + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
-                              - 4741;
+                              - 4791;
  
                // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
                if (!ss->inCheck)