Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 30 Mar 2019 15:10:23 +0000 (16:10 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 30 Mar 2019 15:10:23 +0000 (16:10 +0100)
No functional change.

1  2 
src/bitboard.cpp
src/bitboard.h
src/evaluate.cpp
src/movegen.cpp
src/pawns.cpp
src/position.h
src/search.cpp
src/syzygy/tbprobe.cpp
src/ucioption.cpp

  #include "misc.h"
  
  uint8_t PopCnt16[1 << 16];
- int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+ uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
  
 +Bitboard BoardSizeBB[FILE_NB][RANK_NB];
  Bitboard SquareBB[SQUARE_NB];
  Bitboard ForwardRanksBB[COLOR_NB][RANK_NB];
  Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
  Bitboard LineBB[SQUARE_NB][SQUARE_NB];
 -Bitboard DistanceRingBB[SQUARE_NB][8];
 -Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
 -Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
 +Bitboard DistanceRingBB[SQUARE_NB][FILE_NB];
 +Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
  
+ Bitboard KingFlank[FILE_NB] = {
+   QueenSide ^ FileDBB, QueenSide, QueenSide,
+   CenterFiles, CenterFiles,
+   KingSide, KingSide, KingSide ^ FileEBB
+ };
  Magic RookMagics[SQUARE_NB];
  Magic BishopMagics[SQUARE_NB];
  
  namespace {
  
 +#ifdef LARGEBOARDS
 +  Bitboard RookTable[0xA80000];  // To store rook attacks
 +  Bitboard BishopTable[0x33C00]; // To store bishop attacks
 +#else
    Bitboard RookTable[0x19000];  // To store rook attacks
    Bitboard BishopTable[0x1480]; // To store bishop attacks
 -
 +#endif
 +
 +#ifdef PRECOMPUTED_MAGICS
 +#define B(a, b) (Bitboard(a) << 64) ^ Bitboard(b)
 +  // Use precomputed magics if pext is not avaible,
 +  // since the magics generation is very slow.
 +  Bitboard RookMagicInit[SQUARE_NB] = {
 +      B(0x4068000028000894, 0x20006051028),
 +      B(0x2004000042000004, 0x2810000008004000),
 +      B(0x1020000220004000, 0x8004290180020200),
 +      B(0x4310000101000020, 0x8020100004002000),
 +      B(0x38000080211108, 0x118000104000000),
 +      B(0x4050000080400004, 0x2011040500118010),
 +      B(0x4010000048100200, 0x100000840204000),
 +      B(0x4020000820000100, 0x410106024000804),
 +      B(0x910000008D00021, 0x800004400100010),
 +      B(0x6830000821080004, 0x80C00010100000),
 +      B(0x8040000040500008, 0x200031840804901),
 +      B(0x4018000042201000, 0x8300002D80000841),
 +      B(0x100008000044000, 0x1980020094A89400),
 +      B(0x1000004000082000, 0x4408540710000181),
 +      B(0x1206010001100802, 0x40004100048),
 +      B(0x984010000410001, 0x208080028AE),
 +      B(0x411210000261014, 0x8000414100011208),
 +      B(0x8200100000B0002, 0x1082008404000008),
 +      B(0x5004090000400096, 0x10004020001000E2),
 +      B(0x8899220000020001, 0x8401004904082000),
 +      B(0x801720000080040, 0x101000200082020),
 +      B(0x800060000102411, 0xA8200008808400),
 +      B(0x30C0000081004, 0x1004200082100418),
 +      B(0x1018010000020102, 0x4100000040014082),
 +      B(0x24000008000001, 0x4080041809020000),
 +      B(0x3011200814000104, 0x2110004020000000),
 +      B(0x1814410050000800, 0x4041010220000400),
 +      B(0x20B002010000211, 0x100104188808),
 +      B(0x821020000114, 0x22080A0200304020),
 +      B(0xC0E0020000082, 0x1004108210042000),
 +      B(0x9010010000084, 0x2000011014020406),
 +      B(0x400208018000040, 0x20D000052800018),
 +      B(0x108008000080, 0x240400000104),
 +      B(0x8012001080004400, 0x102010420201000),
 +      B(0x1000000C0001210, 0x821000080441200),
 +      B(0x1C500000200004D0, 0x20042084400410),
 +      B(0x4000284000108000, 0x1809420810080140),
 +      B(0x40804004000, 0x2220005410000000),
 +      B(0x4007080A1020000, 0x8004020D41200020),
 +      B(0x1080000800008000, 0x4080210000002002),
 +      B(0x400000400250000, 0x8000001100410000),
 +      B(0xC8010090010001, 0x2004000068009022),
 +      B(0x8300200008210000, 0x410804100111004),
 +      B(0x42150008210000, 0x81100004A400200),
 +      B(0x2C1410001810001, 0x8200800000411020),
 +      B(0x28420004020000, 0x409002880830900),
 +      B(0x200028000008000, 0x8100000040200004),
 +      B(0x4001030120000, 0x41008A020140404),
 +      B(0x288000004240804, 0x2410020000090),
 +      B(0x104202000004004, 0x2008010000040),
 +      B(0x800A020008022020, 0x4112108040400),
 +      B(0x90044001082420, 0x239806020040A),
 +      B(0x4018000414800030, 0x2001100010000),
 +      B(0x102820010088120, 0x8002004090008),
 +      B(0x280100200000410, 0x840441100000),
 +      B(0x4A020000040020, 0x10820040C0881),
 +      B(0x20000010020, 0x21000800402010),
 +      B(0x161A0400212C80, 0x42000400203002),
 +      B(0xAB00800181208440, 0x3120A01004040),
 +      B(0x261100084025060, 0x81800A2100400),
 +      B(0x1008000000A02000, 0x940000010040910),
 +      B(0x1406400004A010, 0x100011080188C05),
 +      B(0x400002000011000, 0x2080005008080002),
 +      B(0x402C1004012, 0x600004200488003),
 +      B(0x1800080802000409, 0x200012061200104),
 +      B(0x843020018100800, 0xE2000040100E0A04),
 +      B(0xA0010200005048, 0x80000851000012),
 +      B(0x20000900041, 0x200006904002024),
 +      B(0x20010000080002, 0x100000490211000),
 +      B(0x1000018070C, 0x4100008200400010),
 +      B(0x40000004101060, 0x40000109A800112),
 +      B(0x44000908010404, 0x2200000420010409),
 +      B(0x169D042288081204, 0x18000040A000),
 +      B(0x1000041002000, 0x6040040001208000),
 +      B(0x130040088200DA, 0x81600004010300),
 +      B(0x3000062004000220, 0x8404200010200020),
 +      B(0xC000102000020A, 0x108200004001000),
 +      B(0x2000008606120000, 0xC010200008010821),
 +      B(0x80040200000100, 0x80080000800440),
 +      B(0x508028000040100, 0x4280000800124),
 +      B(0x5AA422000B810100, 0xA802200002004404),
 +      B(0x10000A0000012100, 0x8080200000400802),
 +      B(0x240048004008102, 0x200400010800100),
 +      B(0x4140030108004, 0x8C012000024909A0),
 +      B(0x1400018A0A8000, 0x90841080008200),
 +      B(0xA500120088001010, 0x4040020200008042),
 +      B(0x5008024008888001, 0x1A0200A00005000),
 +      B(0x4004D13000026, 0x800008008000A012),
 +      B(0x201501022901000E, 0x8000024100001102),
 +      B(0xE80010140000800C, 0x20004B1080000820),
 +      B(0x8011010100046A00, 0x90010000C021),
 +      B(0x1008020008401440, 0x80900020000E088),
 +      B(0x100088000040000, 0x8124800080002200),
 +      B(0x12C04120401200, 0x410500E80004040B),
 +      B(0x9904A0100020008, 0x800108400020040),
 +      B(0x4000842405D0004, 0x10220200000080),
 +      B(0x4000001080802010, 0x4040880A00200001),
 +      B(0x4000001080802010, 0x4040880A00200001),
 +      B(0x800002021008000, 0xA04000420020000C),
 +      B(0x12A6020000304, 0x8290144200000),
 +      B(0x102803020008, 0x40824014A0200000),
 +      B(0x1400020080210008, 0x8001004000500000),
 +      B(0x120000148212, 0x801C001003A00000),
 +      B(0x2020002908040, 0x2000804140200000),
 +      B(0x820000010080, 0x10A2020420200000),
 +      B(0x508200022440, 0xB004001108800040),
 +      B(0x8202004084010C81, 0xC081A03000400008),
 +      B(0xB04080040204050, 0x1810028080200000),
 +      B(0xAA20014010120001, 0x80308004022200),
 +      B(0xAA20014010120001, 0x80308004022200),
 +      B(0x208018020814020, 0x2004020200410A00),
 +      B(0x6000801000002800, 0xC80121082004080),
 +      B(0x84002080140202, 0x8000004100090100),
 +      B(0x3100114050000, 0x2000818014000100),
 +      B(0x280805000008A400, 0x401042000000300),
 +      B(0x245A20000040401, 0x1000850102080200),
 +      B(0x4010430000D00240, 0xD0800001201100),
 +      B(0x20000080040, 0x9053000880500600),
 +      B(0x1840000610021088, 0x440801002428400),
 +      B(0x448814040010, 0x8410085020500600)
 +  };
 +  Bitboard BishopMagicInit[SQUARE_NB] = {
 +      B(0x2001040305000010, 0x830200040400082),
 +      B(0x1042400080E01200, 0x2004904010811400),
 +      B(0x400010120200, 0x880080D080018000),
 +      B(0x240190C00100040, 0x100A020140044404),
 +      B(0x1018010404010004, 0x1001010018081E0),
 +      B(0x41200A804C0904, 0x40000322000008),
 +      B(0x4001180A004, 0x8000001106000000),
 +      B(0x6006020020030600, 0x1840002100004841),
 +      B(0x4200200100, 0x4001041808002000),
 +      B(0x4100020050124600, 0x1001802902400CA0),
 +      B(0x448C0081440161, 0x200206010008000),
 +      B(0x400008008008408, 0x1000080210100080),
 +      B(0x200280C01008200, 0x210200813000080),
 +      B(0x1A000204400, 0x222200401023000),
 +      B(0x10081040640A00, 0x8410021881400000),
 +      B(0x1840400318080008, 0x800800840080000),
 +      B(0x4204050C040, 0x6500600200140000),
 +      B(0x1012100040204, 0x402404444400000),
 +      B(0x6000012680008240, 0x410140000004220),
 +      B(0x1000020810040008, 0x2D0011000060000),
 +      B(0x1020020400, 0x400108059001001),
 +      B(0x400020001100808, 0x480204800200000B),
 +      B(0x10000010030084, 0x2042000848900022),
 +      B(0x10000010030084, 0x2042000848900022),
 +      B(0x100D801402400, 0x1512404009000400),
 +      B(0x8000208005112400, 0xA02040401000000),
 +      B(0x1000420002800200, 0x4CA000183020000),
 +      B(0x800811480020, 0x408801010224001),
 +      B(0xC805200810900100, 0x9000084204004020),
 +      B(0x8200160204100004, 0x8040004004002022),
 +      B(0x104514013080080, 0x146410040001000),
 +      B(0x140844000080002, 0x1008102020040001),
 +      B(0x4040400041A2002, 0x8040000A8802510),
 +      B(0x801014041008002, 0x80068008025200),
 +      B(0xA00540A414040, 0x4101040010A0000),
 +      B(0x6484008010810002, 0x1100506884024000),
 +      B(0x2800401008006000, 0x1005420884029020),
 +      B(0x6822091010004421, 0x2000458080480),
 +      B(0x40101000200101, 0x10020100001C4E0),
 +      B(0x100400008C42, 0x4000100009008000),
 +      B(0x851220018800400, 0x1681800040080080),
 +      B(0x64200002010, 0x900020200040002),
 +      B(0x20800080000022, 0x80040810002010),
 +      B(0xA88408000802080, 0x20808001000000),
 +      B(0x200000400C005040, 0x100140020290108),
 +      B(0x224100000800408, 0x4204802004400020),
 +      B(0x80080620010210, 0x91080088804040),
 +      B(0x4008002100010, 0x80AC201001000001),
 +      B(0x10008200902C046, 0x8080D03004000010),
 +      B(0x3002100081000180, 0x2210002121528408),
 +      B(0x8C101800804420, 0x1019880200043008),
 +      B(0x200022000920D0, 0x8000800081300020),
 +      B(0x1D40800880000, 0x400040001400050),
 +      B(0x2020004100040, 0x200008040008008),
 +      B(0x4840800040100001, 0x100100040203040),
 +      B(0x40084001105, 0x8800080088000089),
 +      B(0x4000128008020008, 0x4004200200440020),
 +      B(0x210040008520000, 0x820219001080022),
 +      B(0x1494040018002116, 0x400101047020008),
 +      B(0x510008001910C224, 0x80200148118000),
 +      B(0xC0301002301000, 0x4211A08004801),
 +      B(0x50008E0C01001080, 0x100C004102845100),
 +      B(0x400600020060400, 0x88024100250050),
 +      B(0x8202920002002040, 0x810012000003),
 +      B(0x800004208800200, 0x18AA00201000048),
 +      B(0x402100800100002, 0x411000081000400),
 +      B(0x101000022004044, 0x9000100040000),
 +      B(0x41068001001, 0xC00400010001),
 +      B(0x310210001040, 0x1A1200020010000),
 +      B(0xA082409200004048, 0x490040800124101),
 +      B(0x18844820E0040212, 0x1000404420D10000),
 +      B(0x802908A40003348, 0x20200040104140),
 +      B(0x1800404028205003, 0xC020010401089020),
 +      B(0x802100044D01000, 0x8C41888000800040),
 +      B(0x1D0161011410081, 0x10008000100200),
 +      B(0x401000480040100, 0x286800404002212),
 +      B(0x821030000100009, 0x2000090200A00000),
 +      B(0x200020800200800, 0x2000480900841012),
 +      B(0x80A000048030080, 0x200000120200008),
 +      B(0x40B1400008020020, 0x148000200008004),
 +      B(0xA021700002002010, 0x3040E400040100),
 +      B(0x400242C200200640, 0x20440210200281),
 +      B(0x80AC140040206240, 0x120000102801401),
 +      B(0x2020340040832040, 0x10402100A44000),
 +      B(0x420100400040220, 0x80014C8004000106),
 +      B(0x504300822421120, 0x8004004008400100),
 +      B(0x2001100008040, 0x2020104302000000),
 +      B(0xA500802000A, 0x2008008000114100),
 +      B(0x8A0020000200, 0x9C00101001002408),
 +      B(0x104000001001008, 0x9001000204040060),
 +      B(0x1000820080108200, 0xA401000008100001),
 +      B(0x2008600009000480, 0x9008020001400000),
 +      B(0x4000800200040200, 0xA00030400308082),
 +      B(0x4004300202004709, 0x1000100180010020),
 +      B(0xC014800100440010, 0x402020280002C010),
 +      B(0x220208010884680, 0x1040280000042110),
 +      B(0x40B0018019202801, 0x1008408000100040),
 +      B(0x8269010206080044, 0x8001810000000040),
 +      B(0x4000020880081040, 0x208A44000028000),
 +      B(0x4004004E9004220A, 0x2104004001400024),
 +      B(0x8035006008C0904, 0x402002001080120),
 +      B(0x1800884002, 0x404400820000000),
 +      B(0x8088000004008910, 0x8024100401000000),
 +      B(0x142200086000100, 0x28021040020002E),
 +      B(0x1000409141004018, 0x100410820080040A),
 +      B(0x1800801800140, 0x810801060C0801),
 +      B(0x1000C00100402220, 0x808023420000000),
 +      B(0x8A0A202414305008, 0x100040200000021),
 +      B(0xC0208024050, 0x8003088008020401),
 +      B(0x8044004201440101, 0x400820080C024022),
 +      B(0x406018884120099, 0xB00088018002000),
 +      B(0x2000800010403010, 0xC5A002002010010),
 +      B(0x800020040840, 0x201800202800200),
 +      B(0x201280120020008D, 0x258809001000040),
 +      B(0x9100002020181, 0x80400082204000),
 +      B(0x104010080201001, 0x40080080181080),
 +      B(0x8440248092000430, 0xA200804900100000),
 +      B(0x2031010C01000C20, 0x200310A560082008),
 +      B(0x400202081811400, 0x40081802050000C),
 +      B(0x1011002100821300, 0x2400825040804100)
 +  };
 +#undef B
 +#endif
 +
 +#ifdef PRECOMPUTED_MAGICS
 +  void init_magics(Bitboard table[], Magic magics[], Direction directions[], Bitboard magicsInit[]);
 +#else
    void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
 +#endif
  
    // popcount16() counts the non-zero bits using SWAR-Popcount algorithm
    unsigned popcount16(unsigned u) {
      u -= (u >> 1) & 0x5555U;
      u = ((u >> 2) & 0x3333U) + (u & 0x3333U);
@@@ -361,270 -85,54 +366,264 @@@ const std::string Bitboards::pretty(Bit
  void Bitboards::init() {
  
    for (unsigned i = 0; i < (1 << 16); ++i)
-       PopCnt16[i] = (uint8_t) popcount16(i);
+       PopCnt16[i] = (uint8_t)popcount16(i);
  
 -  for (Square s = SQ_A1; s <= SQ_H8; ++s)
 -      SquareBB[s] = (1ULL << s);
 +  for (Square s = SQ_A1; s <= SQ_MAX; ++s)
 +      SquareBB[s] = make_bitboard(s);
 +
-   for (Rank r = RANK_1; r < RANK_MAX; ++r)
-       ForwardRanksBB[WHITE][r] = ~(ForwardRanksBB[BLACK][r + 1] = ForwardRanksBB[BLACK][r] | rank_bb(r));
 +  for (File f = FILE_A; f <= FILE_MAX; ++f)
 +      for (Rank r = RANK_1; r <= RANK_MAX; ++r)
 +          BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : 0);
  
 -  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
 -      for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
 +  for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
 +      for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
-           if (s1 != s2)
            {
                SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
                DistanceRingBB[s1][SquareDistance[s1][s2]] |= s2;
            }
  
 -  int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } };
 +  // Piece moves
 +  Direction RookDirections[5] = { NORTH,  EAST,  SOUTH,  WEST };
 +  Direction BishopDirections[5] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
 +
 +#ifdef PRECOMPUTED_MAGICS
 +  init_magics(RookTable, RookMagics, RookDirections, RookMagicInit);
 +  init_magics(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
 +#else
 +  init_magics(RookTable, RookMagics, RookDirections);
 +  init_magics(BishopTable, BishopMagics, BishopDirections);
 +#endif
 +
 +  int stepsCapture[][13] = {
 +      {}, // NO_PIECE_TYPE
 +      { NORTH_WEST, NORTH_EAST }, // pawn
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
 +      {}, // bishop
 +      {}, // rook
 +      {}, // queen
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
 +      { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
 +      {}, // knibis
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // biskni
 +      { NORTH }, // shogi pawn
 +      {}, // lance
 +      {  2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
 +      { WEST, EAST,  2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
 +      { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
 +      { SOUTH, WEST, EAST, NORTH }, // horse
 +      { SOUTH, WEST, EAST, NORTH }, // clobber
 +      { NORTH_WEST, NORTH_EAST }, // breakthrough
 +      {}, // immobile
 +      { SOUTH, WEST, EAST, NORTH }, // wazir
 +      { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
 +      { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
 +  };
 +  int stepsQuiet[][13] = {
 +      {}, // NO_PIECE_TYPE
 +      { NORTH }, // pawn
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
 +      {}, // bishop
 +      {}, // rook
 +      {}, // queen
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
 +      { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
 +      { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
 +      { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
 +        NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knibis
 +      {}, // biskni
 +      { NORTH }, // shogi pawn
 +      {}, // lance
 +      {  2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
 +      { WEST, EAST,  2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
 +      { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
 +      { SOUTH, WEST, EAST, NORTH }, // horse
 +      {}, // clobber
 +      { NORTH_WEST, NORTH, NORTH_EAST }, // breakthrough
 +      {}, // immobile
 +      { SOUTH, WEST, EAST, NORTH }, // wazir
 +      { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
 +      { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
 +  };
 +  Direction sliderCapture[][9] = {
 +    {}, // NO_PIECE_TYPE
 +    {}, // pawn
 +    {}, // knight
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
 +    { NORTH,  EAST,  SOUTH,  WEST }, // rook
 +    { NORTH,  EAST,  SOUTH,  WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
 +    {}, // fers/met
 +    {}, // alfil
 +    {}, // silver/khon
 +    { NORTH,  EAST,  SOUTH,  WEST }, // aiwok
 +    { NORTH,  EAST,  SOUTH,  WEST }, // bers/dragon
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
 +    { NORTH,  EAST,  SOUTH,  WEST }, // chancellor
 +    { NORTH,  EAST,  SOUTH,  WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // knibis
 +    {}, // biskni
 +    {}, // shogi pawn
 +    { NORTH }, // lance
 +    {}, // shogi knight
 +    {}, // euroshogi knight
 +    {}, // gold
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
 +    {}, // clobber
 +    {}, // breakthrough
 +    {}, // immobile
 +    {}, // wazir
 +    {}, // commoner
 +    {} // king
 +  };
 +  Direction sliderQuiet[][9] = {
 +    {}, // NO_PIECE_TYPE
 +    {}, // pawn
 +    {}, // knight
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
 +    { NORTH,  EAST,  SOUTH,  WEST }, // rook
 +    { NORTH,  EAST,  SOUTH,  WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
 +    {}, // fers/met
 +    {}, // alfil
 +    {}, // silver/khon
 +    { NORTH,  EAST,  SOUTH,  WEST }, // aiwok
 +    { NORTH,  EAST,  SOUTH,  WEST }, // bers/dragon
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
 +    { NORTH,  EAST,  SOUTH,  WEST }, // chancellor
 +    { NORTH,  EAST,  SOUTH,  WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
 +    {}, // knibis
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // biskni
 +    {}, // shogi pawn
 +    { NORTH }, // lance
 +    {}, // shogi knight
 +    {}, // euroshogi knight
 +    {}, // gold
 +    { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
 +    {}, // clobber
 +    {}, // breakthrough
 +    {}, // immobile
 +    {}, // wazir
 +    {}, // commoner
 +    {} // king
 +  };
 +  int sliderDistCapture[] = {
 +    0, // NO_PIECE_TYPE
 +    0, // pawn
 +    0, // knight
 +    FILE_MAX, // bishop
 +    FILE_MAX, // rook
 +    FILE_MAX, // queen
 +    0, // fers/met
 +    0, // alfil
 +    0, // silver/khon
 +    FILE_MAX, // aiwok
 +    FILE_MAX, // bers/dragon
 +    FILE_MAX, // archbishop
 +    FILE_MAX, // chancellor
 +    FILE_MAX, // amazon
 +    FILE_MAX, // knibis
 +    0, // biskni
 +    0, // shogi pawn
 +    FILE_MAX, // lance
 +    0, // shogi knight
 +    0, // euroshogi knight
 +    0, // gold
 +    FILE_MAX, // horse
 +    0, // clobber
 +    0, // breakthrough
 +    0, // immobile
 +    0, // wazir
 +    0, // commoner
 +    0  // king
 +  };
 +  int sliderDistQuiet[] = {
 +    0, // NO_PIECE_TYPE
 +    0, // pawn
 +    0, // knight
 +    FILE_MAX, // bishop
 +    FILE_MAX, // rook
 +    FILE_MAX, // queen
 +    0, // fers/met
 +    0, // alfil
 +    0, // silver/khon
 +    FILE_MAX, // aiwok
 +    FILE_MAX, // bers/dragon
 +    FILE_MAX, // archbishop
 +    FILE_MAX, // chancellor
 +    FILE_MAX, // amazon
 +    0, // knibis
 +    FILE_MAX, // biskni
 +    0, // shogi pawn
 +    FILE_MAX, // lance
 +    0, // shogi knight
 +    0, // euroshogi knight
 +    0, // gold
 +    FILE_MAX, // horse
 +    0, // clobber
 +    0, // breakthrough
 +    0, // immobile
 +    0, // wazir
 +    0, // commoner
 +    0  // king
 +  };
  
    for (Color c = WHITE; c <= BLACK; ++c)
 -      for (PieceType pt : { PAWN, KNIGHT, KING })
 -          for (Square s = SQ_A1; s <= SQ_H8; ++s)
 -              for (int i = 0; steps[pt][i]; ++i)
 +      for (PieceType pt = PAWN; pt <= KING; ++pt)
 +          for (Square s = SQ_A1; s <= SQ_MAX; ++s)
 +          {
 +              for (int i = 0; stepsCapture[pt][i]; ++i)
                {
 -                  Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]);
 +                  Square to = s + Direction(c == WHITE ? stepsCapture[pt][i] : -stepsCapture[pt][i]);
  
 -                  if (is_ok(to) && distance(s, to) < 3)
 +                  if (is_ok(to) && distance(s, to) < 4)
                    {
 -                      if (pt == PAWN)
 -                          PawnAttacks[c][s] |= to;
 -                      else
 -                          PseudoAttacks[pt][s] |= to;
 +                      PseudoAttacks[c][pt][s] |= to;
 +                      LeaperAttacks[c][pt][s] |= to;
                    }
                }
 +              for (int i = 0; stepsQuiet[pt][i]; ++i)
 +              {
 +                  Square to = s + Direction(c == WHITE ? stepsQuiet[pt][i] : -stepsQuiet[pt][i]);
  
 -  Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
 -  Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
 -
 -  init_magics(RookTable, RookMagics, RookDirections);
 -  init_magics(BishopTable, BishopMagics, BishopDirections);
 +                  if (is_ok(to) && distance(s, to) < 4)
 +                  {
 +                      PseudoMoves[c][pt][s] |= to;
 +                      LeaperMoves[c][pt][s] |= to;
 +                  }
 +              }
 +              PseudoAttacks[c][pt][s] |= sliding_attack(sliderCapture[pt], s, 0, sliderDistCapture[pt], c);
 +              PseudoMoves[c][pt][s] |= sliding_attack(sliderQuiet[pt], s, 0, sliderDistQuiet[pt], c);
 +          }
  
 -  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
 +  for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
    {
 -      PseudoAttacks[QUEEN][s1]  = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
 -      PseudoAttacks[QUEEN][s1] |= PseudoAttacks[  ROOK][s1] = attacks_bb<  ROOK>(s1, 0);
 -
        for (PieceType pt : { BISHOP, ROOK })
 -          for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
 -              if (PseudoAttacks[pt][s1] & s2)
 +          for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
-           {
-               if (!(PseudoAttacks[WHITE][pt][s1] & s2))
-                   continue;
-               LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
-               BetweenBB[s1][s2] = attacks_bb(WHITE, pt, s1, SquareBB[s2]) & attacks_bb(WHITE, pt, s2, SquareBB[s1]);
-           }
++              if (PseudoAttacks[WHITE][pt][s1] & s2)
+               {
 -                  LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
 -                  BetweenBB[s1][s2] = attacks_bb(pt, s1, SquareBB[s2]) & attacks_bb(pt, s2, SquareBB[s1]);
++                  LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
++                  BetweenBB[s1][s2] = attacks_bb(WHITE, pt, s1, SquareBB[s2]) & attacks_bb(WHITE, pt, s2, SquareBB[s1]);
+               }
    }
  }
  
diff --cc src/bitboard.h
@@@ -62,47 -50,32 +62,53 @@@ constexpr Bitboard FileEBB = FileABB <
  constexpr Bitboard FileFBB = FileABB << 5;
  constexpr Bitboard FileGBB = FileABB << 6;
  constexpr Bitboard FileHBB = FileABB << 7;
 +#ifdef LARGEBOARDS
 +constexpr Bitboard FileIBB = FileABB << 8;
 +constexpr Bitboard FileJBB = FileABB << 9;
 +constexpr Bitboard FileKBB = FileABB << 10;
 +constexpr Bitboard FileLBB = FileABB << 11;
 +#endif
 +
  
 +#ifdef LARGEBOARDS
 +constexpr Bitboard Rank1BB = 0xFFF;
 +#else
  constexpr Bitboard Rank1BB = 0xFF;
 -constexpr Bitboard Rank2BB = Rank1BB << (8 * 1);
 -constexpr Bitboard Rank3BB = Rank1BB << (8 * 2);
 -constexpr Bitboard Rank4BB = Rank1BB << (8 * 3);
 -constexpr Bitboard Rank5BB = Rank1BB << (8 * 4);
 -constexpr Bitboard Rank6BB = Rank1BB << (8 * 5);
 -constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
 -constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
 +#endif
 +constexpr Bitboard Rank2BB = Rank1BB << (FILE_NB * 1);
 +constexpr Bitboard Rank3BB = Rank1BB << (FILE_NB * 2);
 +constexpr Bitboard Rank4BB = Rank1BB << (FILE_NB * 3);
 +constexpr Bitboard Rank5BB = Rank1BB << (FILE_NB * 4);
 +constexpr Bitboard Rank6BB = Rank1BB << (FILE_NB * 5);
 +constexpr Bitboard Rank7BB = Rank1BB << (FILE_NB * 6);
 +constexpr Bitboard Rank8BB = Rank1BB << (FILE_NB * 7);
 +#ifdef LARGEBOARDS
 +constexpr Bitboard Rank9BB = Rank1BB << (FILE_NB * 8);
 +constexpr Bitboard Rank10BB = Rank1BB << (FILE_NB * 9);
 +#endif
  
- extern int8_t SquareDistance[SQUARE_NB][SQUARE_NB];
+ constexpr Bitboard QueenSide   = FileABB | FileBBB | FileCBB | FileDBB;
+ constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
+ constexpr Bitboard KingSide    = FileEBB | FileFBB | FileGBB | FileHBB;
+ constexpr Bitboard Center      = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
+ extern uint8_t PopCnt16[1 << 16];
+ extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
  
 +extern Bitboard BoardSizeBB[FILE_NB][RANK_NB];
  extern Bitboard SquareBB[SQUARE_NB];
- extern Bitboard ForwardRanksBB[COLOR_NB][RANK_NB];
  extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
  extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
 -extern Bitboard DistanceRingBB[SQUARE_NB][8];
 -extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
 -extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
 +extern Bitboard DistanceRingBB[SQUARE_NB][FILE_NB];
 +extern Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +extern Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +extern Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
 +extern Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+ extern Bitboard KingFlank[FILE_NB];
  
 +#ifdef LARGEBOARDS
 +int popcount(Bitboard b); // required for 128 bit pext
 +#endif
  
  /// Magic holds all magic bitboards relevant data for a single square
  struct Magic {
@@@ -277,21 -214,9 +285,23 @@@ inline Bitboard between_bb(Square s1, S
  /// in front of the given one, from the point of view of the given color. For instance,
  /// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2.
  
- inline Bitboard forward_ranks_bb(Color c, Rank r) {
-   return ForwardRanksBB[c][r];
+ inline Bitboard forward_ranks_bb(Color c, Square s) {
 -  return c == WHITE ? ~Rank1BB << 8 * (rank_of(s) - RANK_1)
 -                    : ~Rank8BB >> 8 * (RANK_8 - rank_of(s));
++  return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * (rank_of(s) - RANK_1)
++                    : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * (RANK_MAX - rank_of(s));
 +}
 +
- inline Bitboard forward_ranks_bb(Color c, Square s) {
-   return ForwardRanksBB[c][rank_of(s)];
++inline Bitboard forward_ranks_bb(Color c, Rank r) {
++  return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * (r - RANK_1)
++                    : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * (RANK_MAX - r);
 +}
 +
 +
 +/// promotion_zone_bb() returns a bitboard representing the squares on all the ranks
 +/// in front of and on the given relative rank, from the point of view of the given color.
 +/// For instance, promotion_zone_bb(BLACK, RANK_7) will return the 16 squares on ranks 1 and 2.
 +
 +inline Bitboard promotion_zone_bb(Color c, Rank r, Rank maxRank) {
-   return ForwardRanksBB[c][relative_rank(c, r, maxRank)] | rank_bb(relative_rank(c, r, maxRank));
++  return forward_ranks_bb(c, relative_rank(c, r, maxRank)) | rank_bb(relative_rank(c, r, maxRank));
  }
  
  
@@@ -366,15 -294,8 +375,14 @@@ inline int popcount(Bitboard b) 
  
  #ifndef USE_POPCNT
  
-   extern uint8_t PopCnt16[1 << 16];
 +#ifdef LARGEBOARDS
 +  union { Bitboard bb; uint16_t u[8]; } v = { b };
 +  return  PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]]
 +        + PopCnt16[v.u[4]] + PopCnt16[v.u[5]] + PopCnt16[v.u[6]] + PopCnt16[v.u[7]];
 +#else
    union { Bitboard bb; uint16_t u[4]; } v = { b };
    return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]];
 +#endif
  
  #elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
  
@@@ -73,18 -73,8 +73,7 @@@ using namespace Trace
  
  namespace {
  
-   constexpr Bitboard QueenSide   = FileABB | FileBBB | FileCBB | FileDBB;
-   constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
-   constexpr Bitboard KingSide    = FileEBB | FileFBB | FileGBB | FileHBB;
-   constexpr Bitboard Center      = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
-   constexpr Bitboard KingFlank[FILE_NB] = {
-     QueenSide ^ FileDBB, QueenSide, QueenSide,
-     CenterFiles, CenterFiles,
-     KingSide, KingSide, KingSide ^ FileEBB
-   };
 -  // Threshold for lazy and space evaluation
 -  constexpr Value LazyThreshold  = Value(1500);
 +  // Threshold for space evaluation
    constexpr Value SpaceThreshold = Value(12222);
  
    // KingAttackWeights[PieceType] contains king attack weights by piece type
    Score Evaluation<T>::king() const {
  
      constexpr Color    Them = (Us == WHITE ? BLACK : WHITE);
 -    constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
 -                                           : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
 +    Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
 +    Bitboard Camp = AllSquares ^ forward_ranks_bb(Us, r);
 +
 +    if (!pos.count<KING>(Us) || !pos.checking_permitted())
 +        return SCORE_ZERO;
  
-     Bitboard weak, b, b1, b2, safe, QueenCheck, unsafeChecks = 0;
+     Bitboard weak, b1, b2, safe, unsafeChecks = 0;
 -    Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
++    Bitboard queenChecks, knightChecks, pawnChecks, otherChecks;
      int kingDanger = 0;
      const Square ksq = pos.square<KING>(Us);
  
      b1 = attacks_bb<ROOK  >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
      b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
  
 -    // Enemy rooks checks
 -    rookChecks = b1 & safe & attackedBy[Them][ROOK];
 -
 -    if (rookChecks)
 -        kingDanger += RookSafeCheck;
 -    else
 -        unsafeChecks |= b1 & attackedBy[Them][ROOK];
 -
 -    // Enemy queen safe checks: we count them only if they are from squares from
 -    // which we can't give a rook check, because rook checks are more valuable.
 -    queenChecks =  (b1 | b2)
 -                 & attackedBy[Them][QUEEN]
 -                 & safe
 -                 & ~attackedBy[Us][QUEEN]
 -                 & ~rookChecks;
 -
 -    if (queenChecks)
 -        kingDanger += QueenSafeCheck;
 -
 -    // Enemy bishops checks: we count them only if they are from squares from
 -    // which we can't give a queen check, because queen checks are more valuable.
 -    bishopChecks =  b2
 -                  & attackedBy[Them][BISHOP]
 -                  & safe
 -                  & ~queenChecks;
 -
 -    if (bishopChecks)
 -        kingDanger += BishopSafeCheck;
 -    else
 -        unsafeChecks |= b2 & attackedBy[Them][BISHOP];
 -
 -    // Enemy knights checks
 -    knightChecks = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
 +    std::function <Bitboard (Color, PieceType)> get_attacks = [this](Color c, PieceType pt) {
 +        return attackedBy[c][pt] | (pos.captures_to_hand() && pos.count_in_hand(c, pt) ? ~pos.pieces() : 0);
 +    };
 +    for (PieceType pt : pos.piece_types())
 +    {
 +        switch (pt)
 +        {
 +        case QUEEN:
 +            // Enemy queen safe checks: we count them only if they are from squares from
 +            // which we can't give a rook check, because rook checks are more valuable.
-             QueenCheck = (b1 | b2)
++            queenChecks = (b1 | b2)
 +                        & get_attacks(Them, QUEEN)
 +                        & safe
 +                        & ~attackedBy[Us][QUEEN]
 +                        & ~(b1 & attackedBy[Them][ROOK]);
 +
-             if (QueenCheck)
++            if (queenChecks)
 +                kingDanger += QueenSafeCheck;
 +            break;
 +        case ROOK:
 +        case BISHOP:
 +        case KNIGHT:
-             b = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & pos.board_bb();
-             if (b & safe)
++            knightChecks = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & pos.board_bb();
++            if (knightChecks & safe)
 +                kingDanger +=  pt == ROOK   ? RookSafeCheck
 +                             : pt == BISHOP ? BishopSafeCheck
 +                                            : KnightSafeCheck;
 +            else
-                 unsafeChecks |= b;
++                unsafeChecks |= knightChecks;
 +            break;
 +        case PAWN:
 +            if (pos.captures_to_hand() && pos.count_in_hand(Them, pt))
 +            {
-                 b = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb();
-                 if (b & safe)
++                pawnChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb();
++                if (pawnChecks & safe)
 +                    kingDanger += OtherSafeCheck;
 +                else
-                     unsafeChecks |= b;
++                    unsafeChecks |= pawnChecks;
 +            }
 +            break;
 +        case SHOGI_PAWN:
 +        case KING:
 +            break;
 +        default:
-             b = attacks_bb(Us, pt, ksq, pos.pieces()) & get_attacks(Them, pt) & pos.board_bb();
-             if (b & safe)
++            otherChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & get_attacks(Them, pt) & pos.board_bb();
++            if (otherChecks & safe)
 +                kingDanger += OtherSafeCheck;
 +            else
-                 unsafeChecks |= b;
++                unsafeChecks |= otherChecks;
 +        }
 +    }
  
 -    if (knightChecks & safe)
 -        kingDanger += KnightSafeCheck;
 -    else
 -        unsafeChecks |= knightChecks;
 +    if (pos.max_check_count())
 +        kingDanger *= 2;
  
      // Unsafe or occupied checking squares will also be considered, as long as
      // the square is in the attacker's mobility area.
      constexpr Direction Up       = (Us == WHITE ? NORTH   : SOUTH);
      constexpr Bitboard  TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
  
-     Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe, restricted;
+     Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
      Score score = SCORE_ZERO;
  
 +    // Bonuses for variants with mandatory captures
 +    if (pos.must_capture())
 +    {
 +        // Penalties for possible captures
 +        score -= make_score(100, 100) * popcount(attackedBy[Us][ALL_PIECES] & pos.pieces(Them));
 +
 +        // Bonus if we threaten to force captures
 +        Bitboard moves = 0, piecebb = pos.pieces(Us);
 +        while (piecebb)
 +        {
 +            Square s = pop_lsb(&piecebb);
 +            if (type_of(pos.piece_on(s)) != KING)
 +                moves |= pos.moves_from(Us, type_of(pos.piece_on(s)), s);
 +        }
 +        score += make_score(200, 200) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces());
 +        score += make_score(200, 200) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces() & ~attackedBy2[Us]);
 +    }
 +
      // Non-pawn enemies
 -    nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
 +    nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN, SHOGI_PAWN);
  
      // Squares strongly protected by the enemy, either because they defend the
      // square with a pawn, or because they defend the square twice and we don't.
@@@ -1151,7 -900,7 +1141,8 @@@ std::string Eval::trace(const Position
       << "     Threats | " << Term(THREAT)
       << "      Passed | " << Term(PASSED)
       << "       Space | " << Term(SPACE)
+      << "  Initiative | " << Term(INITIATIVE)
 +     << "     Variant | " << Term(VARIANT)
       << " ------------+-------------+-------------+------------\n"
       << "       Total | " << Term(TOTAL);
  
diff --cc src/movegen.cpp
Simple merge
diff --cc src/pawns.cpp
@@@ -96,13 -96,13 +96,13 @@@ namespace 
  
          // Flag the pawn
          opposed    = theirPawns & forward_file_bb(Us, s);
-         stoppers   = theirPawns & passed_pawn_mask(Us, s);
+         stoppers   = theirPawns & passed_pawn_span(Us, s);
 -        lever      = theirPawns & PawnAttacks[Us][s];
 -        leverPush  = theirPawns & PawnAttacks[Us][s + Up];
 -        doubled    = ourPawns   & (s - Up);
 +        lever      = theirPawns & PseudoAttacks[Us][PAWN][s];
 +        leverPush  = relative_rank(Them, s, pos.max_rank()) > RANK_1 ? theirPawns & PseudoAttacks[Us][PAWN][s + Up] : 0;
 +        doubled    = relative_rank(Us, s, pos.max_rank()) > RANK_1 ? ourPawns & (s - Up) : 0;
          neighbours = ourPawns   & adjacent_files_bb(f);
          phalanx    = neighbours & rank_bb(s);
 -        support    = neighbours & rank_bb(s - Up);
 +        support    = relative_rank(Us, s, pos.max_rank()) > RANK_1 ? neighbours & rank_bb(s - Up) : 0;
  
          // A pawn is backward when it is behind all pawns of the same color
          // on the adjacent files and cannot be safely advanced.
diff --cc src/position.h
Simple merge
diff --cc src/search.cpp
Simple merge
Simple merge
@@@ -20,7 -20,8 +20,9 @@@
  
  #include <algorithm>
  #include <cassert>
+ #include <ostream>
+ #include <sstream>
 +#include <iostream>
  
  #include "misc.h"
  #include "search.h"
@@@ -188,6 -166,17 +190,15 @@@ Option& Option::operator=(const string
        || (type == "spin" && (stof(v) < min || stof(v) > max)))
        return *this;
  
+   if (type == "combo")
+   {
+       OptionsMap comboMap; // To have case insensitive compare
 -      string token;
 -      std::istringstream ss(defaultValue);
 -      while (ss >> token)
++      for (string token : comboValues)
+           comboMap[token] << Option();
+       if (!comboMap.count(v) || v == "var")
+           return *this;
+   }
    if (type != "button")
        currentValue = v;