Subversion Repositories Games.Chess Giants

Rev

Rev 102 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. /*
  3.     Senpai 1.0 Copyright (C) 2014 Fabien Letouzey.
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. // macros
  20.  
  21. #ifndef DEBUG
  22. # ifndef NDEBUG // Pierre-Marie Baty -- protect macro redefinition
  23. #  define NDEBUG
  24. # endif // Pierre-Marie Baty -- protect macro redefinition
  25. #endif
  26.  
  27. // C includes
  28.  
  29. #include <cassert> // needs NDEBUG
  30. #include <cctype>
  31. #include <cmath>
  32. #include <cstdlib>
  33. #include <ctime>
  34. #ifdef _MSC_VER
  35. #include <algorithm> // Pierre-Marie Baty -- for std::min and std::max
  36. #include <windows.h> // Pierre-Marie Baty -- for ExitProcess()
  37. #undef max // Pierre-Marie Baty -- for std::min and std::max
  38. #undef min // Pierre-Marie Baty -- for std::min and std::max
  39. #endif // _MSC_VER
  40.  
  41. // C++ includes
  42.  
  43. #include <fstream>
  44. #include <iostream>
  45. #include <sstream>
  46. #include <string>
  47. #include <vector>
  48.  
  49. // C++11 includes
  50.  
  51. #include <chrono>
  52. #include <condition_variable>
  53. #include <mutex>
  54. #include <thread>
  55.  
  56. // macros
  57.  
  58. #ifdef _MSC_VER
  59. #  define I64(n) (n##i64)
  60. #  define U64(u) (u##ui64)
  61. #else
  62. #  define I64(n) (n##LL)
  63. #  define U64(u) (u##ULL)
  64. #endif
  65.  
  66. #ifndef __builtin_popcountll // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
  67. int __builtin_popcountll (unsigned long long x) {
  68.    static const unsigned long long m1 = 0x5555555555555555; //binary: 0101...
  69.    static const unsigned long long m2 = 0x3333333333333333; //binary: 00110011..
  70.    static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
  71.    static const unsigned long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
  72.    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
  73.    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
  74.    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits
  75.    return static_cast<int>((x * h01) >> 56);  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
  76. }
  77. #endif // Pierre-Marie Baty -- __builtin_popcountll support for MSVC 32-bit
  78.  
  79. #ifndef __builtin_ctzll // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
  80. #include <intrin.h>
  81. int __builtin_ctzll (unsigned long long x)
  82. {
  83.    // Returns the number of trailing 0-bits in x, starting at the least significant bit position.
  84.    // If x is zero, the result is undefined.
  85.    // This uses a binary search algorithm from Hacker's Delight.
  86.    int n = 1;
  87.    if ((x & 0x00000000FFFFFFFF) == 0) { n = n + 32; x = x >> 32; }
  88.    if ((x & 0x000000000000FFFF) == 0) { n = n + 16; x = x >> 16; }
  89.    if ((x & 0x00000000000000FF) == 0) { n = n +  8; x = x >>  8; }
  90.    if ((x & 0x000000000000000F) == 0) { n = n +  4; x = x >>  4; }
  91.    if ((x & 0x0000000000000003) == 0) { n = n +  2; x = x >>  2; }
  92.    return (n - (x & 1));
  93. }
  94. #endif // Pierre-Marie Baty -- __builtin_ctzll support for MSVC 32-bit
  95.  
  96. // types
  97.  
  98. typedef signed   char int8;
  99. typedef unsigned char uint8;
  100.  
  101. typedef signed   short int int16;
  102. typedef unsigned short int uint16;
  103.  
  104. typedef signed   int int32;
  105. typedef unsigned int uint32;
  106.  
  107. typedef signed   long long int int64;
  108. typedef unsigned long long int uint64;
  109.  
  110. typedef uint64 bit_t;
  111. typedef uint64 hash_t; // key_t is used by Unix :(
  112.  
  113. // modules
  114.  
  115. namespace util {
  116.  
  117. class Timer {
  118.  
  119. private:
  120.  
  121.    typedef std::chrono::time_point<std::chrono::system_clock> time_t;
  122.    typedef std::chrono::duration<int, std::ratio<1, 1000>> millisecond_t;
  123.  
  124.    int p_elapsed;
  125.    bool p_running;
  126.    time_t p_start;
  127.  
  128.    static time_t now() {
  129.       return std::chrono::system_clock::now();
  130.    }
  131.  
  132.    int time() const {
  133.       assert(p_running);
  134.       return std::chrono::duration_cast<millisecond_t>(now() - p_start).count();
  135.    }
  136.  
  137. public:
  138.  
  139.    Timer() {
  140.       reset();
  141.    }
  142.  
  143.    void reset() {
  144.       p_elapsed = 0;
  145.       p_running = false;
  146.    }
  147.  
  148.    void start() {
  149.       p_start = now();
  150.       p_running = true;
  151.    }
  152.  
  153.    void stop() {
  154.       p_elapsed += time();
  155.       p_running = false;
  156.    }
  157.  
  158.    int elapsed() const {
  159.       int time = p_elapsed;
  160.       if (p_running) time += this->time();
  161.       return time;
  162.    }
  163.  
  164. };
  165.  
  166. class Lockable {
  167.  
  168. protected: // HACK for Waitable::wait()
  169.  
  170.    mutable std::mutex p_mutex;
  171.  
  172. public:
  173.  
  174.    void lock   () const { p_mutex.lock(); }
  175.    void unlock () const { p_mutex.unlock(); }
  176. };
  177.  
  178. class Waitable : public Lockable {
  179.  
  180. private:
  181.  
  182.    std::condition_variable_any p_cond;
  183.  
  184. public:
  185.  
  186.    void wait   () { p_cond.wait(p_mutex); } // HACK: direct access
  187.    void signal () { p_cond.notify_one(); }
  188. };
  189.  
  190. int round(double x) {
  191.    return int(std::floor(x + 0.5));
  192. }
  193.  
  194. int div(int a, int b) {
  195.  
  196.    assert(b > 0);
  197.  
  198.    int div = a / b;
  199.    if (a < 0 && a != b * div) div--; // fix buggy C semantics
  200.  
  201.    return div;
  202. }
  203.  
  204. int sqrt(int n) {
  205.    return int(std::sqrt(double(n)));
  206. }
  207.  
  208. bool is_square(int n) {
  209.    int i = sqrt(n);
  210.    return i * i == n;
  211. }
  212.  
  213. double rand_float() {
  214.    return double(std::rand()) / (double(RAND_MAX) + 1.0);
  215. }
  216.  
  217. int rand_int(int n) {
  218.    assert(n > 0);
  219.    return int(rand_float() * double(n));
  220. }
  221.  
  222. int string_find(const std::string & s, char c) {
  223.    return int(s.find(c));
  224. }
  225.  
  226. bool string_case_equal(const std::string & s0, const std::string & s1) {
  227.  
  228.    if (s0.size() != s1.size()) return false;
  229.  
  230.    for (int i = 0; i < int(s0.size()); i++) {
  231.       if (std::tolower(s0[i]) != std::tolower(s1[i])) return false;
  232.    }
  233.  
  234.    return true;
  235. }
  236.  
  237. bool to_bool(const std::string & s) {
  238.    if (string_case_equal(s, "true")) {
  239.       return true;
  240.    } else if (string_case_equal(s, "false")) {
  241.       return false;
  242.    } else {
  243.       std::cerr << "not a boolean: \"" << s << "\"" << std::endl;
  244.       std::exit(EXIT_FAILURE);
  245.    }
  246. }
  247.  
  248. int64 to_int(const std::string & s) {
  249.    std::stringstream ss(s);
  250.    int64 n;
  251.    ss >> n;
  252.    return n;
  253. }
  254.  
  255. std::string to_string(int n) {
  256.    std::stringstream ss;
  257.    ss << n;
  258.    return ss.str();
  259. }
  260.  
  261. std::string to_string(double x) {
  262.    std::stringstream ss;
  263.    ss << x;
  264.    return ss.str();
  265. }
  266.  
  267. void log(const std::string & s) {
  268.    std::ofstream log_file("log.txt", std::ios_base::app);
  269.    log_file << s << std::endl;
  270. }
  271.  
  272. }
  273.  
  274. namespace input {
  275.  
  276. class Input : public util::Waitable {
  277.  
  278.    bool volatile p_has_input;
  279.    bool p_eof;
  280.    std::string p_line;
  281.  
  282. public:
  283.  
  284.    Input() {
  285.       p_has_input = false;
  286.       p_eof = false;
  287.    }
  288.  
  289.    bool has_input() const {
  290.       return p_has_input;
  291.    }
  292.  
  293.    bool get_line(std::string & line) {
  294.  
  295.       lock();
  296.  
  297.       while (!p_has_input) {
  298.          wait();
  299.       }
  300.  
  301.       bool line_ok = !p_eof;
  302.       if (line_ok) line = p_line;
  303.  
  304.       p_has_input = false;
  305.       signal();
  306.  
  307.       unlock();
  308.  
  309.       return line_ok;
  310.    }
  311.  
  312.    void set_eof() {
  313.  
  314.       lock();
  315.  
  316.       while (p_has_input) {
  317.          wait();
  318.       }
  319.  
  320.       p_eof = true;
  321.  
  322.       p_has_input = true;
  323.       signal();
  324.  
  325.       unlock();
  326.    }
  327.  
  328.    void set_line(std::string & line) {
  329.  
  330.       lock();
  331.  
  332.       while (p_has_input) {
  333.          wait();
  334.       }
  335.  
  336.       p_line = line;
  337.  
  338.       p_has_input = true;
  339.       signal();
  340.  
  341.       unlock();
  342.    }
  343.  
  344. };
  345.  
  346. Input input;
  347. std::thread thread;
  348.  
  349. void input_program(Input * input) {
  350.  
  351.    std::string line;
  352.  
  353.    while (std::getline(std::cin, line)) {
  354.       input->set_line(line);
  355.    }
  356.  
  357.    input->set_eof();
  358. }
  359.  
  360. void init() {
  361.    thread = std::thread(input_program, &input);
  362.    thread.detach();
  363. }
  364.  
  365. };
  366.  
  367. namespace side {
  368.  
  369. const int SIZE = 2;
  370.  
  371. enum {
  372.    WHITE,
  373.    BLACK,
  374. };
  375.  
  376. int opposit(int sd) {
  377.    return sd ^ 1;
  378. }
  379.  
  380. }
  381.  
  382. namespace square {
  383.  
  384. const int FILE_SIZE = 8;
  385. const int RANK_SIZE = 8;
  386. const int SIZE = FILE_SIZE * RANK_SIZE;
  387.  
  388. enum {
  389.    FILE_A,
  390.    FILE_B,
  391.    FILE_C,
  392.    FILE_D,
  393.    FILE_E,
  394.    FILE_F,
  395.    FILE_G,
  396.    FILE_H,
  397. };
  398.  
  399. enum {
  400.    RANK_1,
  401.    RANK_2,
  402.    RANK_3,
  403.    RANK_4,
  404.    RANK_5,
  405.    RANK_6,
  406.    RANK_7,
  407.    RANK_8,
  408. };
  409.  
  410. enum {
  411.    NONE = -1,
  412.    A1, A2, A3, A4, A5, A6, A7, A8,
  413.    B1, B2, B3, B4, B5, B6, B7, B8,
  414.    C1, C2, C3, C4, C5, C6, C7, C8,
  415.    D1, D2, D3, D4, D5, D6, D7, D8,
  416.    E1, E2, E3, E4, E5, E6, E7, E8,
  417.    F1, F2, F3, F4, F5, F6, F7, F8,
  418.    G1, G2, G3, G4, G5, G6, G7, G8,
  419.    H1, H2, H3, H4, H5, H6, H7, H8,
  420. };
  421.  
  422. enum {
  423.    INC_LEFT  = -8,
  424.    INC_RIGHT = +8,
  425. };
  426.  
  427. const int CASTLING_DELTA = 16;
  428. const int DOUBLE_PAWN_DELTA = 2;
  429.  
  430. int make(int fl, int rk) {
  431.  
  432.    assert(fl < 8);
  433.    assert(rk < 8);
  434.  
  435.    return (fl << 3) | rk;
  436. }
  437.  
  438. int make(int fl, int rk, int sd) {
  439.  
  440.    assert(fl < 8);
  441.    assert(rk < 8);
  442.  
  443.    return make(fl, (rk ^ -sd) & 7);
  444. }
  445.  
  446. int file(int sq) {
  447.    return sq >> 3;
  448. }
  449.  
  450. int rank(int sq) {
  451.    return sq & 7;
  452. }
  453.  
  454. int rank(int sq, int sd) {
  455.    return (sq ^ -sd) & 7;
  456. }
  457.  
  458. int opposit_file(int sq) {
  459.    return sq ^ 070;
  460. }
  461.  
  462. int opposit_rank(int sq) {
  463.    return sq ^ 007;
  464. }
  465.  
  466. bool is_promotion(int sq) {
  467.    int rk = rank(sq);
  468.    return rk == RANK_1 || rk == RANK_8;
  469. }
  470.  
  471. int colour(int sq) {
  472.    return ((sq >> 3) ^ sq) & 1;
  473. }
  474.  
  475. bool same_colour(int s0, int s1) {
  476.    int diff = s0 ^ s1;
  477.    return (((diff >> 3) ^ diff) & 1) == 0;
  478. }
  479.  
  480. bool same_line(int s0, int s1) {
  481.    return file(s0) == file(s1) || rank(s0) == rank(s1);
  482. }
  483.  
  484. int file_distance(int s0, int s1) {
  485.    return std::abs(file(s1) - file(s0));
  486. }
  487.  
  488. int rank_distance(int s0, int s1) {
  489.    return std::abs(rank(s1) - rank(s0));
  490. }
  491.  
  492. int distance(int s0, int s1) {
  493.    return std::max(file_distance(s0, s1), rank_distance(s0, s1));
  494. }
  495.  
  496. int pawn_inc(int sd) {
  497.    return (sd == side::WHITE) ? +1 : -1;
  498. }
  499.  
  500. int stop(int sq, int sd) {
  501.    return sq + pawn_inc(sd);
  502. }
  503.  
  504. int promotion(int sq, int sd) {
  505.    return make(file(sq), RANK_8, sd);
  506. }
  507.  
  508. bool is_valid_88(int s88) {
  509.    return (s88 & ~0x77) == 0;
  510. }
  511.  
  512. int to_88(int sq) {
  513.    return sq + (sq & 070);
  514. }
  515.  
  516. int from_88(int s88) {
  517.    assert(is_valid_88(s88));
  518.    return (s88 + (s88 & 7)) >> 1;
  519. }
  520.  
  521. int from_fen(int sq) {
  522.    return make(sq & 7, (sq >> 3) ^ 7);
  523. }
  524.  
  525. int from_string(const std::string & s) {
  526.    assert(s.length() == 2);
  527.    return make(s[0] - 'a', s[1] - '1');
  528. }
  529.  
  530. std::string to_string(int sq) {
  531.  
  532.    std::string s;
  533.    s += 'a' + file(sq);
  534.    s += '1' + rank(sq);
  535.  
  536.    return s;
  537. }
  538.  
  539. }
  540.  
  541. namespace wing {
  542.  
  543. const int SIZE = 2;
  544.  
  545. enum {
  546.    KING,
  547.    QUEEN,
  548. };
  549.  
  550. const int shelter_file[SIZE] = { square::FILE_G, square::FILE_B }; // for pawn-shelter eval
  551.  
  552. }
  553.  
  554. namespace piece {
  555.  
  556. const int SIZE = 7;
  557. const int SIDE_SIZE = 12;
  558.  
  559. enum Piece {
  560.    PAWN,
  561.    KNIGHT,
  562.    BISHOP,
  563.    ROOK,
  564.    QUEEN,
  565.    KING,
  566.    NONE,
  567. };
  568.  
  569. enum Side_Piece {
  570.    WHITE_PAWN,
  571.    BLACK_PAWN,
  572.    WHITE_KNIGHT,
  573.    BLACK_KNIGHT,
  574.    WHITE_BISHOP,
  575.    BLACK_BISHOP,
  576.    WHITE_ROOK,
  577.    BLACK_ROOK,
  578.    WHITE_QUEEN,
  579.    BLACK_QUEEN,
  580.    WHITE_KING,
  581.    BLACK_KING,
  582. };
  583.  
  584. const int PAWN_VALUE   = 100;
  585. const int KNIGHT_VALUE = 325;
  586. const int BISHOP_VALUE = 325;
  587. const int ROOK_VALUE   = 500;
  588. const int QUEEN_VALUE  = 975;
  589. const int KING_VALUE   = 10000; // for SEE
  590.  
  591. const std::string Char = "PNBRQK?";
  592. const std::string Fen_Char = "PpNnBbRrQqKk";
  593.  
  594. bool is_minor(int pc) {
  595.    assert(pc < SIZE);
  596.    return pc == KNIGHT || pc == BISHOP;
  597. }
  598.  
  599. bool is_major(int pc) {
  600.    assert(pc < SIZE);
  601.    return pc == ROOK || pc == QUEEN;
  602. }
  603.  
  604. bool is_slider(int pc) {
  605.    assert(pc < SIZE);
  606.    return pc >= BISHOP && pc <= QUEEN;
  607. }
  608.  
  609. int score(int pc) { // for MVV/LVA
  610.    assert(pc < SIZE);
  611.    assert(pc != NONE);
  612.    return pc;
  613. }
  614.  
  615. int value(int pc) {
  616.    assert(pc < SIZE);
  617.    static const int value[SIZE] = { PAWN_VALUE, KNIGHT_VALUE, BISHOP_VALUE, ROOK_VALUE, QUEEN_VALUE, KING_VALUE, 0 };
  618.    return value[pc];
  619. }
  620.  
  621. int make(int pc, int sd) {
  622.    assert(pc < SIZE);
  623.    assert(pc != NONE);
  624.    assert(sd < side::SIZE);
  625.    return (pc << 1) | sd;
  626. }
  627.  
  628. int piece(int p12) {
  629.    assert(p12 < SIDE_SIZE);
  630.    return p12 >> 1;
  631. }
  632.  
  633. int side(int p12) {
  634.    assert(p12 < SIDE_SIZE);
  635.    return p12 & 1;
  636. }
  637.  
  638. int from_char(char c) {
  639.    return util::string_find(Char, c);
  640. }
  641.  
  642. char to_char(int pc) {
  643.    assert(pc < SIZE);
  644.    return Char[pc];
  645. }
  646.  
  647. int from_fen(char c) {
  648.    return util::string_find(Fen_Char, c);
  649. }
  650.  
  651. char to_fen(int p12) {
  652.    assert(p12 < SIDE_SIZE);
  653.    return Fen_Char[p12];
  654. }
  655.  
  656. }
  657.  
  658. namespace move {
  659.  
  660. const int FLAGS_BITS = 9;
  661. const int FLAGS_SIZE = 1 << FLAGS_BITS;
  662. const int FLAGS_MASK = FLAGS_SIZE - 1;
  663.  
  664. const int BITS = FLAGS_BITS + 12;
  665. const int SIZE = 1 << BITS;
  666. const int MASK = SIZE - 1;
  667.  
  668. const int SCORE_BITS = 32 - BITS;
  669. const int SCORE_SIZE = 1 << SCORE_BITS;
  670. const int SCORE_MASK = SCORE_SIZE - 1;
  671.  
  672. enum Move {
  673.    NONE  = 0,
  674.    NULL_ = 1,
  675. };
  676.  
  677. int make_flags(int pc, int cp, int pp = piece::NONE) {
  678.  
  679.    assert(pc < piece::SIZE);
  680.    assert(cp < piece::SIZE);
  681.    assert(pp < piece::SIZE);
  682.  
  683.    return (pc << 6) | (cp << 3) | pp;
  684. }
  685.  
  686. int make(int f, int t, int pc, int cp, int pp = piece::NONE) {
  687.  
  688.    assert(f < square::SIZE);
  689.    assert(t < square::SIZE);
  690.    assert(pc < piece::SIZE);
  691.    assert(cp < piece::SIZE);
  692.    assert(pp < piece::SIZE);
  693.  
  694.    assert(pc != piece::NONE);
  695.    assert(pp == piece::NONE || pc == piece::PAWN);
  696.  
  697.    return (pc << 18) | (cp << 15) | (pp << 12) | (f << 6) | t;
  698. }
  699.  
  700. int from(int mv) {
  701.    assert(mv != NONE);
  702.    assert(mv != NULL_);
  703.    return (mv >> 6) & 077;
  704. }
  705.  
  706. int to(int mv) {
  707.    assert(mv != NONE);
  708.    assert(mv != NULL_);
  709.    return mv & 077;
  710. }
  711.  
  712. int piece(int mv) {
  713.    assert(mv != NONE);
  714.    assert(mv != NULL_);
  715.    return (mv >> 18) & 7;
  716. }
  717.  
  718. int cap(int mv) {
  719.    assert(mv != NONE);
  720.    assert(mv != NULL_);
  721.    return (mv >> 15) & 7;
  722. }
  723.  
  724. int prom(int mv) {
  725.    assert(mv != NONE);
  726.    assert(mv != NULL_);
  727.    return (mv >> 12) & 7;
  728. }
  729.  
  730. int flags(int mv) {
  731.    assert(mv != NONE);
  732.    assert(mv != NULL_);
  733.    return (mv >> 12) & 0777;
  734. }
  735.  
  736. std::string to_can(int mv) {
  737.  
  738.    assert(mv != NONE);
  739.  
  740.    if (mv == NONE)  return "0000";
  741.    if (mv == NULL_) return "0000";
  742.  
  743.    std::string s;
  744.  
  745.    s += square::to_string(from(mv));
  746.    s += square::to_string(to(mv));
  747.  
  748.    if (prom(mv) != piece::NONE) {
  749.       s += std::tolower(piece::to_char(prom(mv)));
  750.    }
  751.  
  752.    return s;
  753. }
  754.  
  755. }
  756.  
  757. namespace bit {
  758.  
  759. bit_t p_left[8];
  760. bit_t p_right[8];
  761. bit_t p_front[8];
  762. bit_t p_rear[8];
  763.  
  764. bit_t p_side_front[side::SIZE][8];
  765. bit_t p_side_rear[side::SIZE][8];
  766.  
  767. bit_t bit(int n) {
  768.    assert(n < 64);
  769.    return U64(1) << n;
  770. }
  771.  
  772. void set(bit_t & b, int n) {
  773.    b |= bit(n);
  774. }
  775.  
  776. void clear(bit_t & b, int n) {
  777.    b &= ~bit(n);
  778. }
  779.  
  780. bool is_set(bit_t b, int n) {
  781.    return (b & bit(n)) != 0;
  782. }
  783.  
  784. int first(bit_t b) {
  785.  
  786.    assert(b != 0);
  787.  
  788. /*
  789.    static const int index[64] = {
  790.        0,  1,  2,  7,  3, 13,  8, 19,
  791.        4, 25, 14, 28,  9, 34, 20, 40,
  792.        5, 17, 26, 38, 15, 46, 29, 48,
  793.       10, 31, 35, 54, 21, 50, 41, 57,
  794.       63,  6, 12, 18, 24, 27, 33, 39,
  795.       16, 37, 45, 47, 30, 53, 49, 56,
  796.       62, 11, 23, 32, 36, 44, 52, 55,
  797.       61, 22, 43, 51, 60, 42, 59, 58,
  798.    };
  799.  
  800.    return index[((b & -b) * U64(0x218A392CD3D5DBF)) >> (64 - 6)];
  801. */
  802.  
  803.    return __builtin_ctzll(b); // GCC
  804. }
  805.  
  806. bit_t rest(bit_t b) {
  807.    assert(b != 0);
  808.    return b & (b - 1);
  809. }
  810.  
  811. int count(bit_t b) {
  812.  
  813. /*
  814.    b = b - ((b >> 1) & U64(0x5555555555555555));
  815.    b = (b & U64(0x3333333333333333)) + ((b >> 2) & U64(0x3333333333333333));
  816.    b = (b + (b >> 4)) & U64(0x0F0F0F0F0F0F0F0F);
  817.    return (b * U64(0x0101010101010101)) >> 56;
  818. */
  819.  
  820.    return __builtin_popcountll(b); // GCC
  821. }
  822.  
  823. int count_loop(bit_t b) {
  824.  
  825. /*
  826.    int n = 0;
  827.  
  828.    for (; b != 0; b = rest(b)) {
  829.       n++;
  830.    }
  831.  
  832.    return n;
  833. */
  834.  
  835.    return __builtin_popcountll(b); // GCC
  836. }
  837.  
  838. bool single(bit_t b) {
  839.    assert(b != 0);
  840.    return rest(b) == 0;
  841. }
  842.  
  843. bit_t file(int fl) {
  844.    assert(fl < 8);
  845.    return U64(0xFF) << (fl * 8);
  846. }
  847.  
  848. bit_t rank(int rk) {
  849.    assert(rk < 8);
  850.    return U64(0x0101010101010101) << rk;
  851. }
  852.  
  853. bit_t files(int fl) {
  854.    assert(fl < 8);
  855.    bit_t file = bit::file(fl);
  856.    return (file << 8) | file | (file >> 8);
  857. }
  858.  
  859. bit_t left(int fl) {
  860.    assert(fl < 8);
  861.    return p_left[fl];
  862. }
  863.  
  864. bit_t right(int fl) {
  865.    assert(fl < 8);
  866.    return p_right[fl];
  867. }
  868.  
  869. bit_t front(int rk) {
  870.    assert(rk < 8);
  871.    return p_front[rk];
  872. }
  873.  
  874. bit_t rear(int rk) {
  875.    assert(rk < 8);
  876.    return p_rear[rk];
  877. }
  878.  
  879. bit_t front(int sq, int sd) {
  880.    int rk = square::rank(sq);
  881.    return p_side_front[sd][rk];
  882. }
  883.  
  884. bit_t rear(int sq, int sd) {
  885.    int rk = square::rank(sq);
  886.    return p_side_rear[sd][rk];
  887. }
  888.  
  889. void init() {
  890.  
  891.    {
  892.       bit_t bf = 0;
  893.       bit_t br = 0;
  894.  
  895.       for (int i = 0; i < 8; i++) {
  896.          p_left[i] = bf;
  897.          p_rear[i] = br;
  898.          bf |= file(i);
  899.          br |= rank(i);
  900.       }
  901.    }
  902.  
  903.    {
  904.       bit_t bf = 0;
  905.       bit_t br = 0;
  906.  
  907.       for (int i = 7; i >= 0; i--) {
  908.          p_right[i] = bf;
  909.          p_front[i] = br;
  910.          bf |= file(i);
  911.          br |= rank(i);
  912.       }
  913.    }
  914.  
  915.    for (int rk = 0; rk < 8; rk++) {
  916.       p_side_front[side::WHITE][rk] = front(rk);
  917.       p_side_front[side::BLACK][rk] = rear(rk);
  918.       p_side_rear [side::WHITE][rk] = rear(rk);
  919.       p_side_rear [side::BLACK][rk] = front(rk);
  920.    }
  921. }
  922.  
  923. }
  924.  
  925. namespace hash {
  926.  
  927. const int TURN       = piece::SIDE_SIZE * square::SIZE;
  928. const int CASTLE     = TURN + 1;
  929. const int EN_PASSANT = CASTLE + 4;
  930. const int SIZE       = EN_PASSANT + 8;
  931.  
  932. hash_t p_rand[SIZE];
  933.  
  934. hash_t rand_64() {
  935.  
  936.    hash_t rand = 0;
  937.  
  938.    for (int i = 0; i < 4; i++) {
  939.       rand = (rand << 16) | util::rand_int(1 << 16);
  940.    }
  941.  
  942.    return rand;
  943. }
  944.  
  945. hash_t rand_key(int index) {
  946.    assert(index >= 0 && index < SIZE);
  947.    return p_rand[index];
  948. }
  949.  
  950. hash_t piece_key(int p12, int sq) {
  951.    return rand_key(p12 * square::SIZE + sq);
  952. }
  953.  
  954. hash_t turn_key(int turn) {
  955.    return (turn == side::WHITE) ? 0 : rand_key(TURN);
  956. }
  957.  
  958. hash_t turn_flip() {
  959.    return rand_key(TURN);
  960. }
  961.  
  962. hash_t flag_key(int flag) {
  963.    assert(flag < 4);
  964.    return rand_key(CASTLE + flag);
  965. }
  966.  
  967. hash_t en_passant_key(int sq) {
  968.    return (sq == square::NONE) ? 0 : rand_key(EN_PASSANT + square::file(sq));
  969. }
  970.  
  971. int64 index(hash_t key) {
  972.    return int64(key);
  973. }
  974.  
  975. uint32 lock(hash_t key) {
  976.    return uint32(key >> 32);
  977. }
  978.  
  979. void init() {
  980.    for (int i = 0; i < SIZE; i++) {
  981.       p_rand[i] = rand_64();
  982.    }
  983. }
  984.  
  985. }
  986.  
  987. namespace castling {
  988.  
  989. struct Info {
  990.    int kf;
  991.    int kt;
  992.    int rf;
  993.    int rt;
  994. };
  995.  
  996. const Info info[4] = {
  997.    { square::E1, square::G1, square::H1, square::F1 },
  998.    { square::E1, square::C1, square::A1, square::D1 },
  999.    { square::E8, square::G8, square::H8, square::F8 },
  1000.    { square::E8, square::C8, square::A8, square::D8 },
  1001. };
  1002.  
  1003. int flags_mask[square::SIZE];
  1004. hash_t flags_key[1 << 4];
  1005.  
  1006. int index(int sd, int wg) {
  1007.    return sd * 2 + wg;
  1008. }
  1009.  
  1010. int side(int index) {
  1011.    return index / 2;
  1012. }
  1013.  
  1014. bool flag(int flags, int index) {
  1015.    assert(index < 4);
  1016.    return bool((flags >> index) & 1);
  1017. }
  1018.  
  1019. void set_flag(int & flags, int index) {
  1020.    assert(index < 4);
  1021.    flags |= 1 << index;
  1022. }
  1023.  
  1024. hash_t flags_key_debug(int flags) {
  1025.  
  1026.    hash_t key = 0;
  1027.  
  1028.    for (int index = 0; index < 4; index++) {
  1029.       if (flag(flags, index)) {
  1030.          key ^= hash::flag_key(index);
  1031.       }
  1032.    }
  1033.  
  1034.    return key;
  1035. }
  1036.  
  1037. void init() {
  1038.  
  1039.    for (int sq = 0; sq < square::SIZE; sq++) {
  1040.       flags_mask[sq] = 0;
  1041.    }
  1042.  
  1043.    set_flag(flags_mask[square::E1], 0);
  1044.    set_flag(flags_mask[square::E1], 1);
  1045.    set_flag(flags_mask[square::H1], 0);
  1046.    set_flag(flags_mask[square::A1], 1);
  1047.  
  1048.    set_flag(flags_mask[square::E8], 2);
  1049.    set_flag(flags_mask[square::E8], 3);
  1050.    set_flag(flags_mask[square::H8], 2);
  1051.    set_flag(flags_mask[square::A8], 3);
  1052.  
  1053.    for (int flags = 0; flags < (1 << 4); flags++) {
  1054.       flags_key[flags] = flags_key_debug(flags);
  1055.    }
  1056. }
  1057.  
  1058. }
  1059.  
  1060. namespace stage {
  1061.  
  1062. const int SIZE = 2;
  1063.  
  1064. enum {
  1065.    MG,
  1066.    EG,
  1067. };
  1068.  
  1069. }
  1070.  
  1071. namespace material {
  1072.  
  1073. const int PAWN_PHASE   = 0;
  1074. const int KNIGHT_PHASE = 1;
  1075. const int BISHOP_PHASE = 1;
  1076. const int ROOK_PHASE   = 2;
  1077. const int QUEEN_PHASE  = 4;
  1078.  
  1079. const int TOTAL_PHASE = PAWN_PHASE * 16 + KNIGHT_PHASE * 4 + BISHOP_PHASE * 4 + ROOK_PHASE * 4 + QUEEN_PHASE * 2;
  1080.  
  1081. const int p_phase[piece::SIZE] = { PAWN_PHASE, KNIGHT_PHASE, BISHOP_PHASE, ROOK_PHASE, QUEEN_PHASE, 0, 0 };
  1082.  
  1083. int phase(int pc) {
  1084.    assert(pc < piece::SIZE);
  1085.    return p_phase[pc];
  1086. }
  1087.  
  1088. }
  1089.  
  1090. namespace board {
  1091.  
  1092. struct Copy {
  1093.    hash_t key;
  1094.    hash_t pawn_key;
  1095.    int flags;
  1096.    int ep_sq;
  1097.    int moves;
  1098.    int recap;
  1099.    int phase;
  1100. };
  1101.  
  1102. struct Undo {
  1103.    Copy copy;
  1104.    int move;
  1105.    int cap_sq;
  1106.    bool castling;
  1107. };
  1108.  
  1109. const std::string start_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -";
  1110.  
  1111. class Board {
  1112.  
  1113. private:
  1114.  
  1115.    static const int SCORE_NONE = -10000; // HACK because "score::NONE" is defined later
  1116.  
  1117.    bit_t p_piece[piece::SIZE];
  1118.    bit_t p_side[side::SIZE];
  1119.    bit_t p_all;
  1120.  
  1121.    int p_king[side::SIZE];
  1122.    int p_count[piece::SIDE_SIZE];
  1123.  
  1124.    int p_square[square::SIZE];
  1125.    int p_turn;
  1126.    Copy p_copy;
  1127.  
  1128.    int p_root;
  1129.    int p_sp;
  1130.    Undo p_stack[1024];
  1131.  
  1132. public:
  1133.  
  1134.    void operator=(const Board & bd) {
  1135.  
  1136.       for (int pc = 0; pc < piece::SIZE; pc++) {
  1137.          p_piece[pc] = bd.p_piece[pc];
  1138.       }
  1139.  
  1140.       for (int sd = 0; sd < side::SIZE; sd++) {
  1141.          p_side[sd] = bd.p_side[sd];
  1142.          p_king[sd] = bd.p_king[sd];
  1143.       }
  1144.  
  1145.       p_all = bd.p_all;
  1146.  
  1147.       for (int p12 = 0; p12 < piece::SIDE_SIZE; p12++) {
  1148.          p_count[p12] = bd.p_count[p12];
  1149.       }
  1150.  
  1151.       for (int sq = 0; sq < square::SIZE; sq++) {
  1152.          p_square[sq] = bd.p_square[sq];
  1153.       }
  1154.  
  1155.       p_turn = bd.p_turn;
  1156.       p_copy = bd.p_copy;
  1157.  
  1158.       p_root = bd.p_root;
  1159.       p_sp = bd.p_sp;
  1160.  
  1161.       for (int sp = 0; sp < bd.p_sp; sp++) {
  1162.          p_stack[sp] = bd.p_stack[sp];
  1163.       }
  1164.  
  1165.       assert(moves() == bd.moves());
  1166.    }
  1167.  
  1168.    bit_t piece(int pc) const {
  1169.       assert(pc < piece::SIZE);
  1170.       assert(pc != piece::NONE);
  1171.       return p_piece[pc];
  1172.    }
  1173.  
  1174.    bit_t piece(int pc, int sd) const {
  1175.       assert(pc < piece::SIZE);
  1176.       assert(pc != piece::NONE);
  1177.       return p_piece[pc] & p_side[sd];
  1178.    }
  1179.  
  1180.    int count(int pc, int sd) const {
  1181.       assert(pc < piece::SIZE);
  1182.       assert(pc != piece::NONE);
  1183.       // return bit::count(piece(pc, sd));
  1184.       return p_count[piece::make(pc, sd)];
  1185.    }
  1186.  
  1187.    bit_t side(int sd) const {
  1188.       return p_side[sd];
  1189.    }
  1190.  
  1191.    bit_t pieces(int sd) const {
  1192.       return p_side[sd] & ~piece(piece::PAWN, sd);
  1193.    }
  1194.  
  1195.    bit_t all() const {
  1196.       return p_all;
  1197.    }
  1198.  
  1199.    bit_t empty() const {
  1200.       return ~p_all;
  1201.    }
  1202.  
  1203.    int square(int sq) const {
  1204.       return p_square[sq];
  1205.    }
  1206.  
  1207.    int square_side(int sq) const {
  1208.       assert(p_square[sq] != piece::NONE);
  1209.       return (p_side[side::BLACK] >> sq) & 1; // HACK: uses Side internals
  1210.    }
  1211.  
  1212.    bool square_is(int sq, int pc, int sd) const {
  1213.       assert(pc < piece::SIZE);
  1214.       assert(pc != piece::NONE);
  1215.       return square(sq) == pc && square_side(sq) == sd;
  1216.    }
  1217.  
  1218.    int king(int sd) const {
  1219.       int sq = p_king[sd];
  1220.       assert(sq == bit::first(piece(piece::KING, sd)));
  1221.       return sq;
  1222.    }
  1223.  
  1224.    int turn() const {
  1225.       return p_turn;
  1226.    }
  1227.  
  1228.    hash_t key() const {
  1229.       hash_t key = p_copy.key;
  1230.       key ^= castling::flags_key[p_copy.flags];
  1231.       key ^= hash::en_passant_key(p_copy.ep_sq);
  1232.       return key;
  1233.    }
  1234.  
  1235.    hash_t pawn_key() const {
  1236.       return p_copy.pawn_key;
  1237.    }
  1238.  
  1239.    hash_t eval_key() const {
  1240.       hash_t key = p_copy.key;
  1241.       key ^= hash::turn_key(p_turn); // remove incremental STM
  1242.       key ^= castling::flags_key[p_copy.flags];
  1243.       return key;
  1244.    }
  1245.  
  1246.    int flags() const {
  1247.       return p_copy.flags;
  1248.    }
  1249.  
  1250.    int ep_sq() const {
  1251.       return p_copy.ep_sq;
  1252.    }
  1253.  
  1254.    int moves() const {
  1255.       return p_copy.moves;
  1256.    }
  1257.  
  1258.    int recap() const {
  1259.       return p_copy.recap;
  1260.    }
  1261.  
  1262.    int phase() const {
  1263.       return p_copy.phase;
  1264.    }
  1265.  
  1266.    int ply() const {
  1267.       assert(p_sp >= p_root);
  1268.       return p_sp - p_root;
  1269.    }
  1270.  
  1271.    int last_move() const {
  1272.       return (p_sp == 0) ? move::NONE : p_stack[p_sp - 1].move;
  1273.    }
  1274.  
  1275.    bool is_draw() const {
  1276.  
  1277.       if (p_copy.moves > 100) { // TODO: check for mate
  1278.          return true;
  1279.       }
  1280.  
  1281.       hash_t key = p_copy.key; // HACK: ignores castling flags and e.p. square
  1282.  
  1283.       assert(p_copy.moves <= p_sp);
  1284.  
  1285.       for (int i = 4; i < p_copy.moves; i += 2) {
  1286.          if (p_stack[p_sp - i].copy.key == key) {
  1287.             return true;
  1288.          }
  1289.       }
  1290.  
  1291.       return false;
  1292.    }
  1293.  
  1294.    void set_root() {
  1295.       p_root = p_sp;
  1296.    }
  1297.  
  1298.    void clear() {
  1299.  
  1300.       for (int pc = 0; pc < piece::SIZE; pc++) {
  1301.          p_piece[pc] = 0;
  1302.       }
  1303.  
  1304.       for (int sd = 0; sd < side::SIZE; sd++) {
  1305.          p_side[sd] = 0;
  1306.       }
  1307.  
  1308.       for (int sq = 0; sq < square::SIZE; sq++) {
  1309.          p_square[sq] = piece::NONE;
  1310.       }
  1311.  
  1312.       for (int sd = 0; sd < side::SIZE; sd++) {
  1313.          p_king[sd] = square::NONE;
  1314.       }
  1315.  
  1316.       for (int p12 = 0; p12 < piece::SIDE_SIZE; p12++) {
  1317.          p_count[p12] = 0;
  1318.       }
  1319.  
  1320.       p_turn = side::WHITE;
  1321.  
  1322.       p_copy.key = 0;
  1323.       p_copy.pawn_key = 0;
  1324.       p_copy.flags = 0;
  1325.       p_copy.ep_sq = square::NONE;
  1326.       p_copy.moves = 0;
  1327.       p_copy.recap = square::NONE;
  1328.       p_copy.phase = 0;
  1329.  
  1330.       p_root = 0;
  1331.       p_sp = 0;
  1332.    }
  1333.  
  1334.    void clear_square(int pc, int sd, int sq, bool update_copy) {
  1335.  
  1336.       assert(pc < piece::SIZE);
  1337.       assert(pc != piece::NONE);
  1338.       assert(sq >= 0 && sq < square::SIZE);
  1339.  
  1340.       assert(pc == p_square[sq]);
  1341.  
  1342.       assert(bit::is_set(p_piece[pc], sq));
  1343.       bit::clear(p_piece[pc], sq);
  1344.  
  1345.       assert(bit::is_set(p_side[sd], sq));
  1346.       bit::clear(p_side[sd], sq);
  1347.  
  1348.       assert(p_square[sq] != piece::NONE);
  1349.       p_square[sq] = piece::NONE;
  1350.  
  1351.       int p12 = piece::make(pc, sd);
  1352.  
  1353.       assert(p_count[p12] != 0);
  1354.       p_count[p12]--;
  1355.  
  1356.       if (update_copy) {
  1357.  
  1358.          hash_t key = hash::piece_key(p12, sq);
  1359.          p_copy.key ^= key;
  1360.          if (pc == piece::PAWN) p_copy.pawn_key ^= key;
  1361.  
  1362.          p_copy.phase -= material::phase(pc);
  1363.       }
  1364.    }
  1365.  
  1366.    void set_square(int pc, int sd, int sq, bool update_copy) {
  1367.  
  1368.       assert(pc < piece::SIZE);
  1369.       assert(pc != piece::NONE);
  1370.       assert(sq >= 0 && sq < square::SIZE);
  1371.  
  1372.       assert(!bit::is_set(p_piece[pc], sq));
  1373.       bit::set(p_piece[pc], sq);
  1374.  
  1375.       assert(!bit::is_set(p_side[sd], sq));
  1376.       bit::set(p_side[sd], sq);
  1377.  
  1378.       assert(p_square[sq] == piece::NONE);
  1379.       p_square[sq] = pc;
  1380.  
  1381.       if (pc == piece::KING) {
  1382.          p_king[sd] = sq;
  1383.       }
  1384.  
  1385.       int p12 = piece::make(pc, sd);
  1386.  
  1387.       p_count[p12]++;
  1388.  
  1389.       if (update_copy) {
  1390.  
  1391.          hash_t key = hash::piece_key(p12, sq);
  1392.          p_copy.key ^= key;
  1393.          if (pc == piece::PAWN) p_copy.pawn_key ^= key;
  1394.  
  1395.          p_copy.phase += material::phase(pc);
  1396.       }
  1397.    }
  1398.  
  1399.    void move_square(int pc, int sd, int f, int t, bool update_copy) { // TODO
  1400.       clear_square(pc, sd, f, update_copy);
  1401.       set_square(pc, sd, t, update_copy);
  1402.    }
  1403.  
  1404.    void flip_turn() {
  1405.       p_turn = side::opposit(p_turn);
  1406.       p_copy.key ^= hash::turn_flip();
  1407.    }
  1408.  
  1409.    void update() {
  1410.  
  1411.       p_all = p_side[side::WHITE] | p_side[side::BLACK];
  1412.  
  1413. #ifdef DEBUG
  1414.  
  1415.       for (int p12 = 0; p12 < piece::SIDE_SIZE; p12++) {
  1416.          assert(p_count[p12] == bit::count(piece(piece::piece(p12), piece::side(p12))));
  1417.       }
  1418.  
  1419.       assert(p_count[piece::WHITE_KING] == 1);
  1420.       assert(p_count[piece::BLACK_KING] == 1);
  1421.  
  1422.       assert((p_piece[piece::PAWN] & bit::rank(square::RANK_1)) == 0);
  1423.       assert((p_piece[piece::PAWN] & bit::rank(square::RANK_8)) == 0);
  1424.  
  1425.       for (int sd = 0; sd < side::SIZE; sd++) {
  1426.          for (int wg = 0; wg < side::SIZE; wg++) {
  1427.             int index = castling::index(sd, wg);
  1428.             if (castling::flag(p_copy.flags, index)) {
  1429.                assert(square_is(castling::info[index].kf, piece::KING, sd));
  1430.                assert(square_is(castling::info[index].rf, piece::ROOK, sd));
  1431.             }
  1432.          }
  1433.       }
  1434.  
  1435. #endif
  1436.  
  1437.    }
  1438.  
  1439.    bool can_castle(int index) const {
  1440.  
  1441.       int sd = castling::side(index);
  1442.  
  1443.       return square_is(castling::info[index].kf, piece::KING, sd)
  1444.           && square_is(castling::info[index].rf, piece::ROOK, sd);
  1445.    }
  1446.  
  1447.    bool pawn_is_attacked(int sq, int sd) const {
  1448.  
  1449.       int fl = square::file(sq);
  1450.       sq -= square::pawn_inc(sd);
  1451.  
  1452.       return (fl != square::FILE_A && square_is(sq + square::INC_LEFT,  piece::PAWN, sd))
  1453.           || (fl != square::FILE_H && square_is(sq + square::INC_RIGHT, piece::PAWN, sd));
  1454.    }
  1455.  
  1456.    void init_fen(const std::string & s) {
  1457.  
  1458.       clear();
  1459.  
  1460.       int pos = 0;
  1461.  
  1462.       // piece placement
  1463.  
  1464.       int sq = 0;
  1465.  
  1466.       while (pos < int(s.size())) {
  1467.  
  1468.          assert(sq <= square::SIZE);
  1469.  
  1470.          char c = s[pos++];
  1471.  
  1472.          if (false) {
  1473.  
  1474.          } else if (c == ' ') {
  1475.  
  1476.             break;
  1477.  
  1478.          } else if (c == '/') {
  1479.  
  1480.             continue;
  1481.  
  1482.          } else if (std::isdigit(c)) {
  1483.  
  1484.             sq += c - '0';
  1485.  
  1486.          } else { // assume piece
  1487.  
  1488.             int p12 = piece::from_fen(c);
  1489.             int pc = piece::piece(p12);
  1490.             int sd = piece::side(p12);
  1491.             set_square(pc, sd, square::from_fen(sq), true);
  1492.             sq++;
  1493.          }
  1494.       }
  1495.  
  1496.       assert(sq == square::SIZE);
  1497.  
  1498.       // turn
  1499.  
  1500.       p_turn = side::WHITE;
  1501.  
  1502.       if (pos < int(s.size())) {
  1503.  
  1504.          p_turn = util::string_find("wb", s[pos++]);
  1505.  
  1506.          if (pos < int(s.size())) {
  1507.             assert(s[pos] == ' ');
  1508.             pos++;
  1509.          }
  1510.       }
  1511.  
  1512.       p_copy.key ^= hash::turn_key(p_turn);
  1513.  
  1514.       // castling flags
  1515.  
  1516.       p_copy.flags = 0;
  1517.  
  1518.       if (pos < int(s.size())) { // read from FEN
  1519.  
  1520.          while (pos < int(s.size())) {
  1521.  
  1522.             char c = s[pos++];
  1523.             if (c == ' ') break;
  1524.             if (c == '-') continue;
  1525.  
  1526.             int index = util::string_find("KQkq", c);
  1527.  
  1528.             if (can_castle(index)) {
  1529.                castling::set_flag(p_copy.flags, index);
  1530.             }
  1531.          }
  1532.  
  1533.       } else { // guess from position
  1534.  
  1535.          for (int index = 0; index < 4; index++) {
  1536.             if (can_castle(index)) {
  1537.                castling::set_flag(p_copy.flags, index);
  1538.             }
  1539.          }
  1540.       }
  1541.  
  1542.       // en-passant square
  1543.  
  1544.       p_copy.ep_sq = square::NONE;
  1545.  
  1546.       if (pos < int(s.size())) { // read from FEN
  1547.  
  1548.          std::string ep_string;
  1549.  
  1550.          while (pos < int(s.size())) {
  1551.  
  1552.             char c = s[pos++];
  1553.             if (c == ' ') break;
  1554.  
  1555.             ep_string += c;
  1556.          }
  1557.  
  1558.          if (ep_string != "-") {
  1559.  
  1560.             int sq = square::from_string(ep_string);
  1561.  
  1562.             if (pawn_is_attacked(sq, p_turn)) {
  1563.                p_copy.ep_sq = sq;
  1564.             }
  1565.          }
  1566.       }
  1567.  
  1568.       update();
  1569.    }
  1570.  
  1571.    void move(int mv) {
  1572.  
  1573.       assert(mv != move::NONE);
  1574.       assert(mv != move::NULL_);
  1575.  
  1576.       int sd = p_turn;
  1577.       int xd = side::opposit(sd);
  1578.  
  1579.       int f = move::from(mv);
  1580.       int t = move::to(mv);
  1581.  
  1582.       int pc = move::piece(mv);
  1583.       int cp = move::cap(mv);
  1584.       int pp = move::prom(mv);
  1585.  
  1586.       assert(p_square[f] == pc);
  1587.       assert(square_side(f) == sd);
  1588.  
  1589.       assert(p_sp < 1024);
  1590.       Undo & undo = p_stack[p_sp++];
  1591.  
  1592.       undo.copy = p_copy;
  1593.       undo.move = mv;
  1594.       undo.castling = false;
  1595.  
  1596.       p_copy.moves++;
  1597.       p_copy.recap = square::NONE;
  1598.  
  1599.       // capture
  1600.  
  1601.       assert(cp != piece::KING);
  1602.  
  1603.       if (pc == piece::PAWN && t == p_copy.ep_sq) {
  1604.  
  1605.          int cap_sq = t - square::pawn_inc(sd);
  1606.          assert(p_square[cap_sq] == cp);
  1607.          assert(cp == piece::PAWN);
  1608.  
  1609.          undo.cap_sq = cap_sq;
  1610.  
  1611.          clear_square(cp, xd, cap_sq, true);
  1612.  
  1613.       } else if (cp != piece::NONE) {
  1614.  
  1615.          assert(p_square[t] == cp);
  1616.          assert(square_side(t) == xd);
  1617.  
  1618.          undo.cap_sq = t;
  1619.  
  1620.          clear_square(cp, xd, t, true);
  1621.  
  1622.       } else {
  1623.  
  1624.          assert(p_square[t] == cp);
  1625.       }
  1626.  
  1627.       // promotion
  1628.  
  1629.       if (pp != piece::NONE) {
  1630.          assert(pc == piece::PAWN);
  1631.          clear_square(piece::PAWN, sd, f, true);
  1632.          set_square(pp, sd, t, true);
  1633.       } else {
  1634.          move_square(pc, sd, f, t, true);
  1635.       }
  1636.  
  1637.       // castling rook
  1638.  
  1639.       if (pc == piece::KING && std::abs(t - f) == square::CASTLING_DELTA) {
  1640.  
  1641.          undo.castling = true;
  1642.  
  1643.          int wg = (t > f) ? wing::KING : wing::QUEEN;
  1644.          int index = castling::index(sd, wg);
  1645.  
  1646.          assert(castling::flag(p_copy.flags, index));
  1647.  
  1648.          assert(f == castling::info[index].kf);
  1649.          assert(t == castling::info[index].kt);
  1650.  
  1651.          move_square(piece::ROOK, sd, castling::info[index].rf, castling::info[index].rt, true);
  1652.       }
  1653.  
  1654.       // turn
  1655.  
  1656.       flip_turn();
  1657.  
  1658.       // castling flags
  1659.  
  1660.       p_copy.flags &= ~castling::flags_mask[f];
  1661.       p_copy.flags &= ~castling::flags_mask[t];
  1662.  
  1663.       // en-passant square
  1664.  
  1665.       p_copy.ep_sq = square::NONE;
  1666.  
  1667.       if (pc == piece::PAWN && std::abs(t - f) == square::DOUBLE_PAWN_DELTA) {
  1668.          int sq = (f + t) / 2;
  1669.          if (pawn_is_attacked(sq, xd)) {
  1670.             p_copy.ep_sq = sq;
  1671.          }
  1672.       }
  1673.  
  1674.       // move counter
  1675.  
  1676.       if (cp != piece::NONE || pc == piece::PAWN) {
  1677.          p_copy.moves = 0; // conversion;
  1678.       }
  1679.  
  1680.       // recapture
  1681.  
  1682.       if (cp != piece::NONE || pp != piece::NONE) {
  1683.          p_copy.recap = t;
  1684.       }
  1685.  
  1686.       update();
  1687.    }
  1688.  
  1689.    void undo() {
  1690.  
  1691.       assert(p_sp > 0);
  1692.       const Undo & undo = p_stack[--p_sp];
  1693.  
  1694.       int mv = undo.move;
  1695.  
  1696.       int f = move::from(mv);
  1697.       int t = move::to(mv);
  1698.  
  1699.       int pc = move::piece(mv);
  1700.       int cp = move::cap(mv);
  1701.       int pp = move::prom(mv);
  1702.  
  1703.       int xd = p_turn;
  1704.       int sd = side::opposit(xd);
  1705.  
  1706.       assert(p_square[t] == pc || p_square[t] == pp);
  1707.       assert(square_side(t) == sd);
  1708.  
  1709.       // castling rook
  1710.  
  1711.       if (undo.castling) {
  1712.  
  1713.          int wg = (t > f) ? wing::KING : wing::QUEEN;
  1714.          int index = castling::index(sd, wg);
  1715.  
  1716.          assert(f == castling::info[index].kf);
  1717.          assert(t == castling::info[index].kt);
  1718.  
  1719.          move_square(piece::ROOK, sd, castling::info[index].rt, castling::info[index].rf, false);
  1720.       }
  1721.  
  1722.       // promotion
  1723.  
  1724.       if (pp != piece::NONE) {
  1725.          assert(pc == piece::PAWN);
  1726.          clear_square(pp, sd, t, false);
  1727.          set_square(piece::PAWN, sd, f, false);
  1728.       } else {
  1729.          move_square(pc, sd, t, f, false);
  1730.       }
  1731.  
  1732.       // capture
  1733.  
  1734.       if (cp != piece::NONE) {
  1735.          set_square(cp, xd, undo.cap_sq, false);
  1736.       }
  1737.  
  1738.       flip_turn();
  1739.       p_copy = undo.copy;
  1740.  
  1741.       update();
  1742.    }
  1743.  
  1744.    void move_null() {
  1745.  
  1746.       assert(p_sp < 1024);
  1747.       Undo & undo = p_stack[p_sp++];
  1748.  
  1749.       undo.move = move::NULL_;
  1750.  
  1751.       undo.copy = p_copy;
  1752.  
  1753.       flip_turn();
  1754.       p_copy.ep_sq = square::NONE;
  1755.       p_copy.moves = 0; // HACK: conversion
  1756.       p_copy.recap = square::NONE;
  1757.  
  1758.       update();
  1759.    }
  1760.  
  1761.    void undo_null() {
  1762.  
  1763.       assert(p_sp > 0);
  1764.       const Undo & undo = p_stack[--p_sp];
  1765.  
  1766.       assert(undo.move == move::NULL_);
  1767.  
  1768.       flip_turn();
  1769.       p_copy = undo.copy;
  1770.  
  1771.       update();
  1772.    }
  1773.  
  1774. };
  1775.  
  1776. }
  1777.  
  1778. namespace attack {
  1779.  
  1780. struct Attacks {
  1781.    int size;
  1782.    int square[2];
  1783.    bit_t avoid;
  1784.    bit_t pinned;
  1785. };
  1786.  
  1787. const int Pawn_Move[side::SIZE] = { +1, -1 };
  1788. const int Pawn_Attack[side::SIZE][2] = { { -15, +17 }, { -17, +15 } };
  1789.  
  1790. const int Knight_Inc[] = { -33, -31, -18, -14, +14, +18, +31, +33, 0 };
  1791. const int Bishop_Inc[] = { -17, -15, +15, +17, 0 };
  1792. const int Rook_Inc[]   = { -16, -1, +1, +16, 0 };
  1793. const int Queen_Inc[]  = { -17, -16, -15, -1, +1, +15, +16, +17, 0 };
  1794.  
  1795. const int * Piece_Inc[piece::SIZE] = { NULL, Knight_Inc, Bishop_Inc, Rook_Inc, Queen_Inc, Queen_Inc, NULL };
  1796.  
  1797. bit_t Pawn_Moves[side::SIZE][square::SIZE];
  1798. bit_t Pawn_Attacks[side::SIZE][square::SIZE];
  1799. bit_t Piece_Attacks[piece::SIZE][square::SIZE];
  1800. bit_t Blockers[piece::SIZE][square::SIZE];
  1801.  
  1802. bit_t Between[square::SIZE][square::SIZE];
  1803. bit_t Behind[square::SIZE][square::SIZE];
  1804.  
  1805. bool line_is_empty(int f, int t, const board::Board & bd) {
  1806.    return (bd.all() & Between[f][t]) == 0;
  1807. }
  1808.  
  1809. bit_t ray(int f, int t) {
  1810.    return Between[f][t] | Behind[f][t]; // HACK: t should be included
  1811. }
  1812.  
  1813. bool pawn_move(int sd, int f, int t, const board::Board & bd) {
  1814.    assert(sd < side::SIZE);
  1815.    return bit::is_set(Pawn_Moves[sd][f], t) && line_is_empty(f, t, bd);
  1816. }
  1817.  
  1818. bool pawn_attack(int sd, int f, int t) {
  1819.    assert(sd < side::SIZE);
  1820.    return bit::is_set(Pawn_Attacks[sd][f], t);
  1821. }
  1822.  
  1823. bool piece_attack(int pc, int f, int t, const board::Board & bd) {
  1824.    assert(pc != piece::PAWN);
  1825.    return bit::is_set(Piece_Attacks[pc][f], t) && line_is_empty(f, t, bd);
  1826. }
  1827.  
  1828. bool attack(int pc, int sd, int f, int t, const board::Board & bd) {
  1829.    assert(sd < side::SIZE);
  1830.    if (pc == piece::PAWN) {
  1831.       return pawn_attack(sd, f, t);
  1832.    } else {
  1833.       return piece_attack(pc, f, t, bd);
  1834.    }
  1835. }
  1836.  
  1837. bit_t pawn_moves_from(int sd, const board::Board & bd) { // for pawn mobility
  1838.  
  1839.    assert(sd < side::SIZE);
  1840.  
  1841.    bit_t fs = bd.piece(piece::PAWN, sd);
  1842.  
  1843.    if (sd == side::WHITE) {
  1844.       return fs << 1;
  1845.    } else {
  1846.       return fs >> 1;
  1847.    }
  1848. }
  1849.  
  1850. bit_t pawn_moves_to(int sd, bit_t ts, const board::Board & bd) {
  1851.  
  1852.    assert(sd < side::SIZE);
  1853.    assert((bd.all() & ts) == 0);
  1854.  
  1855.    bit_t pawns = bd.piece(piece::PAWN, sd);
  1856.    bit_t empty = bd.empty();
  1857.  
  1858.    bit_t fs = 0;
  1859.  
  1860.    if (sd == side::WHITE) {
  1861.       fs |= (ts >> 1);
  1862.       fs |= (ts >> 2) & (empty >> 1) & bit::rank(square::RANK_2);
  1863.    } else {
  1864.       fs |= (ts << 1);
  1865.       fs |= (ts << 2) & (empty << 1) & bit::rank(square::RANK_7);
  1866.    }
  1867.  
  1868.    return pawns & fs;
  1869. }
  1870.  
  1871. bit_t pawn_attacks_from(int sd, const board::Board & bd) {
  1872.  
  1873.    assert(sd < side::SIZE);
  1874.  
  1875.    bit_t fs = bd.piece(piece::PAWN, sd);
  1876.  
  1877.    if (sd == side::WHITE) {
  1878.       return (fs >> 7) | (fs << 9);
  1879.    } else {
  1880.       return (fs >> 9) | (fs << 7);
  1881.    }
  1882. }
  1883.  
  1884. bit_t pawn_attacks_tos(int sd, bit_t ts) {
  1885.  
  1886.    assert(sd < side::SIZE);
  1887.  
  1888.    if (sd == side::WHITE) {
  1889.       return (ts >> 9) | (ts << 7);
  1890.    } else {
  1891.       return (ts >> 7) | (ts << 9);
  1892.    }
  1893. }
  1894.  
  1895. bit_t pawn_attacks_from(int sd, int f) {
  1896.    assert(sd < side::SIZE);
  1897.    return Pawn_Attacks[sd][f];
  1898. }
  1899.  
  1900. bit_t pawn_attacks_to(int sd, int t) {
  1901.    assert(sd < side::SIZE);
  1902.    return pawn_attacks_from(side::opposit(sd), t);
  1903. }
  1904.  
  1905. bit_t piece_attacks_from(int pc, int f, const board::Board & bd) {
  1906.  
  1907.    assert(pc != piece::PAWN);
  1908.  
  1909.    bit_t ts = Piece_Attacks[pc][f];
  1910.  
  1911.    for (bit_t b = bd.all() & Blockers[pc][f]; b != 0; b = bit::rest(b)) {
  1912.       int sq = bit::first(b);
  1913.       ts &= ~Behind[f][sq];
  1914.    }
  1915.  
  1916.    return ts;
  1917. }
  1918.  
  1919. bit_t piece_attacks_to(int pc, int t, const board::Board & bd) {
  1920.    assert(pc != piece::PAWN);
  1921.    return piece_attacks_from(pc, t, bd);
  1922. }
  1923.  
  1924. bit_t piece_moves_from(int pc, int sd, int f, const board::Board & bd) {
  1925.    if (pc == piece::PAWN) {
  1926.       assert(false); // TODO: blockers
  1927.       return Pawn_Moves[sd][f];
  1928.    } else {
  1929.       return piece_attacks_from(pc, f, bd);
  1930.    }
  1931. }
  1932.  
  1933. bit_t attacks_from(int pc, int sd, int f, const board::Board & bd) {
  1934.    if (pc == piece::PAWN) {
  1935.       return Pawn_Attacks[sd][f];
  1936.    } else {
  1937.       return piece_attacks_from(pc, f, bd);
  1938.    }
  1939. }
  1940.  
  1941. bit_t attacks_to(int pc, int sd, int t, const board::Board & bd) {
  1942.    return attacks_from(pc, side::opposit(sd), t, bd); // HACK for pawns
  1943. }
  1944.  
  1945. bit_t pseudo_attacks_from(int pc, int sd, int f) {
  1946.    if (pc == piece::PAWN) {
  1947.       return Pawn_Attacks[sd][f];
  1948.    } else {
  1949.       return Piece_Attacks[pc][f];
  1950.    }
  1951. }
  1952.  
  1953. bit_t pseudo_attacks_to(int pc, int sd, int t) {
  1954.    return pseudo_attacks_from(pc, side::opposit(sd), t); // HACK for pawns
  1955. }
  1956.  
  1957. bit_t slider_pseudo_attacks_to(int sd, int t, const board::Board & bd) {
  1958.  
  1959.    assert(sd < side::SIZE);
  1960.  
  1961.    bit_t b = 0;
  1962.    b |= bd.piece(piece::BISHOP, sd) & Piece_Attacks[piece::BISHOP][t];
  1963.    b |= bd.piece(piece::ROOK,   sd) & Piece_Attacks[piece::ROOK][t];
  1964.    b |= bd.piece(piece::QUEEN,  sd) & Piece_Attacks[piece::QUEEN][t];
  1965.  
  1966.    return b;
  1967. }
  1968.  
  1969. bool attack_behind(int f, int t, int sd, const board::Board & bd) {
  1970.  
  1971.    assert(bd.square(t) != piece::NONE);
  1972.  
  1973.    bit_t behind = Behind[f][t];
  1974.    if (behind == 0) return false;
  1975.  
  1976.    for (bit_t b = slider_pseudo_attacks_to(sd, t, bd) & behind; b != 0; b = bit::rest(b)) {
  1977.  
  1978.       int sq = bit::first(b);
  1979.  
  1980.       if (bit::single(bd.all() & Between[sq][f])) {
  1981.          return true;
  1982.       }
  1983.    }
  1984.  
  1985.    return false;
  1986. }
  1987.  
  1988. bool is_attacked(int t, int sd, const board::Board & bd) {
  1989.  
  1990.    // non-sliders
  1991.  
  1992.    if ((bd.piece(piece::PAWN, sd) & Pawn_Attacks[side::opposit(sd)][t]) != 0) { // HACK
  1993.       return true;
  1994.    }
  1995.  
  1996.    if ((bd.piece(piece::KNIGHT, sd) & Piece_Attacks[piece::KNIGHT][t]) != 0) {
  1997.       return true;
  1998.    }
  1999.  
  2000.    if ((bd.piece(piece::KING, sd) & Piece_Attacks[piece::KING][t]) != 0) {
  2001.       return true;
  2002.    }
  2003.  
  2004.    // sliders
  2005.  
  2006.    for (bit_t b = slider_pseudo_attacks_to(sd, t, bd); b != 0; b = bit::rest(b)) {
  2007.  
  2008.       int f = bit::first(b);
  2009.  
  2010.       if ((bd.all() & Between[f][t]) == 0) {
  2011.          return true;
  2012.       }
  2013.    }
  2014.  
  2015.    return false;
  2016. }
  2017.  
  2018. bit_t pinned_by(int t, int sd, const board::Board & bd) {
  2019.  
  2020.    bit_t pinned = 0;
  2021.  
  2022.    for (bit_t b = slider_pseudo_attacks_to(sd, t, bd); b != 0; b = bit::rest(b)) {
  2023.  
  2024.       int f = bit::first(b);
  2025.  
  2026.       bit_t bb = bd.all() & Between[f][t];
  2027.  
  2028.       if (bb != 0 && bit::single(bb)) {
  2029.          pinned |= bb;
  2030.       }
  2031.    }
  2032.  
  2033.    return pinned;
  2034. }
  2035.  
  2036. void init_attacks(Attacks & attacks, int sd, const board::Board & bd) { // for strictly-legal moves
  2037.  
  2038.    int atk = side::opposit(sd);
  2039.    int def = sd;
  2040.  
  2041.    int t = bd.king(def);
  2042.  
  2043.    attacks.size   = 0;
  2044.    attacks.avoid  = 0;
  2045.    attacks.pinned = 0;
  2046.  
  2047.    // non-sliders
  2048.  
  2049.    {
  2050.       bit_t b = 0;
  2051.       b |= bd.piece(piece::PAWN,   atk) & Pawn_Attacks[def][t]; // HACK
  2052.       b |= bd.piece(piece::KNIGHT, atk) & Piece_Attacks[piece::KNIGHT][t];
  2053.  
  2054.       if (b != 0) {
  2055.          assert(bit::single(b));
  2056.          assert(attacks.size < 2);
  2057.          attacks.square[attacks.size++] = bit::first(b);
  2058.       }
  2059.    }
  2060.  
  2061.    // sliders
  2062.  
  2063.    for (bit_t b = slider_pseudo_attacks_to(atk, t, bd); b != 0; b = bit::rest(b)) {
  2064.  
  2065.       int f = bit::first(b);
  2066.  
  2067.       bit_t bb = bd.all() & Between[f][t];
  2068.  
  2069.       if (bb == 0) {
  2070.          assert(attacks.size < 2);
  2071.          attacks.square[attacks.size++] = f;
  2072.          attacks.avoid |= ray(f, t);
  2073.       } else if (bit::single(bb)) {
  2074.          attacks.pinned |= bb;
  2075.       }
  2076.    }
  2077. }
  2078.  
  2079. void init_attacks(Attacks & attacks, const board::Board & bd) {
  2080.    init_attacks(attacks, bd.turn(), bd);
  2081. }
  2082.  
  2083. bool is_legal(const board::Board & bd) {
  2084.  
  2085.    int atk = bd.turn();
  2086.    int def = side::opposit(atk);
  2087.  
  2088.    return !is_attacked(bd.king(def), atk, bd);
  2089. }
  2090.  
  2091. bool is_in_check(const board::Board & bd) {
  2092.  
  2093.    int atk = bd.turn();
  2094.    int def = side::opposit(atk);
  2095.  
  2096.    return is_attacked(bd.king(atk), def, bd);
  2097. }
  2098.  
  2099. bit_t pawn_moves_debug(int sd, int sq) {
  2100.  
  2101.    assert(sd < side::SIZE);
  2102.  
  2103.    bit_t b = 0;
  2104.  
  2105.    int f = square::to_88(sq);
  2106.    int inc = Pawn_Move[sd];
  2107.  
  2108.    int t = f + inc;
  2109.  
  2110.    if (square::is_valid_88(t)) {
  2111.       bit::set(b, square::from_88(t));
  2112.    }
  2113.  
  2114.    if (square::rank(sq, sd) == square::RANK_2) {
  2115.       t += inc;
  2116.       assert(square::is_valid_88(t));
  2117.       bit::set(b, square::from_88(t));
  2118.    }
  2119.  
  2120.    return b;
  2121. }
  2122.  
  2123. bit_t pawn_attacks_debug(int sd, int sq) {
  2124.  
  2125.    assert(sd < side::SIZE);
  2126.  
  2127.    bit_t b = 0;
  2128.  
  2129.    int f = square::to_88(sq);
  2130.  
  2131.    for (int dir = 0; dir < 2; dir++) {
  2132.       int t = f + Pawn_Attack[sd][dir];
  2133.       if (square::is_valid_88(t)) {
  2134.          bit::set(b, square::from_88(t));
  2135.       }
  2136.    }
  2137.  
  2138.    return b;
  2139. }
  2140.  
  2141. bit_t piece_attacks_debug(int pc, int sq) {
  2142.  
  2143.    assert(pc != piece::PAWN);
  2144.  
  2145.    bit_t b = 0;
  2146.  
  2147.    int f = square::to_88(sq);
  2148.  
  2149.    for (int dir = 0; true; dir++) {
  2150.  
  2151.       int inc = Piece_Inc[pc][dir];
  2152.       if (inc == 0) break;
  2153.  
  2154.       if (piece::is_slider(pc)) {
  2155.  
  2156.          for (int t = f + inc; square::is_valid_88(t); t += inc) {
  2157.             bit::set(b, square::from_88(t));
  2158.          }
  2159.  
  2160.       } else {
  2161.  
  2162.          int t = f + inc;
  2163.  
  2164.          if (square::is_valid_88(t)) {
  2165.             bit::set(b, square::from_88(t));
  2166.          }
  2167.       }
  2168.    }
  2169.  
  2170.    return b;
  2171. }
  2172.  
  2173. int delta_inc(int f, int t) {
  2174.  
  2175.    for (int dir = 0; dir < 8; dir++) {
  2176.  
  2177.       int inc = Queen_Inc[dir];
  2178.  
  2179.       for (int sq = f + inc; square::is_valid_88(sq); sq += inc) {
  2180.          if (sq == t) {
  2181.             return inc;
  2182.          }
  2183.       }
  2184.    }
  2185.  
  2186.    return 0;
  2187. }
  2188.  
  2189. bit_t between_debug(int f, int t) {
  2190.  
  2191.    f = square::to_88(f);
  2192.    t = square::to_88(t);
  2193.  
  2194.    bit_t b = 0;
  2195.  
  2196.    int inc = delta_inc(f, t);
  2197.  
  2198.    if (inc != 0) {
  2199.       for (int sq = f + inc; sq != t; sq += inc) {
  2200.          bit::set(b, square::from_88(sq));
  2201.       }
  2202.    }
  2203.  
  2204.    return b;
  2205. }
  2206.  
  2207. bit_t behind_debug(int f, int t) {
  2208.  
  2209.    f = square::to_88(f);
  2210.    t = square::to_88(t);
  2211.  
  2212.    bit_t b = 0;
  2213.  
  2214.    int inc = delta_inc(f, t);
  2215.  
  2216.    if (inc != 0) {
  2217.       for (int sq = t + inc; square::is_valid_88(sq); sq += inc) {
  2218.          bit::set(b, square::from_88(sq));
  2219.       }
  2220.    }
  2221.  
  2222.    return b;
  2223. }
  2224.  
  2225. bit_t blockers_debug(int pc, int f) {
  2226.  
  2227.    assert(pc != piece::PAWN);
  2228.  
  2229.    bit_t b = 0;
  2230.  
  2231.    bit_t attacks = piece_attacks_debug(pc, f);
  2232.  
  2233.    for (bit_t bb = attacks; bb != 0; bb = bit::rest(bb)) {
  2234.       int sq = bit::first(bb);
  2235.       if ((attacks & behind_debug(f, sq)) != 0) {
  2236.          bit::set(b, sq);
  2237.       }
  2238.    }
  2239.  
  2240.    return b;
  2241. }
  2242.  
  2243. void init() {
  2244.  
  2245.    for (int sd = 0; sd < side::SIZE; sd++) {
  2246.       for (int sq = 0; sq < square::SIZE; sq++) {
  2247.          Pawn_Moves[sd][sq] = pawn_moves_debug(sd, sq);
  2248.          Pawn_Attacks[sd][sq] = pawn_attacks_debug(sd, sq);
  2249.       }
  2250.    }
  2251.  
  2252.    for (int pc = piece::KNIGHT; pc <= piece::KING; pc++) {
  2253.       for (int sq = 0; sq < square::SIZE; sq++) {
  2254.          Piece_Attacks[pc][sq] = piece_attacks_debug(pc, sq);
  2255.          Blockers[pc][sq] = blockers_debug(pc, sq);
  2256.       }
  2257.    }
  2258.  
  2259.    for (int f = 0; f < square::SIZE; f++) {
  2260.       for (int t = 0; t < square::SIZE; t++) {
  2261.          Between[f][t] = between_debug(f, t);
  2262.          Behind[f][t]  = behind_debug(f, t);
  2263.       }
  2264.    }
  2265. }
  2266.  
  2267. }
  2268.  
  2269. namespace gen {
  2270.  
  2271. class List {
  2272.  
  2273. private:
  2274.  
  2275.    static const int SIZE = 256;
  2276.  
  2277.    int p_size;
  2278.    uint32 p_pair[SIZE];
  2279.  
  2280.    void move_to(int pf, int pt) {
  2281.  
  2282.       assert(pt <= pf && pf < p_size);
  2283.  
  2284.       uint32 p = p_pair[pf];
  2285.  
  2286.       for (int i = pf; i > pt; i--) {
  2287.          p_pair[i] = p_pair[i - 1];
  2288.       }
  2289.  
  2290.       p_pair[pt] = p;
  2291.    }
  2292.  
  2293.    void add_pair(uint32 p) {
  2294.       assert(p_size < SIZE);
  2295.       p_pair[p_size++] = p;
  2296.    }
  2297.  
  2298.    uint32 pair(int pos) const {
  2299.       assert(pos < p_size);
  2300.       return p_pair[pos];
  2301.    }
  2302.  
  2303. public:
  2304.  
  2305.    List() {
  2306.       clear();
  2307.    }
  2308.  
  2309.    void operator=(const List & ml) {
  2310.  
  2311.       clear();
  2312.  
  2313.       for (int pos = 0; pos < ml.size(); pos++) {
  2314.          uint32 p = ml.pair(pos);
  2315.          add_pair(p);
  2316.       }
  2317.    }
  2318.  
  2319.    void clear() {
  2320.       p_size = 0;
  2321.    }
  2322.  
  2323.    void add(int mv, int sc = 0) {
  2324.       assert(mv >= 0 && mv < move::SIZE);
  2325.       assert(sc >= 0 && sc < move::SCORE_SIZE);
  2326.       assert(!contain(mv));
  2327.       add_pair((sc << move::BITS) | mv);
  2328.    }
  2329.  
  2330.    void set_score(int pos, int sc) {
  2331.       assert(pos < p_size);
  2332.       assert(sc >= 0 && sc < move::SCORE_SIZE);
  2333.       p_pair[pos] = (sc << move::BITS) | move(pos);
  2334.       assert(score(pos) == sc);
  2335.    }
  2336.  
  2337.    void move_to_front(int pos) {
  2338.       move_to(pos, 0);
  2339.    }
  2340.  
  2341.    void sort() { // insertion sort
  2342.  
  2343.       for (int i = 1; i < p_size; i++) {
  2344.  
  2345.          uint32 p = p_pair[i];
  2346.  
  2347.          int j;
  2348.  
  2349.          for (j = i; j > 0 && p_pair[j - 1] < p; j--) {
  2350.             p_pair[j] = p_pair[j - 1];
  2351.          }
  2352.  
  2353.          p_pair[j] = p;
  2354.       }
  2355.  
  2356.       for (int i = 0; i < p_size - 1; i++) {
  2357.          assert(p_pair[i] >= p_pair[i + 1]);
  2358.       }
  2359.    }
  2360.  
  2361.    int size() const {
  2362.       return p_size;
  2363.    }
  2364.  
  2365.    int move(int pos) const {
  2366.       return pair(pos) & move::MASK;
  2367.    }
  2368.  
  2369.    int score(int pos) const {
  2370.       return pair(pos) >> move::BITS;
  2371.    }
  2372.  
  2373.    bool contain(int mv) const {
  2374.  
  2375.       for (int pos = 0; pos < size(); pos++) {
  2376.          if (move(pos) == mv) {
  2377.             return true;
  2378.          }
  2379.       }
  2380.  
  2381.       return false;
  2382.    }
  2383.  
  2384. };
  2385.  
  2386. void add_pawn_move(List & ml, int f, int t, const board::Board & bd) {
  2387.  
  2388.    assert(bd.square(f) == piece::PAWN);
  2389.  
  2390.    int pc = bd.square(f);
  2391.    int cp = bd.square(t);
  2392.  
  2393.    if (square::is_promotion(t)) {
  2394.       ml.add(move::make(f, t, pc, cp, piece::QUEEN));
  2395.       ml.add(move::make(f, t, pc, cp, piece::KNIGHT));
  2396.       ml.add(move::make(f, t, pc, cp, piece::ROOK));
  2397.       ml.add(move::make(f, t, pc, cp, piece::BISHOP));
  2398.    } else {
  2399.       ml.add(move::make(f, t, pc, cp));
  2400.    }
  2401. }
  2402.  
  2403. void add_piece_move(List & ml, int f, int t, const board::Board & bd) {
  2404.    assert(bd.square(f) != piece::PAWN);
  2405.    ml.add(move::make(f, t, bd.square(f), bd.square(t)));
  2406. }
  2407.  
  2408. void add_move(List & ml, int f, int t, const board::Board & bd) {
  2409.    if (bd.square(f) == piece::PAWN) {
  2410.       add_pawn_move(ml, f, t, bd);
  2411.    } else {
  2412.       add_piece_move(ml, f, t, bd);
  2413.    }
  2414. }
  2415.  
  2416. void add_piece_moves_from(List & ml, int f, bit_t ts, const board::Board & bd) {
  2417.  
  2418.    int pc = bd.square(f);
  2419.  
  2420.    for (bit_t b = attack::piece_attacks_from(pc, f, bd) & ts; b != 0; b = bit::rest(b)) {
  2421.       int t = bit::first(b);
  2422.       add_piece_move(ml, f, t, bd);
  2423.    }
  2424. }
  2425.  
  2426. void add_captures_to(List & ml, int sd, int t, const board::Board & bd) {
  2427.  
  2428.    for (int pc = piece::PAWN; pc <= piece::KING; pc++) {
  2429.       for (bit_t b = bd.piece(pc, sd) & attack::attacks_to(pc, sd, t, bd); b != 0; b = bit::rest(b)) {
  2430.          int f = bit::first(b);
  2431.          add_move(ml, f, t, bd);
  2432.       }
  2433.    }
  2434. }
  2435.  
  2436. void add_captures_to_no_king(List & ml, int sd, int t, const board::Board & bd) { // for evasions
  2437.  
  2438.    for (int pc = piece::PAWN; pc <= piece::QUEEN; pc++) { // skip king
  2439.       for (bit_t b = bd.piece(pc, sd) & attack::attacks_to(pc, sd, t, bd); b != 0; b = bit::rest(b)) {
  2440.          int f = bit::first(b);
  2441.          add_move(ml, f, t, bd);
  2442.       }
  2443.    }
  2444. }
  2445.  
  2446. void add_pawn_captures(List & ml, int sd, bit_t ts, const board::Board & bd) {
  2447.  
  2448.    bit_t pawns = bd.piece(piece::PAWN, sd);
  2449.    ts &= bd.side(side::opposit(sd)); // not needed
  2450.  
  2451.    if (sd == side::WHITE) {
  2452.  
  2453.       for (bit_t b = (ts << 7) & pawns; b != 0; b = bit::rest(b)) {
  2454.          int f = bit::first(b);
  2455.          int t = f - 7;
  2456.          add_pawn_move(ml, f, t, bd);
  2457.       }
  2458.  
  2459.       for (bit_t b = (ts >> 9) & pawns; b != 0; b = bit::rest(b)) {
  2460.          int f = bit::first(b);
  2461.          int t = f + 9;
  2462.          add_pawn_move(ml, f, t, bd);
  2463.       }
  2464.  
  2465.    } else {
  2466.  
  2467.       for (bit_t b = (ts << 9) & pawns; b != 0; b = bit::rest(b)) {
  2468.          int f = bit::first(b);
  2469.          int t = f - 9;
  2470.          add_pawn_move(ml, f, t, bd);
  2471.       }
  2472.  
  2473.       for (bit_t b = (ts >> 7) & pawns; b != 0; b = bit::rest(b)) {
  2474.          int f = bit::first(b);
  2475.          int t = f + 7;
  2476.          add_pawn_move(ml, f, t, bd);
  2477.       }
  2478.    }
  2479. }
  2480.  
  2481. void add_promotions(List & ml, int sd, bit_t ts, const board::Board & bd) {
  2482.  
  2483.    bit_t pawns = bd.piece(piece::PAWN, sd);
  2484.  
  2485.    if (sd == side::WHITE) {
  2486.  
  2487.       for (bit_t b = pawns & (ts >> 1) & bit::rank(square::RANK_7); b != 0; b = bit::rest(b)) {
  2488.          int f = bit::first(b);
  2489.          int t = f + 1;
  2490.          assert(bd.square(t) == piece::NONE);
  2491.          assert(square::is_promotion(t));
  2492.          add_pawn_move(ml, f, t, bd);
  2493.       }
  2494.  
  2495.    } else {
  2496.  
  2497.       for (bit_t b = pawns & (ts << 1) & bit::rank(square::RANK_2); b != 0; b = bit::rest(b)) {
  2498.          int f = bit::first(b);
  2499.          int t = f - 1;
  2500.          assert(bd.square(t) == piece::NONE);
  2501.          assert(square::is_promotion(t));
  2502.          add_pawn_move(ml, f, t, bd);
  2503.       }
  2504.    }
  2505. }
  2506.  
  2507. void add_promotions(List & ml, int sd, const board::Board & bd) {
  2508.    add_promotions(ml, sd, bd.empty(), bd);
  2509. }
  2510.  
  2511. void add_pawn_quiets(List & ml, int sd, bit_t ts, const board::Board & bd) {
  2512.  
  2513.    bit_t pawns = bd.piece(piece::PAWN, sd);
  2514.    bit_t empty = bd.empty();
  2515.  
  2516.    if (sd == side::WHITE) {
  2517.  
  2518.       for (bit_t b = pawns & (ts >> 1) & ~bit::rank(square::RANK_7); b != 0; b = bit::rest(b)) { // don't generate promotions
  2519.          int f = bit::first(b);
  2520.          int t = f + 1;
  2521.          assert(bd.square(t) == piece::NONE);
  2522.          assert(!square::is_promotion(t));
  2523.          add_pawn_move(ml, f, t, bd);
  2524.       }
  2525.  
  2526.       for (bit_t b = pawns & (ts >> 2) & (empty >> 1) & bit::rank(square::RANK_2); b != 0; b = bit::rest(b)) {
  2527.          int f = bit::first(b);
  2528.          int t = f + 2;
  2529.          assert(bd.square(t) == piece::NONE);
  2530.          assert(!square::is_promotion(t));
  2531.          add_pawn_move(ml, f, t, bd);
  2532.       }
  2533.  
  2534.    } else {
  2535.  
  2536.       for (bit_t b = pawns & (ts << 1) & ~bit::rank(square::RANK_2); b != 0; b = bit::rest(b)) { // don't generate promotions
  2537.          int f = bit::first(b);
  2538.          int t = f - 1;
  2539.          assert(bd.square(t) == piece::NONE);
  2540.          assert(!square::is_promotion(t));
  2541.          add_pawn_move(ml, f, t, bd);
  2542.       }
  2543.  
  2544.       for (bit_t b = pawns & (ts << 2) & (empty << 1) & bit::rank(square::RANK_7); b != 0; b = bit::rest(b)) {
  2545.          int f = bit::first(b);
  2546.          int t = f - 2;
  2547.          assert(bd.square(t) == piece::NONE);
  2548.          assert(!square::is_promotion(t));
  2549.          add_pawn_move(ml, f, t, bd);
  2550.       }
  2551.    }
  2552. }
  2553.  
  2554. void add_pawn_pushes(List & ml, int sd, const board::Board & bd) {
  2555.  
  2556.    bit_t ts = 0;
  2557.  
  2558.    if (sd == side::WHITE) {
  2559.  
  2560.       ts |= bit::rank(square::RANK_7);
  2561.       ts |= bit::rank(square::RANK_6) & ~attack::pawn_attacks_from(side::BLACK, bd) & (~bd.piece(piece::PAWN) >> 1); // HACK: direct access
  2562.  
  2563.    } else {
  2564.  
  2565.       ts |= bit::rank(square::RANK_2);
  2566.       ts |= bit::rank(square::RANK_3) & ~attack::pawn_attacks_from(side::WHITE, bd) & (~bd.piece(piece::PAWN) << 1); // HACK: direct access
  2567.    }
  2568.  
  2569.    add_pawn_quiets(ml, sd, ts & bd.empty(), bd);
  2570. }
  2571.  
  2572. void add_en_passant(List & ml, int sd, const board::Board & bd) {
  2573.  
  2574.    int t = bd.ep_sq();
  2575.  
  2576.    if (t != square::NONE) {
  2577.  
  2578.       bit_t fs = bd.piece(piece::PAWN, sd) & attack::Pawn_Attacks[side::opposit(sd)][t];
  2579.  
  2580.       for (bit_t b = fs; b != 0; b = bit::rest(b)) {
  2581.          int f = bit::first(b);
  2582.          ml.add(move::make(f, t, piece::PAWN, piece::PAWN));
  2583.       }
  2584.    }
  2585. }
  2586.  
  2587. bool can_castle(int sd, int wg, const board::Board & bd) {
  2588.  
  2589.    int index = castling::index(sd, wg);
  2590.  
  2591.    if (castling::flag(bd.flags(), index)) {
  2592.  
  2593.       int kf = castling::info[index].kf;
  2594.       // int kt = castling::info[index].kt;
  2595.       int rf = castling::info[index].rf;
  2596.       int rt = castling::info[index].rt;
  2597.  
  2598.       assert(bd.square_is(kf, piece::KING, sd));
  2599.       assert(bd.square_is(rf, piece::ROOK, sd));
  2600.  
  2601.       return attack::line_is_empty(kf, rf, bd) && !attack::is_attacked(rt, side::opposit(sd), bd);
  2602.    }
  2603.  
  2604.    return false;
  2605. }
  2606.  
  2607. void add_castling(List & ml, int sd, const board::Board & bd) {
  2608.  
  2609.    for (int wg = 0; wg < wing::SIZE; wg++) {
  2610.       if (can_castle(sd, wg, bd)) {
  2611.          int index = castling::index(sd, wg);
  2612.          add_piece_move(ml, castling::info[index].kf, castling::info[index].kt, bd);
  2613.       }
  2614.    }
  2615. }
  2616.  
  2617. void add_piece_moves(List & ml, int sd, bit_t ts, const board::Board & bd) {
  2618.  
  2619.    assert(ts != 0);
  2620.  
  2621.    for (int pc = piece::KNIGHT; pc <= piece::KING; pc++) {
  2622.       for (bit_t b = bd.piece(pc, sd); b != 0; b = bit::rest(b)) {
  2623.          int f = bit::first(b);
  2624.          add_piece_moves_from(ml, f, ts, bd);
  2625.       }
  2626.    }
  2627. }
  2628.  
  2629. void add_piece_moves_no_king(List & ml, int sd, bit_t ts, const board::Board & bd) { // for evasions
  2630.  
  2631.    assert(ts != 0);
  2632.  
  2633.    for (int pc = piece::KNIGHT; pc <= piece::QUEEN; pc++) { // skip king
  2634.       for (bit_t b = bd.piece(pc, sd); b != 0; b = bit::rest(b)) {
  2635.          int f = bit::first(b);
  2636.          add_piece_moves_from(ml, f, ts, bd);
  2637.       }
  2638.    }
  2639. }
  2640.  
  2641. void add_piece_moves_rare(List & ml, int sd, bit_t ts, const board::Board & bd) { // for captures
  2642.  
  2643.    assert(ts != 0);
  2644.  
  2645.    for (int pc = piece::KNIGHT; pc <= piece::KING; pc++) {
  2646.  
  2647.       for (bit_t b = bd.piece(pc, sd); b != 0; b = bit::rest(b)) {
  2648.  
  2649.          int f = bit::first(b);
  2650.  
  2651.          for (bit_t bb = attack::pseudo_attacks_from(pc, sd, f) & ts; bb != 0; bb = bit::rest(bb)) {
  2652.  
  2653.             int t = bit::first(bb);
  2654.  
  2655.             if (attack::line_is_empty(f, t, bd)) {
  2656.                add_piece_move(ml, f, t, bd);
  2657.             }
  2658.          }
  2659.       }
  2660.    }
  2661. }
  2662.  
  2663. void add_captures(List & ml, int sd, const board::Board & bd) {
  2664.  
  2665.    bit_t ts = bd.side(side::opposit(sd));
  2666.  
  2667.    add_pawn_captures(ml, sd, ts, bd);
  2668.    add_piece_moves_rare(ml, sd, ts, bd);
  2669.    add_en_passant(ml, sd, bd);
  2670. }
  2671.  
  2672. void add_captures_mvv_lva(List & ml, int sd, const board::Board & bd) { // unused
  2673.  
  2674.    for (int pc = piece::QUEEN; pc >= piece::PAWN; pc--) {
  2675.       for (bit_t b = bd.piece(pc, side::opposit(sd)); b != 0; b = bit::rest(b)) {
  2676.          int t = bit::first(b);
  2677.          add_captures_to(ml, sd, t, bd);
  2678.       }
  2679.    }
  2680.  
  2681.    add_en_passant(ml, sd, bd);
  2682. }
  2683.  
  2684. bool is_move(int mv, const board::Board & bd) { // for TT-move legality
  2685.  
  2686.    int sd = bd.turn();
  2687.  
  2688.    int f = move::from(mv);
  2689.    int t = move::to(mv);
  2690.  
  2691.    int pc = move::piece(mv);
  2692.    int cp = move::cap(mv);
  2693.  
  2694.    if (!(bd.square(f) == pc && bd.square_side(f) == sd)) {
  2695.       return false;
  2696.    }
  2697.  
  2698.    if (bd.square(t) != piece::NONE && bd.square_side(t) == sd) {
  2699.       return false;
  2700.    }
  2701.  
  2702.    if (pc == piece::PAWN && t == bd.ep_sq()) {
  2703.       if (cp != piece::PAWN) {
  2704.          return false;
  2705.       }
  2706.    } else if (bd.square(t) != cp) {
  2707.       return false;
  2708.    }
  2709.  
  2710.    if (cp == piece::KING) {
  2711.       return false;
  2712.    }
  2713.  
  2714.    if (pc == piece::PAWN) {
  2715.  
  2716.       // TODO
  2717.  
  2718.       return true;
  2719.  
  2720.    } else {
  2721.  
  2722.       // TODO: castling
  2723.  
  2724.       // return attack::piece_attack(pc, f, t, bd);
  2725.  
  2726.       return true;
  2727.    }
  2728.  
  2729.    assert(false);
  2730. }
  2731.  
  2732. bool is_quiet_move(int mv, const board::Board & bd) { // for killer legality
  2733.  
  2734.    int sd = bd.turn();
  2735.  
  2736.    int f = move::from(mv);
  2737.    int t = move::to(mv);
  2738.  
  2739.    int pc = move::piece(mv);
  2740.    assert(move::cap(mv) == piece::NONE);
  2741.    assert(move::prom(mv) == piece::NONE);
  2742.  
  2743.    if (!(bd.square(f) == pc && bd.square_side(f) == sd)) {
  2744.       return false;
  2745.    }
  2746.  
  2747.    if (bd.square(t) != piece::NONE) {
  2748.       return false;
  2749.    }
  2750.  
  2751.    if (pc == piece::PAWN) {
  2752.  
  2753.       int inc = square::pawn_inc(sd);
  2754.  
  2755.       if (false) {
  2756.       } else if (t - f == inc && !square::is_promotion(t)) {
  2757.          return true;
  2758.       } else if (t - f == inc * 2 && square::rank(f, sd) == square::RANK_2) {
  2759.          return bd.square(f + inc) == piece::NONE;
  2760.       } else {
  2761.          return false;
  2762.       }
  2763.  
  2764.    } else {
  2765.  
  2766.       // TODO: castling
  2767.  
  2768.       return attack::piece_attack(pc, f, t, bd);
  2769.    }
  2770.  
  2771.    assert(false);
  2772. }
  2773.  
  2774. void add_quiets(List & ml, int sd, const board::Board & bd) {
  2775.    add_castling(ml, sd, bd);
  2776.    add_piece_moves(ml, sd, bd.empty(), bd);
  2777.    add_pawn_quiets(ml, sd, bd.empty(), bd);
  2778. }
  2779.  
  2780. void add_evasions(List & ml, int sd, const board::Board & bd, const attack::Attacks & attacks) {
  2781.  
  2782.    assert(attacks.size > 0);
  2783.  
  2784.    int king = bd.king(sd);
  2785.  
  2786.    add_piece_moves_from(ml, king, ~bd.side(sd) & ~attacks.avoid, bd);
  2787.  
  2788.    if (attacks.size == 1) {
  2789.  
  2790.       int t = attacks.square[0];
  2791.  
  2792.       add_captures_to_no_king(ml, sd, t, bd);
  2793.       add_en_passant(ml, sd, bd);
  2794.  
  2795.       bit_t ts = attack::Between[king][t];
  2796.       assert(attack::line_is_empty(king, t, bd));
  2797.  
  2798.       if (ts != 0) {
  2799.          add_pawn_quiets(ml, sd, ts, bd);
  2800.          add_promotions(ml, sd, ts, bd);
  2801.          add_piece_moves_no_king(ml, sd, ts, bd);
  2802.       }
  2803.    }
  2804. }
  2805.  
  2806. void add_evasions(List & ml, int sd, const board::Board & bd) {
  2807.    attack::Attacks attacks;
  2808.    attack::init_attacks(attacks, sd, bd);
  2809.    add_evasions(ml, sd, bd, attacks);
  2810. }
  2811.  
  2812. void add_checks(List & ml, int sd, const board::Board & bd) {
  2813.  
  2814.    int atk = sd;
  2815.    int def = side::opposit(sd);
  2816.  
  2817.    int king = bd.king(def);
  2818.    bit_t pinned = attack::pinned_by(king, atk, bd);
  2819.    bit_t empty = bd.empty();
  2820.    empty &= ~attack::pawn_attacks_from(side::opposit(sd), bd); // pawn-safe
  2821.  
  2822.    // discovered checks
  2823.  
  2824.    for (bit_t fs = bd.pieces(atk) & pinned; fs != 0; fs = bit::rest(fs)) { // TODO: pawns
  2825.       int f = bit::first(fs);
  2826.       bit_t ts = empty & ~attack::ray(king, f); // needed only for pawns
  2827.       add_piece_moves_from(ml, f, ts, bd);
  2828.    }
  2829.  
  2830.    // direct checks, pawns
  2831.  
  2832.    {
  2833.       bit_t ts = attack::pseudo_attacks_to(piece::PAWN, sd, king) & empty;
  2834.  
  2835.       add_pawn_quiets(ml, sd, ts, bd);
  2836.    }
  2837.  
  2838.    // direct checks, knights
  2839.  
  2840.    {
  2841.       int pc = piece::KNIGHT;
  2842.  
  2843.       bit_t attacks = attack::pseudo_attacks_to(pc, sd, king) & empty;
  2844.  
  2845.       for (bit_t b = bd.piece(pc, sd) & ~pinned; b != 0; b = bit::rest(b)) {
  2846.  
  2847.          int f = bit::first(b);
  2848.  
  2849.          bit_t moves = attack::pseudo_attacks_from(pc, sd, f);
  2850.  
  2851.          for (bit_t bb = moves & attacks; bb != 0; bb = bit::rest(bb)) {
  2852.             int t = bit::first(bb);
  2853.             add_piece_move(ml, f, t, bd);
  2854.          }
  2855.       }
  2856.    }
  2857.  
  2858.    // direct checks, sliders
  2859.  
  2860.    for (int pc = piece::BISHOP; pc <= piece::QUEEN; pc++) {
  2861.  
  2862.       bit_t attacks = attack::pseudo_attacks_to(pc, sd, king) & empty;
  2863.  
  2864.       for (bit_t b = bd.piece(pc, sd) & ~pinned; b != 0; b = bit::rest(b)) {
  2865.  
  2866.          int f = bit::first(b);
  2867.  
  2868.          bit_t moves = attack::pseudo_attacks_from(pc, sd, f);
  2869.  
  2870.          for (bit_t bb = moves & attacks; bb != 0; bb = bit::rest(bb)) {
  2871.  
  2872.             int t = bit::first(bb);
  2873.  
  2874.             if (attack::line_is_empty(f, t, bd) && attack::line_is_empty(t, king, bd)) {
  2875.                add_piece_move(ml, f, t, bd);
  2876.             }
  2877.          }
  2878.       }
  2879.    }
  2880. }
  2881.  
  2882. bool is_legal_debug(int mv, board::Board & bd) { // HACK: duplicate from Move_Type
  2883.  
  2884.    bd.move(mv);
  2885.    bool b = attack::is_legal(bd);
  2886.    bd.undo();
  2887.  
  2888.    return b;
  2889. }
  2890.  
  2891. void gen_moves_debug(List & ml, const board::Board & bd) {
  2892.  
  2893.    ml.clear();
  2894.  
  2895.    int sd = bd.turn();
  2896.  
  2897.    if (attack::is_in_check(bd)) {
  2898.       add_evasions(ml, sd, bd);
  2899.    } else {
  2900.       add_captures(ml, sd, bd);
  2901.       add_promotions(ml, sd, bd);
  2902.       add_quiets(ml, sd, bd);
  2903.    }
  2904. }
  2905.  
  2906. void filter_legals(List & dst, const List & src, board::Board & bd) {
  2907.  
  2908.    dst.clear();
  2909.  
  2910.    for (int pos = 0; pos < src.size(); pos++) {
  2911.  
  2912.       int mv = src.move(pos);
  2913.  
  2914.       if (is_legal_debug(mv, bd)) {
  2915.          dst.add(mv);
  2916.       }
  2917.    }
  2918. }
  2919.  
  2920. void gen_legals(List & ml, board::Board & bd) {
  2921.  
  2922.    List pseudos;
  2923.    gen_moves_debug(pseudos, bd);
  2924.  
  2925.    filter_legals(ml, pseudos, bd);
  2926. }
  2927.  
  2928. void gen_legal_evasions(List & ml, board::Board & bd) {
  2929.  
  2930.    int sd = bd.turn();
  2931.  
  2932.    attack::Attacks attacks;
  2933.    attack::init_attacks(attacks, sd, bd);
  2934.  
  2935.    if (attacks.size == 0) {
  2936.       ml.clear();
  2937.       return;
  2938.    }
  2939.  
  2940.    List pseudos;
  2941.    add_evasions(pseudos, sd, bd, attacks);
  2942.  
  2943.    filter_legals(ml, pseudos, bd);
  2944. }
  2945.  
  2946. }
  2947.  
  2948. namespace score {
  2949.  
  2950. enum {
  2951.    NONE     = -10000,
  2952.    MIN      =  -9999,
  2953.    EVAL_MIN =  -8999,
  2954.    EVAL_MAX =  +8999,
  2955.    MAX      =  +9999,
  2956.    MATE     = +10000,
  2957. };
  2958.  
  2959. enum {
  2960.    FLAGS_NONE  = 0,
  2961.    FLAGS_LOWER = 1 << 0,
  2962.    FLAGS_UPPER = 1 << 1,
  2963.    FLAGS_EXACT = FLAGS_LOWER | FLAGS_UPPER,
  2964. };
  2965.  
  2966. bool is_mate(int sc) {
  2967.    return sc < EVAL_MIN || sc > EVAL_MAX;
  2968. }
  2969.  
  2970. int signed_mate(int sc) {
  2971.    if (sc < EVAL_MIN) { // -MATE
  2972.       return -(MATE + sc) / 2;
  2973.    } else if (sc > EVAL_MAX) { // +MATE
  2974.       return (MATE - sc + 1) / 2;
  2975.    } else {
  2976.       assert(false);
  2977.       return 0;
  2978.    }
  2979. }
  2980.  
  2981. int side_score(int sc, int sd) {
  2982.    return (sd == side::WHITE) ? +sc : -sc;
  2983. }
  2984.  
  2985. int from_trans(int sc, int ply) {
  2986.    if (sc < EVAL_MIN) {
  2987.       return sc + ply;
  2988.    } else if (sc > EVAL_MAX) {
  2989.       return sc - ply;
  2990.    } else {
  2991.       return sc;
  2992.    }
  2993. }
  2994.  
  2995. int to_trans(int sc, int ply) {
  2996.    if (sc < EVAL_MIN) {
  2997.       return sc - ply;
  2998.    } else if (sc > EVAL_MAX) {
  2999.       return sc + ply;
  3000.    } else {
  3001.       return sc;
  3002.    }
  3003. }
  3004.  
  3005. int flags(int sc, int alpha, int beta) {
  3006.  
  3007.    int flags = FLAGS_NONE;
  3008.    if (sc > alpha) flags |= FLAGS_LOWER;
  3009.    if (sc < beta)  flags |= FLAGS_UPPER;
  3010.  
  3011.    return flags;
  3012. }
  3013.  
  3014. }
  3015.  
  3016. namespace trans {
  3017.  
  3018. struct Entry { // 16 bytes
  3019.    uint32 lock;
  3020.    uint32 move; // TODO: uint16 #
  3021.    uint16 pad_1;
  3022.    int16 score;
  3023.    uint8 date;
  3024.    int8 depth;
  3025.    uint8 flags;
  3026.    uint8 pad_2;
  3027. };
  3028.  
  3029. void clear_entry(Entry & entry) {
  3030.  
  3031.    assert(sizeof(Entry) == 16);
  3032.  
  3033.    entry.lock = 0;
  3034.    entry.move = move::NONE;
  3035.    entry.pad_1 = 0;
  3036.    entry.score = 0;
  3037.    entry.date = 0;
  3038.    entry.depth = -1;
  3039.    entry.flags = score::FLAGS_NONE;
  3040.    entry.pad_2 = 0;
  3041. }
  3042.  
  3043. class Table {
  3044.  
  3045. private:
  3046.  
  3047.    Entry * p_table;
  3048.    int p_bits;
  3049.    uint64 p_size;
  3050.    uint64 p_mask;
  3051.  
  3052.    int p_date;
  3053.    uint64 p_used;
  3054.  
  3055.    int size_to_bits(int size) {
  3056.  
  3057.       int bits = 0;
  3058.  
  3059.       for (uint64 entries = (uint64(size) << 20) / sizeof(Entry); entries > 1; entries /= 2) {
  3060.          bits++;
  3061.       }
  3062.  
  3063.       return bits;
  3064.    }
  3065.  
  3066. public:
  3067.  
  3068.    Table() {
  3069.  
  3070.       p_table = NULL;
  3071.       p_bits = 0;
  3072.       p_size = 1;
  3073.       p_mask = 0;
  3074.  
  3075.       p_date = 0;
  3076.       p_used = 0;
  3077.    }
  3078.  
  3079.    void set_size(int size) {
  3080.  
  3081.       int bits = size_to_bits(size);
  3082.       if (bits == p_bits) return;
  3083.  
  3084.       p_bits = bits;
  3085.       p_size = U64(1) << bits;
  3086.       p_mask = p_size - 1;
  3087.  
  3088.       if (p_table != NULL) {
  3089.          free();
  3090.          alloc();
  3091.       }
  3092.    }
  3093.  
  3094.    void alloc() {
  3095.       assert(p_table == NULL);
  3096.       p_table = new Entry[(unsigned int) p_size]; // Pierre-Marie Baty -- added type cast
  3097.       clear();
  3098.    }
  3099.  
  3100.    void free() {
  3101.       assert(p_table != NULL);
  3102.       delete [] p_table;
  3103.       p_table = NULL;
  3104.    }
  3105.  
  3106.    void clear() {
  3107.  
  3108.       Entry e;
  3109.       clear_entry(e);
  3110.  
  3111.       for (uint64 i = 0; i < p_size; i++) {
  3112.          p_table[i] = e;
  3113.       }
  3114.  
  3115.       p_date = 1;
  3116.       p_used = 0;
  3117.    }
  3118.  
  3119.    void inc_date() {
  3120.       p_date = (p_date + 1) % 256;
  3121.       p_used = 0;
  3122.    }
  3123.  
  3124.    void store(hash_t key, int depth, int ply, int move, int score, int flags) {
  3125.  
  3126.       assert(depth >= 0 && depth < 100);
  3127.       assert(move != move::NULL_);
  3128.       assert(score >= score::MIN && score <= score::MAX);
  3129.  
  3130.       score = score::to_trans(score, ply);
  3131.  
  3132.       uint64 index = hash::index(key) & p_mask;
  3133.       uint32 lock  = hash::lock(key);
  3134.  
  3135.       Entry * be = NULL;
  3136.       int bs = -1;
  3137.  
  3138.       for (uint64 i = 0; i < 4; i++) {
  3139.  
  3140.          uint64 idx = (index + i) & p_mask;
  3141.          assert(idx < p_size);
  3142.          Entry & entry = p_table[idx];
  3143.  
  3144.          if (entry.lock == lock) {
  3145.  
  3146.             if (entry.date != p_date) {
  3147.                entry.date = p_date;
  3148.                p_used++;
  3149.             }
  3150.  
  3151.             if (depth >= entry.depth) {
  3152.                if (move != move::NONE) entry.move = move;
  3153.                entry.depth = depth;
  3154.                entry.score = score;
  3155.                entry.flags = flags;
  3156.             } else if (entry.move == move::NONE) {
  3157.                entry.move = move;
  3158.             }
  3159.  
  3160.             return;
  3161.          }
  3162.  
  3163.          int sc = 99 - entry.depth; // NOTE: entry.depth can be -1
  3164.          if (entry.date != p_date) sc += 101;
  3165.          assert(sc >= 0 && sc < 202);
  3166.  
  3167.          if (sc > bs) {
  3168.             be = &entry;
  3169.             bs = sc;
  3170.          }
  3171.       }
  3172.  
  3173.       assert(be != NULL);
  3174.  
  3175.       if (be->date != p_date) p_used++;
  3176.  
  3177.       be->lock = lock;
  3178.       be->date = p_date;
  3179.       be->move = move;
  3180.       be->depth = depth;
  3181.       be->score = score;
  3182.       be->flags = flags;
  3183.    }
  3184.  
  3185.    bool retrieve(hash_t key, int depth, int ply, int & move, int & score, int & flags) {
  3186.  
  3187.       assert(depth >= 0 && depth < 100);
  3188.  
  3189.       uint64 index = hash::index(key) & p_mask;
  3190.       uint32 lock  = hash::lock(key);
  3191.  
  3192.       for (uint64 i = 0; i < 4; i++) {
  3193.  
  3194.          uint64 idx = (index + i) & p_mask;
  3195.          assert(idx < p_size);
  3196.          Entry & entry = p_table[idx];
  3197.  
  3198.          if (entry.lock == lock) {
  3199.  
  3200.             if (entry.date != p_date) {
  3201.                entry.date = p_date; // touch entry
  3202.                p_used++;
  3203.             }
  3204.  
  3205.             move = entry.move;
  3206.             score = score::from_trans(entry.score, ply);
  3207.             flags = entry.flags;
  3208.  
  3209.             if (entry.depth >= depth) {
  3210.                return true;
  3211.             } else if (score::is_mate(score)) {
  3212.                flags &= ~(score < 0 ? score::FLAGS_LOWER : score::FLAGS_UPPER);
  3213.                return true;
  3214.             }
  3215.  
  3216.             return false;
  3217.          }
  3218.       }
  3219.  
  3220.       return false;
  3221.    }
  3222.  
  3223.    int used() const {
  3224.       return int((p_used * 1000 + p_size / 2) / p_size);
  3225.    }
  3226.  
  3227. };
  3228.  
  3229. }
  3230.  
  3231. namespace engine {
  3232.  
  3233. struct Engine {
  3234.    int hash;
  3235.    bool ponder;
  3236.    int threads;
  3237.    bool log;
  3238. };
  3239.  
  3240. Engine engine;
  3241.  
  3242. void init() {
  3243.    engine.hash = 64;
  3244.    engine.ponder = false;
  3245.    engine.threads = 1;
  3246.    engine.log = false;
  3247. }
  3248.  
  3249. }
  3250.  
  3251. namespace pawn { // HACK: early declaration for pawn-pushes move type
  3252.  
  3253. bit_t passed_me[square::SIZE][side::SIZE];
  3254. bit_t passed_opp[square::SIZE][side::SIZE];
  3255.  
  3256. bool is_passed(int sq, int sd, const board::Board & bd) {
  3257.    return (bd.piece(piece::PAWN, side::opposit(sd)) & passed_opp[sq][sd]) == 0
  3258.        && (bd.piece(piece::PAWN, sd) & passed_me[sq][sd]) == 0;
  3259. }
  3260.  
  3261. int square_distance(int ks, int ps, int sd) {
  3262.    int prom = square::promotion(ps, sd);
  3263.    return square::distance(ks, prom) - square::distance(ps, prom);
  3264. }
  3265.  
  3266. }
  3267.  
  3268. namespace move {
  3269.  
  3270. bool is_win (int mv, const board::Board & bd);
  3271.  
  3272. class SEE {
  3273.  
  3274. private:
  3275.  
  3276.    const board::Board * p_board;
  3277.    int p_to;
  3278.    bit_t p_all;
  3279.  
  3280.    int p_val;
  3281.    int p_side;
  3282.  
  3283.    void init(int t, int sd) {
  3284.  
  3285.       p_to = t;
  3286.       p_all = p_board->all();
  3287.  
  3288.       int pc = p_board->square(t);
  3289.  
  3290.       p_val = piece::value(pc);
  3291.       p_side = sd;
  3292.    }
  3293.  
  3294.    int move(int f) {
  3295.  
  3296.       assert(bit::is_set(p_all, f));
  3297.       bit::clear(p_all, f);
  3298.  
  3299.       int pc = p_board->square(f);
  3300.       assert(pc != piece::NONE && p_board->square_side(f) == p_side);
  3301.  
  3302.       int val = p_val;
  3303.       p_val = piece::value(pc);
  3304.  
  3305.       if (pc == piece::PAWN && square::is_promotion(p_to)) {
  3306.          int delta = piece::QUEEN_VALUE - piece::PAWN_VALUE;
  3307.          val   += delta;
  3308.          p_val += delta;
  3309.       }
  3310.  
  3311.       if (val == piece::KING_VALUE) { // stop at king capture
  3312.          p_all = 0; // HACK: erase all attackers
  3313.       }
  3314.  
  3315.       p_side = side::opposit(p_side);
  3316.  
  3317.       return val;
  3318.    }
  3319.  
  3320.    int see_rec(int alpha, int beta) {
  3321.  
  3322.       assert(alpha < beta);
  3323.  
  3324.       int s0 = 0;
  3325.  
  3326.       if (s0 > alpha) {
  3327.          alpha = s0;
  3328.          if (s0 >= beta) return s0;
  3329.       }
  3330.  
  3331.       if (p_val <= alpha) { // FP, NOTE: fails for promotions
  3332.          return p_val;
  3333.       }
  3334.  
  3335.       int f = pick_lva();
  3336.  
  3337.       if (f == square::NONE) {
  3338.          return s0;
  3339.       }
  3340.  
  3341.       int cap = move(f); // NOTE: has side effect
  3342.       int s1 = cap - see_rec(cap - beta, cap - alpha);
  3343.  
  3344.       return std::max(s0, s1);
  3345.    }
  3346.  
  3347.    int pick_lva() const {
  3348.  
  3349.       int sd = p_side;
  3350.  
  3351.       for (int pc = piece::PAWN; pc <= piece::KING; pc++) {
  3352.  
  3353.          bit_t fs = p_board->piece(pc, sd) & attack::pseudo_attacks_to(pc, sd, p_to) & p_all;
  3354.  
  3355.          for (bit_t b = fs; b != 0; b = bit::rest(b)) {
  3356.  
  3357.             int f = bit::first(b);
  3358.  
  3359.             if ((p_all & attack::Between[f][p_to]) == 0) {
  3360.                return f;
  3361.             }
  3362.          }
  3363.       }
  3364.  
  3365.       return square::NONE;
  3366.    }
  3367.  
  3368. public:
  3369.  
  3370.    int see(int mv, int alpha, int beta, const board::Board & bd) {
  3371.  
  3372.       assert(alpha < beta);
  3373.  
  3374.       p_board = &bd;
  3375.  
  3376.       int f = from(mv);
  3377.       int t = to(mv);
  3378.  
  3379.       int pc = p_board->square(f);
  3380.       int sd = p_board->square_side(f);
  3381.  
  3382.       init(t, sd);
  3383.       int cap = move(f); // NOTE: assumes queen promotion
  3384.  
  3385.       if (pc == piece::PAWN && square::is_promotion(t)) { // adjust for under-promotion
  3386.          int delta = piece::QUEEN_VALUE - piece::value(prom(mv));
  3387.          cap   -= delta;
  3388.          p_val -= delta;
  3389.       }
  3390.  
  3391.       return cap - see_rec(cap - beta, cap - alpha);
  3392.    }
  3393.  
  3394. };
  3395.  
  3396. bool is_capture(int mv) {
  3397.    return cap(mv) != piece::NONE;
  3398. }
  3399.  
  3400. bool is_en_passant(int mv, const board::Board & bd) {
  3401.    return piece(mv) == piece::PAWN && to(mv) == bd.ep_sq();
  3402. }
  3403.  
  3404. bool is_recapture(int mv, const board::Board & bd) {
  3405.    return to(mv) == bd.recap() && is_win(mv, bd);
  3406. }
  3407.  
  3408. bool is_promotion(int mv) {
  3409.    return prom(mv) != piece::NONE;
  3410. }
  3411.  
  3412. bool is_queen_promotion(int mv) {
  3413.    return prom(mv) == piece::QUEEN;
  3414. }
  3415.  
  3416. bool is_under_promotion(int mv) {
  3417.    int pp = prom(mv);
  3418.    return pp != piece::NONE && pp != piece::QUEEN;
  3419. }
  3420.  
  3421. bool is_tactical(int mv) {
  3422.    return is_capture(mv) || is_promotion(mv);
  3423. }
  3424.  
  3425. bool is_pawn_push(int mv, const board::Board & bd) {
  3426.  
  3427.    if (is_tactical(mv)) {
  3428.       return false;
  3429.    }
  3430.  
  3431.    int f = from(mv);
  3432.    int t = to(mv);
  3433.  
  3434.    int pc = bd.square(f);
  3435.    int sd = bd.square_side(f);
  3436.  
  3437.    return pc == piece::PAWN && square::rank(t, sd) >= square::RANK_6 && pawn::is_passed(t, sd, bd) && !is_capture(mv);
  3438. }
  3439.  
  3440. bool is_castling(int mv) {
  3441.    return piece(mv) == piece::KING && std::abs(to(mv) - from(mv)) == square::CASTLING_DELTA;
  3442. }
  3443.  
  3444. bool is_conversion(int mv) {
  3445.    return is_capture(mv) || piece(mv) == piece::PAWN || is_castling(mv);
  3446. }
  3447.  
  3448. int make(int f, int t, int pp, const board::Board & bd) {
  3449.  
  3450.    int pc = bd.square(f);
  3451.    int cp = bd.square(t);
  3452.  
  3453.    if (pc == piece::PAWN && t == bd.ep_sq()) {
  3454.       cp = piece::PAWN;
  3455.    }
  3456.  
  3457.    if (pc == piece::PAWN && square::is_promotion(t) && pp == piece::NONE) { // not needed
  3458.       pp = piece::QUEEN;
  3459.    }
  3460.  
  3461.    return make(f, t, pc, cp, pp);
  3462. }
  3463.  
  3464. int from_string(const std::string & s, const board::Board & bd) {
  3465.  
  3466.    assert(s.length() >= 4);
  3467.  
  3468.    int f = square::from_string(s.substr(0, 2));
  3469.    int t = square::from_string(s.substr(2, 2));
  3470.    int pp = (s.length() > 4) ? piece::from_char(std::toupper(s[4])) : piece::NONE;
  3471.  
  3472.    return make(f, t, pp, bd);
  3473. }
  3474.  
  3475. int see(int mv, int alpha, int beta, const board::Board & bd) {
  3476.    SEE see;
  3477.    return see.see(mv, alpha, beta, bd);
  3478. }
  3479.  
  3480. int see_max(int mv) {
  3481.  
  3482.    assert(is_tactical(mv));
  3483.  
  3484.    int sc = piece::value(cap(mv));
  3485.  
  3486.    int pp = prom(mv);
  3487.    if (pp != piece::NONE) sc += piece::value(pp) - piece::PAWN_VALUE;
  3488.  
  3489.    return sc;
  3490. }
  3491.  
  3492. bool is_safe(int mv, const board::Board & bd) {
  3493.  
  3494.    int pc = piece(mv);
  3495.    int cp = cap(mv);
  3496.    int pp = prom(mv);
  3497.  
  3498.    if (false) {
  3499.    } else if (pc == piece::KING) {
  3500.       return true;
  3501.    } else if (piece::value(cp) >= piece::value(pc)) {
  3502.       return true;
  3503.    } else if (pp != piece::NONE && pp != piece::QUEEN) { // under-promotion
  3504.       return false;
  3505.    } else {
  3506.       return see(mv, -1, 0, bd) >= 0;
  3507.    }
  3508. }
  3509.  
  3510. bool is_win(int mv, const board::Board & bd) {
  3511.  
  3512.    assert(is_tactical(mv));
  3513.  
  3514.    int pc = piece(mv);
  3515.    int cp = cap(mv);
  3516.    int pp = prom(mv);
  3517.  
  3518.    if (false) {
  3519.    } else if (pc == piece::KING) {
  3520.       return true;
  3521.    } else if (piece::value(cp) > piece::value(pc)) {
  3522.       return true;
  3523.    } else if (pp != piece::NONE && pp != piece::QUEEN) { // under-promotion
  3524.       return false;
  3525.    } else {
  3526.       return see(mv, 0, +1, bd) > 0;
  3527.    }
  3528. }
  3529.  
  3530. bool is_legal_debug(int mv, board::Board & bd) {
  3531.  
  3532.    bd.move(mv);
  3533.    bool b = attack::is_legal(bd);
  3534.    bd.undo();
  3535.  
  3536.    return b;
  3537. }
  3538.  
  3539. bool is_legal(int mv, board::Board & bd, const attack::Attacks & attacks) {
  3540.  
  3541.    int sd = bd.turn();
  3542.  
  3543.    int f = from(mv);
  3544.    int t = to(mv);
  3545.  
  3546.    if (is_en_passant(mv, bd)) {
  3547.       return is_legal_debug(mv, bd);
  3548.    }
  3549.  
  3550.    if (piece(mv) == piece::KING) {
  3551.       return !attack::is_attacked(t, side::opposit(sd), bd);
  3552.    }
  3553.  
  3554.    if (!bit::is_set(attacks.pinned, f)) {
  3555.       return true;
  3556.    }
  3557.  
  3558.    if (bit::is_set(attack::ray(bd.king(sd), f), t)) {
  3559.       return true;
  3560.    }
  3561.  
  3562.    return false;
  3563. }
  3564.  
  3565. bool is_check_debug(int mv, board::Board & bd) {
  3566.  
  3567.    bd.move(mv);
  3568.    bool b = attack::is_in_check(bd);
  3569.    bd.undo();
  3570.  
  3571.    return b;
  3572. }
  3573.  
  3574. bool is_check(int mv, board::Board & bd) {
  3575.  
  3576.    if (is_promotion(mv) || is_en_passant(mv, bd) || is_castling(mv)) {
  3577.       return is_check_debug(mv, bd);
  3578.    }
  3579.  
  3580.    int f = from(mv);
  3581.    int t = to(mv);
  3582.  
  3583.    int pc = (prom(mv) != piece::NONE) ? prom(mv) : piece(mv);
  3584.    int sd = bd.square_side(f);
  3585.  
  3586.    int king = bd.king(side::opposit(sd));
  3587.  
  3588.    if (attack::attack(pc, sd, t, king, bd)) {
  3589.       return true;
  3590.    }
  3591.  
  3592.    if (attack::attack_behind(king, f, sd, bd) && !bit::is_set(attack::ray(king, f), t)) {
  3593.       return true;
  3594.    }
  3595.  
  3596.    return false;
  3597. }
  3598.  
  3599. }
  3600.  
  3601. namespace sort {
  3602.  
  3603. class Killer {
  3604.  
  3605. private:
  3606.  
  3607.    static const int PLY = 100;
  3608.  
  3609.    struct List {
  3610.       int k0;
  3611.       int k1;
  3612.    };
  3613.  
  3614.    List p_killer[PLY];
  3615.  
  3616. public:
  3617.  
  3618.    void clear() {
  3619.       for (int ply = 0; ply < PLY; ply++) {
  3620.          p_killer[ply].k0 = move::NONE;
  3621.          p_killer[ply].k1 = move::NONE;
  3622.       }
  3623.    }
  3624.  
  3625.    void add(int mv, int ply) {
  3626.       if (p_killer[ply].k0 != mv) {
  3627.          p_killer[ply].k1 = p_killer[ply].k0;
  3628.          p_killer[ply].k0 = mv;
  3629.       }
  3630.    }
  3631.  
  3632.    int killer_0(int ply) const {
  3633.       return p_killer[ply].k0;
  3634.    }
  3635.  
  3636.    int killer_1(int ply) const {
  3637.       return p_killer[ply].k1;
  3638.    }
  3639.  
  3640. };
  3641.  
  3642. class History {
  3643.  
  3644. private:
  3645.  
  3646.    static const int PROB_BIT   = 11;
  3647.    static const int PROB_ONE   = 1 << PROB_BIT;
  3648.    static const int PROB_HALF  = 1 << (PROB_BIT - 1);
  3649.    static const int PROB_SHIFT = 5;
  3650.  
  3651.    int p_prob[piece::SIDE_SIZE * square::SIZE];
  3652.  
  3653.    static int index(int mv, const board::Board & bd) {
  3654.  
  3655.       assert(!move::is_tactical(mv));
  3656.  
  3657.       int sd = bd.square_side(move::from(mv));
  3658.       int p12 = piece::make(move::piece(mv), sd);
  3659.  
  3660.       int idx = p12 * square::SIZE + move::to(mv);
  3661.       assert(idx < piece::SIDE_SIZE * square::SIZE);
  3662.  
  3663.       return idx;
  3664.    }
  3665.  
  3666.    void update_good(int mv, const board::Board & bd) {
  3667.       if (!move::is_tactical(mv)) {
  3668.          int idx = index(mv, bd);
  3669.          p_prob[idx] += (PROB_ONE - p_prob[idx]) >> PROB_SHIFT;
  3670.       }
  3671.    }
  3672.  
  3673.    void update_bad(int mv, const board::Board & bd) {
  3674.       if (!move::is_tactical(mv)) {
  3675.          int idx = index(mv, bd);
  3676.          p_prob[idx] -= p_prob[idx] >> PROB_SHIFT;
  3677.       }
  3678.    }
  3679.  
  3680. public:
  3681.  
  3682.    void clear() {
  3683.       for (int idx = 0; idx < piece::SIDE_SIZE * square::SIZE; idx++) {
  3684.          p_prob[idx] = PROB_HALF;
  3685.       }
  3686.    }
  3687.  
  3688.    void add(int bm, const gen::List & searched, const board::Board & bd) {
  3689.  
  3690.       assert(bm != move::NONE);
  3691.  
  3692.       update_good(bm, bd);
  3693.  
  3694.       for (int pos = 0; pos < searched.size(); pos++) {
  3695.          int mv = searched.move(pos);
  3696.          if (mv != bm) update_bad(mv, bd);
  3697.       }
  3698.    }
  3699.  
  3700.    int score(int mv, const board::Board & bd) const {
  3701.       int idx = index(mv, bd);
  3702.       return p_prob[idx];
  3703.    }
  3704.  
  3705. };
  3706.  
  3707. int capture_score_debug(int pc, int cp) {
  3708.    int sc = piece::score(cp) * 6 + (5 - piece::score(pc));
  3709.    assert(sc >= 0 && sc < 36);
  3710.    return sc;
  3711. }
  3712.  
  3713. int promotion_score_debug(int pp) {
  3714.    switch (pp) {
  3715.    case piece::QUEEN:
  3716.       return 3;
  3717.    case piece::KNIGHT:
  3718.       return 2;
  3719.    case piece::ROOK:
  3720.       return 1;
  3721.    case piece::BISHOP:
  3722.       return 0;
  3723.    default:
  3724.       assert(false);
  3725.       return 0;
  3726.    }
  3727. }
  3728.  
  3729. int tactical_score_debug(int pc, int cp, int pp) {
  3730.  
  3731.    int sc;
  3732.  
  3733.    if (cp != piece::NONE) {
  3734.       sc = capture_score_debug(pc, cp) + 4;
  3735.    } else {
  3736.       sc = promotion_score_debug(pp);
  3737.    }
  3738.  
  3739.    assert(sc >= 0 && sc < 40);
  3740.    return sc;
  3741. }
  3742.  
  3743. int capture_score(int mv) {
  3744.    assert(move::is_capture(mv));
  3745.    return capture_score_debug(move::piece(mv), move::cap(mv));
  3746. }
  3747.  
  3748. int promotion_score(int mv) {
  3749.    assert(move::is_promotion(mv) && !move::is_capture(mv));
  3750.    return promotion_score_debug(move::prom(mv));
  3751. }
  3752.  
  3753. int tactical_score(int mv) {
  3754.    assert(move::is_tactical(mv));
  3755.    return tactical_score_debug(move::piece(mv), move::cap(mv), move::prom(mv));
  3756. }
  3757.  
  3758. int evasion_score(int mv, int trans_move) {
  3759.  
  3760.    int sc;
  3761.  
  3762.    if (false) {
  3763.    } else if (mv == trans_move) {
  3764.       sc = move::SCORE_MASK;
  3765.    } else if (move::is_tactical(mv)) {
  3766.       sc = tactical_score(mv) + 1;
  3767.       assert (sc >= 1 && sc < 41);
  3768.    } else {
  3769.       sc = 0;
  3770.    }
  3771.  
  3772.    return sc;
  3773. }
  3774.  
  3775. void sort_tacticals(gen::List & ml) {
  3776.  
  3777.    for (int pos = 0; pos < ml.size(); pos++) {
  3778.       int mv = ml.move(pos);
  3779.       int sc = tactical_score(mv);
  3780.       ml.set_score(pos, sc);
  3781.    }
  3782.  
  3783.    ml.sort();
  3784. }
  3785.  
  3786. void sort_history(gen::List & ml, const board::Board & bd, const History & history) {
  3787.  
  3788.    for (int pos = 0; pos < ml.size(); pos++) {
  3789.       int mv = ml.move(pos);
  3790.       int sc = history.score(mv, bd);
  3791.       ml.set_score(pos, sc);
  3792.    }
  3793.  
  3794.    ml.sort();
  3795. }
  3796.  
  3797. void sort_evasions(gen::List & ml, int trans_move) {
  3798.  
  3799.    for (int pos = 0; pos < ml.size(); pos++) {
  3800.       int mv = ml.move(pos);
  3801.       int sc = evasion_score(mv, trans_move);
  3802.       ml.set_score(pos, sc);
  3803.    }
  3804.  
  3805.    ml.sort();
  3806. }
  3807.  
  3808. }
  3809.  
  3810. namespace gen_sort {
  3811.  
  3812. // HACK: outside of List class because of C++ "static const" limitations :(
  3813.  
  3814. enum Inst {
  3815.    GEN_EVASION,
  3816.    GEN_TRANS,
  3817.    GEN_TACTICAL,
  3818.    GEN_KILLER,
  3819.    GEN_CHECK,
  3820.    GEN_PAWN,
  3821.    GEN_QUIET,
  3822.    GEN_BAD,
  3823.    GEN_END,
  3824.    POST_MOVE,
  3825.    POST_MOVE_SEE,
  3826.    POST_KILLER,
  3827.    POST_KILLER_SEE,
  3828.    POST_BAD,
  3829. };
  3830.  
  3831. const Inst Prog_Main[]    = { GEN_TRANS, POST_KILLER, GEN_TACTICAL, POST_MOVE_SEE, GEN_KILLER, POST_KILLER_SEE, GEN_QUIET, POST_MOVE_SEE, GEN_BAD, POST_BAD, GEN_END };
  3832. const Inst Prog_QS_Root[] = { GEN_TRANS, POST_KILLER, GEN_TACTICAL, POST_MOVE, GEN_CHECK, POST_KILLER, GEN_PAWN, POST_MOVE, GEN_END };
  3833. const Inst Prog_QS[]      = { GEN_TRANS, POST_KILLER, GEN_TACTICAL, POST_MOVE, GEN_END };
  3834. const Inst Prog_Evasion[] = { GEN_EVASION, POST_MOVE_SEE, GEN_BAD, POST_BAD, GEN_END };
  3835.  
  3836. class List {
  3837.  
  3838. private:
  3839.  
  3840.    board::Board * p_board;
  3841.    const attack::Attacks * p_attacks;
  3842.    const sort::Killer * p_killer;
  3843.    const sort::History * p_hist;
  3844.    int p_trans_move;
  3845.  
  3846.    const Inst * p_ip;
  3847.    Inst p_gen;
  3848.    Inst p_post;
  3849.  
  3850.    gen::List p_todo;
  3851.    gen::List p_done;
  3852.    gen::List p_bad;
  3853.  
  3854.    int p_pos;
  3855.    bool p_candidate;
  3856.  
  3857.    bool gen() {
  3858.  
  3859.       p_todo.clear();
  3860.       p_pos = 0;
  3861.  
  3862.       switch (p_gen) { {
  3863.  
  3864.       } case GEN_EVASION: {
  3865.  
  3866.          gen::add_evasions(p_todo, p_board->turn(), *p_board, *p_attacks);
  3867.          sort::sort_evasions(p_todo, p_trans_move);
  3868.          break;
  3869.  
  3870.       } case GEN_TRANS: {
  3871.  
  3872.          int mv = p_trans_move;
  3873.  
  3874.          if (mv != move::NONE && gen::is_move(mv, *p_board)) {
  3875.             p_todo.add(mv);
  3876.          }
  3877.  
  3878.          p_candidate = true;
  3879.  
  3880.          break;
  3881.  
  3882.       } case GEN_TACTICAL: {
  3883.  
  3884.          gen::add_captures(p_todo, p_board->turn(), *p_board);
  3885.          gen::add_promotions(p_todo, p_board->turn(), *p_board);
  3886.          sort::sort_tacticals(p_todo);
  3887.  
  3888.          p_candidate = true;
  3889.  
  3890.          break;
  3891.  
  3892.       } case GEN_KILLER: {
  3893.  
  3894.          int k0 = p_killer->killer_0(p_board->ply());
  3895.  
  3896.          if (k0 != move::NONE && gen::is_quiet_move(k0, *p_board)) {
  3897.             p_todo.add(k0);
  3898.          }
  3899.  
  3900.          int k1 = p_killer->killer_1(p_board->ply());
  3901.  
  3902.          if (k1 != move::NONE && gen::is_quiet_move(k1, *p_board)) {
  3903.             p_todo.add(k1);
  3904.          }
  3905.  
  3906.          p_candidate = true;
  3907.  
  3908.          break;
  3909.  
  3910.       } case GEN_CHECK: {
  3911.  
  3912.          gen::add_checks(p_todo, p_board->turn(), *p_board);
  3913.  
  3914.          p_candidate = true; // not needed yet
  3915.  
  3916.          break;
  3917.  
  3918.       } case GEN_PAWN: {
  3919.  
  3920.          gen::add_castling(p_todo, p_board->turn(), *p_board);
  3921.          gen::add_pawn_pushes(p_todo, p_board->turn(), *p_board);
  3922.  
  3923.          p_candidate = true; // not needed yet
  3924.  
  3925.          break;
  3926.  
  3927.       } case GEN_QUIET: {
  3928.  
  3929.          gen::add_quiets(p_todo, p_board->turn(), *p_board);
  3930.          sort::sort_history(p_todo, *p_board, *p_hist);
  3931.  
  3932.          p_candidate = false;
  3933.  
  3934.          break;
  3935.  
  3936.       } case GEN_BAD: {
  3937.  
  3938.          p_todo = p_bad;
  3939.  
  3940.          p_candidate = false;
  3941.  
  3942.          break;
  3943.  
  3944.       } case GEN_END: {
  3945.  
  3946.          return false;
  3947.  
  3948.       } default: {
  3949.  
  3950.          assert(false);
  3951.  
  3952.       } }
  3953.  
  3954.       return true;
  3955.    }
  3956.  
  3957.    bool post(int mv) {
  3958.  
  3959.       assert(mv != move::NONE);
  3960.  
  3961.       switch (p_post) { {
  3962.  
  3963.       } case POST_MOVE: {
  3964.  
  3965.          if (p_done.contain(mv)) {
  3966.             return false;
  3967.          }
  3968.  
  3969.          if (!move::is_legal(mv, *p_board, *p_attacks)) {
  3970.             return false;
  3971.          }
  3972.  
  3973.          break;
  3974.  
  3975.       } case POST_MOVE_SEE: {
  3976.  
  3977.          if (p_done.contain(mv)) {
  3978.             return false;
  3979.          }
  3980.  
  3981.          if (!move::is_legal(mv, *p_board, *p_attacks)) {
  3982.             return false;
  3983.          }
  3984.  
  3985.          if (!move::is_safe(mv, *p_board)) {
  3986.             p_bad.add(mv);
  3987.             return false;
  3988.          }
  3989.  
  3990.          break;
  3991.  
  3992.       } case POST_KILLER: {
  3993.  
  3994.          if (p_done.contain(mv)) {
  3995.             return false;
  3996.          }
  3997.  
  3998.          if (!move::is_legal(mv, *p_board, *p_attacks)) {
  3999.             return false;
  4000.          }
  4001.  
  4002.          p_done.add(mv);
  4003.  
  4004.          break;
  4005.  
  4006.       } case POST_KILLER_SEE: {
  4007.  
  4008.          if (p_done.contain(mv)) {
  4009.             return false;
  4010.          }
  4011.  
  4012.          if (!move::is_legal(mv, *p_board, *p_attacks)) {
  4013.             return false;
  4014.          }
  4015.  
  4016.          p_done.add(mv);
  4017.  
  4018.          if (!move::is_safe(mv, *p_board)) {
  4019.             p_bad.add(mv);
  4020.             return false;
  4021.          }
  4022.  
  4023.          break;
  4024.  
  4025.       } case POST_BAD: {
  4026.  
  4027.          assert(move::is_legal(mv, *p_board, *p_attacks));
  4028.  
  4029.          break;
  4030.  
  4031.       } default: {
  4032.  
  4033.          assert(false);
  4034.  
  4035.       } }
  4036.  
  4037.       return true;
  4038.    }
  4039.  
  4040. public:
  4041.  
  4042.    void init(int depth, board::Board & bd, const attack::Attacks & attacks, int trans_move, const sort::Killer & killer, const sort::History & history, bool use_fp = false) {
  4043.  
  4044.       p_board = &bd;
  4045.       p_attacks = &attacks;
  4046.       p_killer = &killer;
  4047.       p_hist = &history;
  4048.       p_trans_move = trans_move;
  4049.  
  4050.       if (false) {
  4051.       } else if (attacks.size != 0) { // in check
  4052.          p_ip = Prog_Evasion;
  4053.       } else if (depth < 0) {
  4054.          p_ip = Prog_QS;
  4055.       } else if (depth == 0) {
  4056.          p_ip = Prog_QS_Root;
  4057.       } else if (use_fp) {
  4058.          p_ip = Prog_QS_Root;
  4059.       } else {
  4060.          p_ip = Prog_Main;
  4061.       }
  4062.  
  4063.       p_todo.clear();
  4064.       p_done.clear();
  4065.       p_bad.clear();
  4066.  
  4067.       p_pos = 0;
  4068.       p_candidate = false;
  4069.    }
  4070.  
  4071.    int next() {
  4072.  
  4073.       while (true) {
  4074.  
  4075.          while (p_pos >= p_todo.size()) {
  4076.  
  4077.             p_gen  = *p_ip++;
  4078.             p_post = *p_ip++;
  4079.  
  4080.             if (!gen()) return move::NONE;
  4081.          }
  4082.  
  4083.          int mv = p_todo.move(p_pos++);
  4084.          if (post(mv)) return mv;
  4085.       }
  4086.    }
  4087.  
  4088.    bool is_candidate() const {
  4089.       return p_candidate;
  4090.    }
  4091.  
  4092. };
  4093.  
  4094. }
  4095.  
  4096. namespace material {
  4097.  
  4098. const int p_power[piece::SIZE] = { 0, 1, 1, 2, 4, 0, 0 };
  4099. const int p_score[piece::SIZE][stage::SIZE] = { { 85, 95 }, { 325, 325 }, { 325, 325 }, { 460, 540 }, { 975, 975 }, { 0, 0 }, { 0, 0 } };
  4100.  
  4101. int phase_weight[TOTAL_PHASE + 1];
  4102.  
  4103. int power(int pc) {
  4104.    assert(pc < piece::SIZE);
  4105.    return p_power[pc];
  4106. }
  4107.  
  4108. int score(int pc, int stage) {
  4109.    assert(pc < piece::SIZE);
  4110.    assert(stage < stage::SIZE);
  4111.    return p_score[pc][stage];
  4112. }
  4113.  
  4114. int force(int sd, const board::Board & bd) { // for draw eval
  4115.  
  4116.    int force = 0;
  4117.  
  4118.    for (int pc = piece::KNIGHT; pc <= piece::QUEEN; pc++) {
  4119.       force += bd.count(pc, sd) * power(pc);
  4120.    }
  4121.  
  4122.    return force;
  4123. }
  4124.  
  4125. bool lone_king(int sd, const board::Board & bd) {
  4126.  
  4127.    return bd.count(piece::KNIGHT, sd) == 0
  4128.        && bd.count(piece::BISHOP, sd) == 0
  4129.        && bd.count(piece::ROOK,   sd) == 0
  4130.        && bd.count(piece::QUEEN,  sd) == 0;
  4131. }
  4132.  
  4133. bool lone_bishop(int sd, const board::Board & bd) {
  4134.  
  4135.    return bd.count(piece::KNIGHT, sd) == 0
  4136.        && bd.count(piece::BISHOP, sd) == 1
  4137.        && bd.count(piece::ROOK,   sd) == 0
  4138.        && bd.count(piece::QUEEN,  sd) == 0;
  4139. }
  4140.  
  4141. bool lone_king_or_bishop(int sd, const board::Board & bd) {
  4142.  
  4143.    return bd.count(piece::KNIGHT, sd) == 0
  4144.        && bd.count(piece::BISHOP, sd) <= 1
  4145.        && bd.count(piece::ROOK,   sd) == 0
  4146.        && bd.count(piece::QUEEN,  sd) == 0;
  4147. }
  4148.  
  4149. bool lone_king_or_minor(int sd, const board::Board & bd) {
  4150.  
  4151.    return bd.count(piece::KNIGHT, sd) + bd.count(piece::BISHOP, sd) <= 1
  4152.        && bd.count(piece::ROOK,   sd) == 0
  4153.        && bd.count(piece::QUEEN,  sd) == 0;
  4154. }
  4155.  
  4156. bool two_knights(int sd, const board::Board & bd) {
  4157.  
  4158.    return bd.count(piece::KNIGHT, sd) == 2
  4159.        && bd.count(piece::BISHOP, sd) == 0
  4160.        && bd.count(piece::ROOK,   sd) == 0
  4161.        && bd.count(piece::QUEEN,  sd) == 0;
  4162. }
  4163.  
  4164. int interpolation(int mg, int eg, const board::Board & bd) {
  4165.  
  4166.    int phase = std::min(bd.phase(), TOTAL_PHASE);
  4167.    assert(phase >= 0 && phase <= TOTAL_PHASE);
  4168.  
  4169.    int weight = phase_weight[phase];
  4170.    return (mg * weight + eg * (256 - weight) + 128) >> 8;
  4171. }
  4172.  
  4173. void init() {
  4174.  
  4175.    for (int i = 0; i <= TOTAL_PHASE; i++) {
  4176.       double x = double(i) / double(TOTAL_PHASE / 2) - 1.0;
  4177.       double y = 1.0 / (1.0 + std::exp(-x * 5.0));
  4178.       phase_weight[i] = util::round(y * 256.0);
  4179.    }
  4180. }
  4181.  
  4182. }
  4183.  
  4184. namespace pst {
  4185.  
  4186. const int Knight_Line[8]  = { -4, -2,  0, +1, +1,  0, -2, -4 };
  4187. const int King_Line[8]    = { -3, -1,  0, +1, +1,  0, -1, -3 };
  4188. const int King_File[8]    = { +1, +2,  0, -2, -2,  0, +2, +1 };
  4189. const int King_Rank[8]    = { +1,  0, -2, -4, -6, -8,-10,-12 };
  4190.  
  4191. const int Advance_Rank[8] = { -3, -2, -1,  0, +1, +2, +1,  0 };
  4192.  
  4193. int p_score[piece::SIDE_SIZE][square::SIZE][stage::SIZE];
  4194.  
  4195. int score(int p12, int sq, int stage) {
  4196.    return p_score[p12][sq][stage];
  4197. }
  4198.  
  4199. void init() {
  4200.  
  4201.    for (int p12 = 0; p12 < piece::SIDE_SIZE; p12++) {
  4202.       for (int sq = 0; sq < square::SIZE; sq++) {
  4203.          p_score[p12][sq][stage::MG] = 0;
  4204.          p_score[p12][sq][stage::EG] = 0;
  4205.       }
  4206.    }
  4207.  
  4208.    for (int sq = 0; sq < square::SIZE; sq++) {
  4209.  
  4210.       int fl = square::file(sq);
  4211.       int rk = square::rank(sq);
  4212.  
  4213.       p_score[piece::WHITE_PAWN][sq][stage::MG] = 0;
  4214.       p_score[piece::WHITE_PAWN][sq][stage::EG] = 0;
  4215.  
  4216.       p_score[piece::WHITE_KNIGHT][sq][stage::MG] = (Knight_Line[fl] + Knight_Line[rk] + Advance_Rank[rk]) * 4;
  4217.       p_score[piece::WHITE_KNIGHT][sq][stage::EG] = (Knight_Line[fl] + Knight_Line[rk] + Advance_Rank[rk]) * 4;
  4218.  
  4219.       p_score[piece::WHITE_BISHOP][sq][stage::MG] = (King_Line[fl] + King_Line[rk]) * 2;
  4220.       p_score[piece::WHITE_BISHOP][sq][stage::EG] = (King_Line[fl] + King_Line[rk]) * 2;
  4221.  
  4222.       p_score[piece::WHITE_ROOK][sq][stage::MG] = King_Line[fl] * 5;
  4223.       p_score[piece::WHITE_ROOK][sq][stage::EG] = 0;
  4224.  
  4225.       p_score[piece::WHITE_QUEEN][sq][stage::MG] = (King_Line[fl] + King_Line[rk]) * 1;
  4226.       p_score[piece::WHITE_QUEEN][sq][stage::EG] = (King_Line[fl] + King_Line[rk]) * 1;
  4227.  
  4228.       p_score[piece::WHITE_KING][sq][stage::MG] = (King_File[fl] + King_Rank[rk]) * 8;
  4229.       p_score[piece::WHITE_KING][sq][stage::EG] = (King_Line[fl] + King_Line[rk] + Advance_Rank[rk]) * 8;
  4230.    }
  4231.  
  4232.    for (int pc = piece::PAWN; pc <= piece::KING; pc++) {
  4233.  
  4234.       int wp = piece::make(pc, side::WHITE);
  4235.       int bp = piece::make(pc, side::BLACK);
  4236.  
  4237.       for (int bs = 0; bs < square::SIZE; bs++) {
  4238.  
  4239.          int ws = square::opposit_rank(bs);
  4240.  
  4241.          p_score[bp][bs][stage::MG] = p_score[wp][ws][stage::MG];
  4242.          p_score[bp][bs][stage::EG] = p_score[wp][ws][stage::EG];
  4243.       }
  4244.    }
  4245. }
  4246.  
  4247. }
  4248.  
  4249. namespace pawn {
  4250.  
  4251. struct Info { // 80 bytes; TODO: merge some bitboards and/or file info?
  4252.    int8 open[square::FILE_SIZE][side::SIZE];
  4253.    uint8 shelter[square::FILE_SIZE][side::SIZE];
  4254.    bit_t passed;
  4255.    bit_t target[side::SIZE];
  4256.    bit_t safe;
  4257.    uint32 lock;
  4258.    int16 mg;
  4259.    int16 eg;
  4260.    int8 left_file;
  4261.    int8 right_file;
  4262. };
  4263.  
  4264. void clear_info (Info & info);
  4265. void comp_info  (Info & info, const board::Board & bd);
  4266.  
  4267. class Table {
  4268.  
  4269. private:
  4270.  
  4271.    static const int BITS = 12;
  4272.    static const int SIZE = 1 << BITS;
  4273.    static const int MASK = SIZE - 1;
  4274.  
  4275.    Info p_table[SIZE];
  4276.  
  4277. public:
  4278.  
  4279.    void clear() {
  4280.  
  4281.       Info info;
  4282.       clear_info(info);
  4283.  
  4284.       for (int index = 0; index < SIZE; index++) {
  4285.          p_table[index] = info;
  4286.       }
  4287.    }
  4288.  
  4289.    void clear_fast() {
  4290.       for (int index = 0; index < SIZE; index++) {
  4291.          p_table[index].lock = 1; // board w/o pawns has key 0!
  4292.       }
  4293.    }
  4294.  
  4295.    const Info & info(const board::Board & bd) {
  4296.  
  4297.       hash_t key = bd.pawn_key();
  4298.  
  4299.       int    index = hash::index(key) & MASK;
  4300.       uint32 lock  = hash::lock(key);
  4301.  
  4302.       Info & entry = p_table[index];
  4303.  
  4304.       if (entry.lock != lock) {
  4305.          entry.lock = lock;
  4306.          comp_info(entry, bd);
  4307.       }
  4308.  
  4309.       return entry;
  4310.    }
  4311.  
  4312. };
  4313.  
  4314. bit_t duo[square::SIZE];
  4315.  
  4316. void clear_info(Info & info) {
  4317.  
  4318.    info.passed = 0;
  4319.    info.safe = 0;
  4320.    info.lock = 1; // board w/o pawns has key 0!
  4321.    info.mg = 0;
  4322.    info.eg = 0;
  4323.    info.left_file  = square::FILE_A;
  4324.    info.right_file = square::FILE_H;
  4325.  
  4326.    for (int sd = 0; sd < side::SIZE; sd++) {
  4327.       info.target[sd] = 0;
  4328.    }
  4329.  
  4330.    for (int fl = 0; fl < square::FILE_SIZE; fl++) {
  4331.       for (int sd = 0; sd < side::SIZE; sd++) {
  4332.          info.open[fl][sd] = 0;
  4333.          info.shelter[fl][sd] = 0;
  4334.       }
  4335.    }
  4336. }
  4337.  
  4338. bool is_empty(int sq, const board::Board & bd) {
  4339.    return bd.square(sq) != piece::PAWN;
  4340. }
  4341.  
  4342. bool is_attacked(int sq, int sd, const board::Board & bd) {
  4343.    return (bd.piece(piece::PAWN, sd) & attack::pawn_attacks_to(sd, sq)) != 0;
  4344. }
  4345.  
  4346. bool is_controlled(int sq, int sd, const board::Board & bd) {
  4347.  
  4348.    bit_t attackers = bd.piece(piece::PAWN, sd) & attack::pawn_attacks_to(sd, sq);
  4349.    bit_t defenders = bd.piece(piece::PAWN, side::opposit(sd)) & attack::pawn_attacks_to(side::opposit(sd), sq);
  4350.  
  4351.    return bit::count_loop(attackers) > bit::count_loop(defenders);
  4352. }
  4353.  
  4354. bool is_safe(int sq, int sd, const board::Board & bd) {
  4355.    return is_empty(sq, bd) && !is_controlled(sq, side::opposit(sd), bd);
  4356. }
  4357.  
  4358. bit_t potential_attacks(int sq, int sd, const board::Board & bd) {
  4359.  
  4360.    int inc = square::pawn_inc(sd);
  4361.  
  4362.    bit_t attacks = attack::pawn_attacks_from(sd, sq);
  4363.  
  4364.    for (sq += inc; !square::is_promotion(sq) && is_safe(sq, sd, bd); sq += inc) {
  4365.       attacks |= attack::pawn_attacks_from(sd, sq);
  4366.    }
  4367.  
  4368.    return attacks;
  4369. }
  4370.  
  4371. bool is_duo(int sq, int sd, const board::Board & bd) {
  4372.    return (bd.piece(piece::PAWN, sd) & duo[sq]) != 0;
  4373. }
  4374.  
  4375. bool is_isolated(int sq, int sd, const board::Board & bd) {
  4376.  
  4377.    int fl = square::file(sq);
  4378.    bit_t files = bit::files(fl) & ~bit::file(fl);
  4379.  
  4380.    return (bd.piece(piece::PAWN, sd) & files) == 0;
  4381. }
  4382.  
  4383. bool is_weak(int sq, int sd, const board::Board & bd) {
  4384.  
  4385.    int fl = square::file(sq);
  4386.    int rk = square::rank(sq, sd);
  4387.  
  4388.    uint64 pawns = bd.piece(piece::PAWN, sd);
  4389.    int inc = square::pawn_inc(sd);
  4390.  
  4391.    // already fine?
  4392.  
  4393.    if ((pawns & duo[sq]) != 0) {
  4394.       return false;
  4395.    }
  4396.  
  4397.    if (is_attacked(sq, sd, bd)) {
  4398.       return false;
  4399.    }
  4400.  
  4401.    // can advance next to other pawn in one move?
  4402.  
  4403.    int s1 = sq + inc;
  4404.    int s2 = s1 + inc;
  4405.  
  4406.    if ((pawns & duo[s1]) != 0 && is_safe(s1, sd, bd)) {
  4407.       return false;
  4408.    }
  4409.  
  4410.    if (rk == square::RANK_2 && (pawns & duo[s2]) != 0 && is_safe(s1, sd, bd) && is_safe(s2, sd, bd)) {
  4411.       return false;
  4412.    }
  4413.  
  4414.    // can be defended in one move?
  4415.  
  4416.    if (fl != square::FILE_A) {
  4417.  
  4418.       int s0 = sq + square::INC_LEFT;
  4419.       int s1 = s0 - inc;
  4420.       int s2 = s1 - inc;
  4421.       int s3 = s2 - inc;
  4422.  
  4423.       if (bd.square_is(s2, piece::PAWN, sd) && is_safe(s1, sd, bd)) {
  4424.          return false;
  4425.       }
  4426.  
  4427.       if (rk == square::RANK_5 && bd.square_is(s3, piece::PAWN, sd) && is_safe(s2, sd, bd) && is_safe(s1, sd, bd)) {
  4428.          return false;
  4429.       }
  4430.    }
  4431.  
  4432.    if (fl != square::FILE_H) {
  4433.  
  4434.       int s0 = sq + square::INC_RIGHT;
  4435.       int s1 = s0 - inc;
  4436.       int s2 = s1 - inc;
  4437.       int s3 = s2 - inc;
  4438.  
  4439.       if (bd.square_is(s2, piece::PAWN, sd) && is_safe(s1, sd, bd)) {
  4440.          return false;
  4441.       }
  4442.  
  4443.       if (rk == square::RANK_5 && bd.square_is(s3, piece::PAWN, sd) && is_safe(s2, sd, bd) && is_safe(s1, sd, bd)) {
  4444.          return false;
  4445.       }
  4446.    }
  4447.  
  4448.    return true;
  4449. }
  4450.  
  4451. bool is_doubled(int sq, int sd, const board::Board & bd) {
  4452.    int fl = square::file(sq);
  4453.    return (bd.piece(piece::PAWN, sd) & bit::file(fl) & bit::rear(sq, sd)) != 0;
  4454. }
  4455.  
  4456. bool is_blocked(int sq, int sd, const board::Board & bd) {
  4457.    return !is_safe(square::stop(sq, sd), sd, bd) && !is_attacked(sq, side::opposit(sd), bd);
  4458. }
  4459.  
  4460. int shelter_file(int fl, int sd, const board::Board & bd) {
  4461.  
  4462.    assert(fl >= 0 && fl < 8);
  4463.  
  4464.    if (false) {
  4465.    } else if (bd.square_is(square::make(fl, square::RANK_2, sd), piece::PAWN, sd)) {
  4466.       return 2;
  4467.    } else if (bd.square_is(square::make(fl, square::RANK_3, sd), piece::PAWN, sd)) {
  4468.       return 1;
  4469.    } else {
  4470.       return 0;
  4471.    }
  4472. }
  4473.  
  4474. int shelter_files(int fl, int sd, const board::Board & bd) {
  4475.  
  4476.    int fl_left  = (fl == square::FILE_A) ? fl + 1 : fl - 1;
  4477.    int fl_right = (fl == square::FILE_H) ? fl - 1 : fl + 1;
  4478.  
  4479.    int sc = shelter_file(fl, sd, bd) * 2 + shelter_file(fl_left, sd, bd) + shelter_file(fl_right, sd, bd);
  4480.    assert(sc >= 0 && sc <= 8);
  4481.  
  4482.    return sc;
  4483. }
  4484.  
  4485. void comp_info(Info & info, const board::Board & bd) {
  4486.  
  4487.    info.passed = 0;
  4488.    info.safe = 0;
  4489.  
  4490.    info.mg = 0;
  4491.    info.eg = 0;
  4492.  
  4493.    info.left_file  = square::FILE_H + 1;
  4494.    info.right_file = square::FILE_A - 1;
  4495.  
  4496.    for (int sd = 0; sd < side::SIZE; sd++) {
  4497.       info.target[sd] = 0;
  4498.    }
  4499.  
  4500.    bit_t weak = 0;
  4501.    bit_t strong = 0;
  4502.    bit_t safe[side::SIZE] = { bit_t(~0), bit_t(~0) };
  4503.  
  4504.    for (int sd = 0; sd < side::SIZE; sd++) {
  4505.  
  4506.       int p12 = piece::make(piece::PAWN, sd);
  4507.  
  4508.       strong |= bd.piece(piece::PAWN, sd) & attack::pawn_attacks_from(sd, bd); // defended pawns
  4509.  
  4510.       {
  4511.          int n = bd.count(piece::PAWN, sd);
  4512.          info.mg += n * material::score(piece::PAWN, stage::MG);
  4513.          info.eg += n * material::score(piece::PAWN, stage::EG);
  4514.       }
  4515.  
  4516.       for (bit_t b = bd.piece(piece::PAWN, sd); b != 0; b = bit::rest(b)) {
  4517.  
  4518.          int sq = bit::first(b);
  4519.  
  4520.          int fl = square::file(sq);
  4521.          int rk = square::rank(sq, sd);
  4522.  
  4523.          if (fl < info.left_file)  info.left_file  = fl;
  4524.          if (fl > info.right_file) info.right_file = fl;
  4525.  
  4526.          info.mg += pst::score(p12, sq, stage::MG);
  4527.          info.eg += pst::score(p12, sq, stage::EG);
  4528.  
  4529.          if (is_isolated(sq, sd, bd)) {
  4530.  
  4531.             bit::set(weak, sq);
  4532.  
  4533.             info.mg -= 10;
  4534.             info.eg -= 20;
  4535.  
  4536.          } else if (is_weak(sq, sd, bd)) {
  4537.  
  4538.             bit::set(weak, sq);
  4539.  
  4540.             info.mg -= 5;
  4541.             info.eg -= 10;
  4542.          }
  4543.  
  4544.          if (is_doubled(sq, sd, bd)) {
  4545.             info.mg -= 5;
  4546.             info.eg -= 10;
  4547.          }
  4548.  
  4549.          if (is_passed(sq, sd, bd)) {
  4550.  
  4551.             bit::set(info.passed, sq);
  4552.  
  4553.             info.mg += 10;
  4554.             info.eg += 20;
  4555.  
  4556.             if (rk >= square::RANK_5) {
  4557.                int stop = square::stop(sq, sd);
  4558.                if (is_duo(sq, sd, bd) && rk <= square::RANK_6) stop += square::pawn_inc(sd); // stop one line "later" for duos
  4559.                bit::set(info.target[side::opposit(sd)], stop);
  4560.             }
  4561.          }
  4562.  
  4563.          safe[side::opposit(sd)] &= ~potential_attacks(sq, sd, bd);
  4564.       }
  4565.  
  4566.       for (int fl = 0; fl < square::FILE_SIZE; fl++) {
  4567.          info.shelter[fl][sd] = shelter_files(fl, sd, bd) * 4;
  4568.       }
  4569.  
  4570.       info.mg = -info.mg;
  4571.       info.eg = -info.eg;
  4572.    }
  4573.  
  4574.    weak &= ~strong; // defended doubled pawns are not weak
  4575.    assert((weak & strong) == 0);
  4576.  
  4577.    info.target[side::WHITE] |= bd.piece(piece::PAWN, side::BLACK) & weak;
  4578.    info.target[side::BLACK] |= bd.piece(piece::PAWN, side::WHITE) & weak;
  4579.  
  4580.    info.safe = (safe[side::WHITE] & bit::front(square::RANK_4))
  4581.              | (safe[side::BLACK] & bit::rear (square::RANK_5));
  4582.  
  4583.    if (info.left_file > info.right_file) { // no pawns
  4584.       info.left_file  = square::FILE_A;
  4585.       info.right_file = square::FILE_H;
  4586.    }
  4587.  
  4588.    assert(info.left_file <= info.right_file);
  4589.  
  4590.    // file "openness"
  4591.  
  4592.    for (int sd = 0; sd < side::SIZE; sd++) {
  4593.  
  4594.       for (int fl = 0; fl < square::FILE_SIZE; fl++) {
  4595.  
  4596.          bit_t file = bit::file(fl);
  4597.  
  4598.          int open;
  4599.  
  4600.          if (false) {
  4601.          } else if ((bd.piece(piece::PAWN, sd) & file) != 0) {
  4602.             open = 0;
  4603.          } else if ((bd.piece(piece::PAWN, side::opposit(sd)) & file) == 0) {
  4604.             open = 4;
  4605.          } else if ((strong & file) != 0) {
  4606.             open = 1;
  4607.          } else if ((weak & file) != 0) {
  4608.             open = 3;
  4609.          } else {
  4610.             open = 2;
  4611.          }
  4612.  
  4613.          info.open[fl][sd] = open * 5;
  4614.       }
  4615.    }
  4616. }
  4617.  
  4618. void init() {
  4619.  
  4620.    for (int sq = 0; sq < square::SIZE; sq++) {
  4621.  
  4622.       int fl = square::file(sq);
  4623.       int rk = square::rank(sq);
  4624.  
  4625.       passed_me[sq][side::WHITE] = bit::file(fl) & bit::front(rk);
  4626.       passed_me[sq][side::BLACK] = bit::file(fl) & bit::rear(rk);
  4627.  
  4628.       passed_opp[sq][side::WHITE] = bit::files(fl) & bit::front(rk);
  4629.       passed_opp[sq][side::BLACK] = bit::files(fl) & bit::rear(rk);
  4630.  
  4631.       bit_t b = 0;
  4632.       if (fl != square::FILE_A) bit::set(b, sq + square::INC_LEFT);
  4633.       if (fl != square::FILE_H) bit::set(b, sq + square::INC_RIGHT);
  4634.       duo[sq] = b;
  4635.    }
  4636. }
  4637.  
  4638. }
  4639.  
  4640. namespace eval {
  4641.  
  4642. int comp_eval (const board::Board & bd, pawn::Table & pawn_table);
  4643.  
  4644. struct Entry {
  4645.    uint32 lock;
  4646.    int eval;
  4647. };
  4648.  
  4649. class Table {
  4650.  
  4651. private:
  4652.  
  4653.    static const int BITS = 16;
  4654.    static const int SIZE = 1 << BITS;
  4655.    static const int MASK = SIZE - 1;
  4656.  
  4657.    Entry p_table[SIZE];
  4658.  
  4659. public:
  4660.  
  4661.    void clear() {
  4662.       for (int index = 0; index < SIZE; index++) {
  4663.          p_table[index].lock = 0;
  4664.          p_table[index].eval = 0;
  4665.       }
  4666.    }
  4667.  
  4668.    int eval(const board::Board & bd, pawn::Table & pawn_table) { // NOTE: score for white
  4669.  
  4670.       hash_t key = bd.eval_key();
  4671.  
  4672.       int    index = hash::index(key) & MASK;
  4673.       uint32 lock  = hash::lock(key);
  4674.  
  4675.       Entry & entry = p_table[index];
  4676.  
  4677.       if (entry.lock == lock) {
  4678.          return entry.eval;
  4679.       }
  4680.  
  4681.       int eval = comp_eval(bd, pawn_table);
  4682.  
  4683.       entry.lock = lock;
  4684.       entry.eval = eval;
  4685.  
  4686.       return eval;
  4687.    }
  4688.  
  4689. };
  4690.  
  4691. struct Attack_Info {
  4692.  
  4693.    bit_t piece_attacks[square::SIZE];
  4694.    bit_t all_attacks[side::SIZE];
  4695.    bit_t multiple_attacks[side::SIZE];
  4696.  
  4697.    bit_t ge_pieces[side::SIZE][piece::SIZE];
  4698.  
  4699.    bit_t lt_attacks[side::SIZE][piece::SIZE];
  4700.    bit_t le_attacks[side::SIZE][piece::SIZE];
  4701.  
  4702.    bit_t king_evasions[side::SIZE];
  4703.  
  4704.    bit_t pinned;
  4705. };
  4706.  
  4707. const int attack_weight[piece::SIZE]   = { 0, 4, 4, 2, 1, 4, 0 };
  4708. const int attacked_weight[piece::SIZE] = { 0, 1, 1, 2, 4, 8, 0 };
  4709.  
  4710. int mob_weight[32];
  4711. int dist_weight[8]; // for king-passer distance
  4712.  
  4713. bit_t small_centre, medium_centre, large_centre;
  4714. bit_t centre_0, centre_1;
  4715.  
  4716. bit_t side_area[side::SIZE];
  4717. bit_t king_area[side::SIZE][square::SIZE];
  4718.  
  4719. void comp_attacks(Attack_Info & ai, const board::Board & bd) {
  4720.  
  4721.    // prepare for adding defended opponent pieces
  4722.  
  4723.    for (int sd = 0; sd < side::SIZE; sd++) {
  4724.  
  4725.       bit_t b = 0;
  4726.  
  4727.       for (int pc = piece::KING; pc >= piece::KNIGHT; pc--) {
  4728.          b |= bd.piece(pc, sd);
  4729.          ai.ge_pieces[sd][pc] = b;
  4730.       }
  4731.  
  4732.       ai.ge_pieces[sd][piece::BISHOP] = ai.ge_pieces[sd][piece::KNIGHT]; // minors are equal
  4733.    }
  4734.  
  4735.    // pawn attacks
  4736.  
  4737.    {
  4738.       int pc = piece::PAWN;
  4739.  
  4740.       for (int sd = 0; sd < side::SIZE; sd++) {
  4741.  
  4742.          bit_t b = attack::pawn_attacks_from(sd, bd);
  4743.  
  4744.          ai.lt_attacks[sd][pc] = 0; // not needed
  4745.          ai.le_attacks[sd][pc] = b;
  4746.          ai.all_attacks[sd] = b;
  4747.       }
  4748.    }
  4749.  
  4750.    // piece attacks
  4751.  
  4752.    ai.multiple_attacks[side::WHITE] = 0;
  4753.    ai.multiple_attacks[side::BLACK] = 0;
  4754.  
  4755.    for (int pc = piece::KNIGHT; pc <= piece::KING; pc++) {
  4756.  
  4757.       int lower_piece = (pc == piece::BISHOP) ? piece::PAWN : pc - 1; // HACK: direct access
  4758.       assert(lower_piece >= piece::PAWN && lower_piece < pc);
  4759.  
  4760.       for (int sd = 0; sd < side::SIZE; sd++) {
  4761.          ai.lt_attacks[sd][pc] = ai.le_attacks[sd][lower_piece];
  4762.       }
  4763.  
  4764.       for (int sd = 0; sd < side::SIZE; sd++) {
  4765.  
  4766.          for (bit_t fs = bd.piece(pc, sd); fs != 0; fs = bit::rest(fs)) {
  4767.  
  4768.             int sq = bit::first(fs);
  4769.  
  4770.             bit_t ts = attack::piece_attacks_from(pc, sq, bd);
  4771.             ai.piece_attacks[sq] = ts;
  4772.  
  4773.             ai.multiple_attacks[sd] |= ts & ai.all_attacks[sd];
  4774.             ai.all_attacks[sd] |= ts;
  4775.          }
  4776.  
  4777.          ai.le_attacks[sd][pc] = ai.all_attacks[sd];
  4778.          assert((ai.le_attacks[sd][pc] & ai.lt_attacks[sd][pc]) == ai.lt_attacks[sd][pc]);
  4779.  
  4780.          if (pc == piece::BISHOP) { // minors are equal
  4781.             ai.le_attacks[sd][piece::KNIGHT] = ai.le_attacks[sd][piece::BISHOP];
  4782.          }
  4783.       }
  4784.    }
  4785.  
  4786.    for (int sd = 0; sd < side::SIZE; sd++) {
  4787.       int king = bd.king(sd);
  4788.       bit_t ts = attack::pseudo_attacks_from(piece::KING, sd, king);
  4789.       ai.king_evasions[sd] = ts & ~bd.side(sd) & ~ai.all_attacks[side::opposit(sd)];
  4790.    }
  4791.  
  4792.    // pinned pieces
  4793.  
  4794.    ai.pinned = 0;
  4795.  
  4796.    for (int sd = 0; sd < side::SIZE; sd++) {
  4797.       int sq = bd.king(sd);
  4798.       ai.pinned |= bd.side(sd) & attack::pinned_by(sq, side::opposit(sd), bd);
  4799.    }
  4800. }
  4801.  
  4802. int mul_shift(int a, int b, int c) {
  4803.    int bias = 1 << (c - 1);
  4804.    return (a * b + bias) >> c;
  4805. }
  4806.  
  4807. int passed_score(int sc, int rk) {
  4808.    static const int passed_weight[8] = { 0, 0, 0, 2, 6, 12, 20, 0 };
  4809.    return mul_shift(sc, passed_weight[rk], 4);
  4810. }
  4811.  
  4812. int mobility_score(int /* pc */, bit_t ts) {
  4813.    // assert(pc < piece::SIZE);
  4814.    int mob = bit::count(ts);
  4815.    return mul_shift(20, mob_weight[mob], 8);
  4816. }
  4817.  
  4818. int attack_mg_score(int pc, int sd, bit_t ts) {
  4819.  
  4820.    assert(pc < piece::SIZE);
  4821.  
  4822.    int c0 = bit::count(ts & centre_0);
  4823.    int c1 = bit::count(ts & centre_1);
  4824.    int sc = c1 * 2 + c0;
  4825.  
  4826.    sc += bit::count(ts & side_area[side::opposit(sd)]);
  4827.  
  4828.    return (sc - 4) * attack_weight[pc] / 2;
  4829. }
  4830.  
  4831. int attack_eg_score(int pc, int sd, bit_t ts, const pawn::Info & pi) {
  4832.    assert(pc < piece::SIZE);
  4833.    return bit::count(ts & pi.target[sd]) * attack_weight[pc] * 4;
  4834. }
  4835.  
  4836. int capture_score(int pc, int sd, bit_t ts, const board::Board & bd, const Attack_Info & ai) {
  4837.  
  4838.    assert(pc < piece::SIZE);
  4839.  
  4840.    int sc = 0;
  4841.  
  4842.    for (bit_t b = ts & bd.pieces(side::opposit(sd)); b != 0; b = bit::rest(b)) {
  4843.  
  4844.       int t = bit::first(b);
  4845.  
  4846.       int cp = bd.square(t);
  4847.       sc += attacked_weight[cp];
  4848.       if (bit::is_set(ai.pinned, t)) sc += attacked_weight[cp] * 2;
  4849.    }
  4850.  
  4851.    return attack_weight[pc] * sc * 4;
  4852. }
  4853.  
  4854. int shelter_score(int sq, int sd, const board::Board & bd, const pawn::Info & pi) {
  4855.  
  4856.    if (square::rank(sq, sd) > square::RANK_2) {
  4857.       return 0;
  4858.    }
  4859.  
  4860.    int s0 = pi.shelter[square::file(sq)][sd];
  4861.  
  4862.    int s1 = 0;
  4863.  
  4864.    for (int wg = 0; wg < wing::SIZE; wg++) {
  4865.  
  4866.       int index = castling::index(sd, wg);
  4867.  
  4868.       if (castling::flag(bd.flags(), index)) {
  4869.          int fl = wing::shelter_file[wg];
  4870.          s1 = std::max(s1, int(pi.shelter[fl][sd]));
  4871.       }
  4872.    }
  4873.  
  4874.    if (s1 > s0) {
  4875.       return (s0 + s1) / 2;
  4876.    } else {
  4877.       return s0;
  4878.    }
  4879. }
  4880.  
  4881. int king_score(int sc, int n) {
  4882.    int weight = 256 - (256 >> n);
  4883.    return mul_shift(sc, weight, 8);
  4884. }
  4885.  
  4886. int eval_outpost(int sq, int sd, const board::Board & bd, const pawn::Info & pi) {
  4887.  
  4888.    assert(square::rank(sq, sd) >= square::RANK_5);
  4889.  
  4890.    int xd = side::opposit(sd);
  4891.  
  4892.    int weight = 0;
  4893.  
  4894.    if (bit::is_set(pi.safe, sq)) { // safe square
  4895.       weight += 2;
  4896.    }
  4897.  
  4898.    if (bd.square_is(square::stop(sq, sd), piece::PAWN, xd)) { // shielded
  4899.       weight++;
  4900.    }
  4901.  
  4902.    if (pawn::is_attacked(sq, sd, bd)) { // defended
  4903.       weight++;
  4904.    }
  4905.  
  4906.    return weight - 2;
  4907. }
  4908.  
  4909. bool passer_is_unstoppable(int sq, int sd, const board::Board & bd) {
  4910.  
  4911.    if (!material::lone_king(side::opposit(sd), bd)) return false;
  4912.  
  4913.    int fl = square::file(sq);
  4914.    bit_t front = bit::file(fl) & bit::front(sq, sd);
  4915.  
  4916.    if ((bd.all() & front) != 0) { // path not free
  4917.       return false;
  4918.    }
  4919.  
  4920.    if (pawn::square_distance(bd.king(side::opposit(sd)), sq, sd) >= 2) { // opponent king outside square
  4921.       return true;
  4922.    }
  4923.  
  4924.    if ((front & ~attack::pseudo_attacks_from(piece::KING, sd, bd.king(sd))) == 0) { // king controls promotion path
  4925.       return true;
  4926.    }
  4927.  
  4928.    return false;
  4929. }
  4930.  
  4931. int eval_passed(int sq, int sd, const board::Board & bd, const Attack_Info & ai) {
  4932.  
  4933.    int fl = square::file(sq);
  4934.    int xd = side::opposit(sd);
  4935.  
  4936.    int weight = 4;
  4937.  
  4938.    // blocker
  4939.  
  4940.    if (bd.square(square::stop(sq, sd)) != piece::NONE) {
  4941.       weight--;
  4942.    }
  4943.  
  4944.    // free path
  4945.  
  4946.    bit_t front = bit::file(fl) & bit::front(sq, sd);
  4947.    bit_t rear  = bit::file(fl) & bit::rear (sq, sd);
  4948.  
  4949.    if ((bd.all() & front) == 0) {
  4950.  
  4951.       bool major_behind = false;
  4952.       bit_t majors = bd.piece(piece::ROOK, xd) | bd.piece(piece::QUEEN, xd);
  4953.  
  4954.       for (bit_t b = majors & rear; b != 0; b = bit::rest(b)) {
  4955.  
  4956.          int f = bit::first(b);
  4957.  
  4958.          if (attack::line_is_empty(f, sq, bd)) {
  4959.             major_behind = true;
  4960.          }
  4961.       }
  4962.  
  4963.       if (!major_behind && (ai.all_attacks[xd] & front) == 0) {
  4964.          weight += 2;
  4965.       }
  4966.    }
  4967.  
  4968.    return weight;
  4969. }
  4970.  
  4971. int eval_pawn_cap(int sd, const board::Board & bd, const Attack_Info & ai) {
  4972.  
  4973.    bit_t ts = attack::pawn_attacks_from(sd, bd);
  4974.  
  4975.    int sc = 0;
  4976.  
  4977.    for (bit_t b = ts & bd.pieces(side::opposit(sd)); b != 0; b = bit::rest(b)) {
  4978.  
  4979.       int t = bit::first(b);
  4980.  
  4981.       int cp = bd.square(t);
  4982.       if (cp == piece::KING) continue;
  4983.  
  4984.       sc += piece::value(cp) - 50;
  4985.       if (bit::is_set(ai.pinned, t)) sc += (piece::value(cp) - 50) * 2;
  4986.    }
  4987.  
  4988.    return sc / 10;
  4989. }
  4990.  
  4991. int eval_pattern(const board::Board & bd) {
  4992.  
  4993.    int eval = 0;
  4994.  
  4995.    // fianchetto
  4996.  
  4997.    if (bd.square_is(square::B2, piece::BISHOP, side::WHITE)
  4998.     && bd.square_is(square::B3, piece::PAWN,   side::WHITE)
  4999.     && bd.square_is(square::C2, piece::PAWN,   side::WHITE)) {
  5000.       eval += 20;
  5001.    }
  5002.  
  5003.    if (bd.square_is(square::G2, piece::BISHOP, side::WHITE)
  5004.     && bd.square_is(square::G3, piece::PAWN,   side::WHITE)
  5005.     && bd.square_is(square::F2, piece::PAWN,   side::WHITE)) {
  5006.       eval += 20;
  5007.    }
  5008.  
  5009.    if (bd.square_is(square::B7, piece::BISHOP, side::BLACK)
  5010.     && bd.square_is(square::B6, piece::PAWN,   side::BLACK)
  5011.     && bd.square_is(square::C7, piece::PAWN,   side::BLACK)) {
  5012.       eval -= 20;
  5013.    }
  5014.  
  5015.    if (bd.square_is(square::G7, piece::BISHOP, side::BLACK)
  5016.     && bd.square_is(square::G6, piece::PAWN,   side::BLACK)
  5017.     && bd.square_is(square::F7, piece::PAWN,   side::BLACK)) {
  5018.       eval -= 20;
  5019.    }
  5020.  
  5021.    return eval;
  5022. }
  5023.  
  5024. bool has_minor(int sd, const board::Board & bd) {
  5025.    return bd.count(piece::KNIGHT, sd) + bd.count(piece::BISHOP, sd) != 0;
  5026. }
  5027.  
  5028. int draw_mul(int sd, const board::Board & bd, const pawn::Info & pi) {
  5029.  
  5030.    int xd = side::opposit(sd);
  5031.  
  5032.    int pawn[side::SIZE];
  5033.    pawn[side::WHITE] = bd.count(piece::PAWN, side::WHITE);
  5034.    pawn[side::BLACK] = bd.count(piece::PAWN, side::BLACK);
  5035.  
  5036.    int force = material::force(sd, bd) - material::force(xd, bd);
  5037.  
  5038.    // rook-file pawns
  5039.  
  5040.    if (material::lone_king_or_bishop(sd, bd) && pawn[sd] != 0) {
  5041.  
  5042.       bit_t b = bd.piece(piece::BISHOP, sd);
  5043.  
  5044.       if ((bd.piece(piece::PAWN, sd) & ~bit::file(square::FILE_A)) == 0
  5045.        && (bd.piece(piece::PAWN, xd) &  bit::file(square::FILE_B)) == 0) {
  5046.  
  5047.          int prom = (sd == side::WHITE) ? square::A8 : square::A1;
  5048.  
  5049.          if (square::distance(bd.king(xd), prom) <= 1) {
  5050.             if (b == 0 || !square::same_colour(bit::first(b), prom)) {
  5051.                return 1;
  5052.             }
  5053.          }
  5054.       }
  5055.  
  5056.       if ((bd.piece(piece::PAWN, sd) & ~bit::file(square::FILE_H)) == 0
  5057.        && (bd.piece(piece::PAWN, xd) &  bit::file(square::FILE_G)) == 0) {
  5058.  
  5059.          int prom = (sd == side::WHITE) ? square::H8 : square::H1;
  5060.  
  5061.          if (square::distance(bd.king(xd), prom) <= 1) {
  5062.             if (b == 0 || !square::same_colour(bit::first(b), prom)) {
  5063.                return 1;
  5064.             }
  5065.          }
  5066.       }
  5067.    }
  5068.  
  5069.    if (pawn[sd] == 0 && material::lone_king_or_minor(sd, bd)) {
  5070.       return 1;
  5071.    }
  5072.  
  5073.    if (pawn[sd] == 0 && material::two_knights(sd, bd)) {
  5074.       return 2;
  5075.    }
  5076.  
  5077.    if (pawn[sd] == 0 && force <= 1) {
  5078.       return 2;
  5079.    }
  5080.  
  5081.    if (pawn[sd] == 1 && force == 0 && has_minor(xd, bd)) {
  5082.       return 4;
  5083.    }
  5084.  
  5085.    if (pawn[sd] == 1 && force == 0) {
  5086.  
  5087.       int king = bd.king(xd);
  5088.       int pawn = bit::first(bd.piece(piece::PAWN, sd));
  5089.       int stop = square::stop(pawn, sd);
  5090.  
  5091.       if (king == stop || (square::rank(pawn, sd) <= square::RANK_6 && king == square::stop(stop, sd))) {
  5092.          return 4;
  5093.       }
  5094.    }
  5095.  
  5096.    if (pawn[sd] == 2 && pawn[xd] >= 1 && force == 0 && has_minor(xd, bd) && (bd.piece(piece::PAWN, sd) & pi.passed) == 0) {
  5097.       return 8;
  5098.    }
  5099.  
  5100.    if (material::lone_bishop(side::WHITE, bd) && material::lone_bishop(side::BLACK, bd) && std::abs(pawn[side::WHITE] - pawn[side::BLACK]) <= 2) { // opposit-colour bishops
  5101.  
  5102.       int wb = bit::first(bd.piece(piece::BISHOP, side::WHITE));
  5103.       int bb = bit::first(bd.piece(piece::BISHOP, side::BLACK));
  5104.  
  5105.       if (!square::same_colour(wb, bb)) {
  5106.          return 8;
  5107.       }
  5108.    }
  5109.  
  5110.    return 16;
  5111. }
  5112.  
  5113. int my_distance(int f, int t, int weight) {
  5114.    int dist = square::distance(f, t);
  5115.    return mul_shift(dist_weight[dist], weight, 8);
  5116. }
  5117.  
  5118. int check_number(int pc, int sd, bit_t ts, int king, const board::Board & bd) {
  5119.  
  5120.    assert(pc != piece::KING);
  5121.  
  5122.    int xd = side::opposit(sd);
  5123.    bit_t checks = ts & ~bd.side(sd) & attack::pseudo_attacks_to(pc, sd, king);
  5124.  
  5125.    if (!piece::is_slider(pc)) {
  5126.       return bit::count_loop(checks);
  5127.    }
  5128.  
  5129.    int n = 0;
  5130.  
  5131.    bit_t b = checks & attack::pseudo_attacks_to(piece::KING, xd, king); // contact checks
  5132.    n += bit::count_loop(b) * 2;
  5133.    checks &= ~b;
  5134.  
  5135.    for (bit_t b = checks; b != 0; b = bit::rest(b)) {
  5136.  
  5137.       int t = bit::first(b);
  5138.  
  5139.       if (attack::line_is_empty(t, king, bd)) {
  5140.          n++;
  5141.       }
  5142.    }
  5143.  
  5144.    return n;
  5145. }
  5146.  
  5147. int comp_eval(const board::Board & bd, pawn::Table & pawn_table) { // NOTE: score for white
  5148.  
  5149.    Attack_Info ai;
  5150.    comp_attacks(ai, bd);
  5151.  
  5152.    const pawn::Info & pi = pawn_table.info(bd);
  5153.  
  5154.    int eval = 0;
  5155.    int mg = 0;
  5156.    int eg = 0;
  5157.  
  5158.    int shelter[side::SIZE];
  5159.  
  5160.    for (int sd = 0; sd < side::SIZE; sd++) {
  5161.       shelter[sd] = shelter_score(bd.king(sd), sd, bd, pi);
  5162.    }
  5163.  
  5164.    for (int sd = 0; sd < side::SIZE; sd++) {
  5165.  
  5166.       int xd = side::opposit(sd);
  5167.  
  5168.       int my_king = bd.king(sd);
  5169.       int op_king = bd.king(xd);
  5170.  
  5171.       bit_t target = ~(bd.piece(piece::PAWN, sd) | attack::pawn_attacks_from(xd, bd));
  5172.  
  5173.       int king_n = 0;
  5174.       int king_power = 0;
  5175.  
  5176.       // pawns
  5177.  
  5178.       {
  5179.          bit_t fs = bd.piece(piece::PAWN, sd);
  5180.  
  5181.          bit_t front = (sd == side::WHITE) ? bit::front(square::RANK_3) : bit::rear(square::RANK_6);
  5182.  
  5183.          for (bit_t b = fs & pi.passed & front; b != 0; b = bit::rest(b)) {
  5184.  
  5185.             int sq = bit::first(b);
  5186.  
  5187.             int rk = square::rank(sq, sd);
  5188.  
  5189.             if (passer_is_unstoppable(sq, sd, bd)) {
  5190.  
  5191.                int weight = std::max(rk - square::RANK_3, 0);
  5192.                assert(weight >= 0 and weight < 5);
  5193.  
  5194.                eg += (piece::QUEEN_VALUE - piece::PAWN_VALUE) * weight / 5;
  5195.  
  5196.             } else {
  5197.  
  5198.                int sc = eval_passed(sq, sd, bd, ai);
  5199.  
  5200.                int sc_mg = sc * 20;
  5201.                int sc_eg = sc * 25;
  5202.  
  5203.                int stop = square::stop(sq, sd);
  5204.                sc_eg -= my_distance(my_king, stop, 10);
  5205.                sc_eg += my_distance(op_king, stop, 20);
  5206.  
  5207.                mg += passed_score(sc_mg, rk);
  5208.                eg += passed_score(sc_eg, rk);
  5209.             }
  5210.          }
  5211.  
  5212.          eval += bit::count(attack::pawn_moves_from(sd, bd) & bd.empty()) * 4 - bd.count(piece::PAWN, sd) * 2;
  5213.  
  5214.          eval += eval_pawn_cap(sd, bd, ai);
  5215.       }
  5216.  
  5217.       // pieces
  5218.  
  5219.       for (int pc = piece::KNIGHT; pc <= piece::KING; pc++) {
  5220.  
  5221.          int p12 = piece::make(pc, sd); // for PST
  5222.  
  5223.          {
  5224.             int n = bd.count(pc, sd);
  5225.             mg += n * material::score(pc, stage::MG);
  5226.             eg += n * material::score(pc, stage::EG);
  5227.          }
  5228.  
  5229.          for (bit_t b = bd.piece(pc, sd); b != 0; b = bit::rest(b)) {
  5230.  
  5231.             int sq = bit::first(b);
  5232.  
  5233.             int fl = square::file(sq);
  5234.             int rk = square::rank(sq, sd);
  5235.  
  5236.             // compute safe attacks
  5237.  
  5238.             bit_t ts_all = ai.piece_attacks[sq];
  5239.             bit_t ts_pawn_safe = ts_all & target;
  5240.  
  5241.             bit_t safe = ~ai.all_attacks[xd] | ai.multiple_attacks[sd];
  5242.  
  5243.             if (true && piece::is_slider(pc)) { // battery support
  5244.  
  5245.                bit_t bishops = bd.piece(piece::BISHOP, sd) | bd.piece(piece::QUEEN, sd);
  5246.                bit_t rooks   = bd.piece(piece::ROOK,   sd) | bd.piece(piece::QUEEN, sd);
  5247.  
  5248.                bit_t support = 0;
  5249.                support |= bishops & attack::pseudo_attacks_to(piece::BISHOP, sd, sq);
  5250.                support |= rooks   & attack::pseudo_attacks_to(piece::ROOK,   sd, sq);
  5251.  
  5252.                for (bit_t b = ts_all & support; b != 0; b = bit::rest(b)) {
  5253.                   int f = bit::first(b);
  5254.                   assert(attack::line_is_empty(f, sq, bd));
  5255.                   safe |= attack::Behind[f][sq];
  5256.                }
  5257.             }
  5258.  
  5259.             bit_t ts_safe = ts_pawn_safe & ~ai.lt_attacks[xd][pc] & safe;
  5260.  
  5261.             mg += pst::score(p12, sq, stage::MG);
  5262.             eg += pst::score(p12, sq, stage::EG);
  5263.  
  5264.             if (pc == piece::KING) {
  5265.                eg += mobility_score(pc, ts_safe);
  5266.             } else {
  5267.                eval += mobility_score(pc, ts_safe);
  5268.             }
  5269.  
  5270.             if (pc != piece::KING) {
  5271.                mg += attack_mg_score(pc, sd, ts_pawn_safe);
  5272.             }
  5273.  
  5274.             eg += attack_eg_score(pc, sd, ts_pawn_safe, pi);
  5275.  
  5276.             eval += capture_score(pc, sd, ts_all & (ai.ge_pieces[xd][pc] | target), bd, ai);
  5277.  
  5278.             if (pc != piece::KING) {
  5279.                eval += check_number(pc, sd, ts_safe, op_king, bd) * material::power(pc) * 6;
  5280.             }
  5281.  
  5282.             if (pc != piece::KING && (ts_safe & king_area[xd][op_king]) != 0) { // king attack
  5283.                king_n++;
  5284.                king_power += material::power(pc);
  5285.             }
  5286.  
  5287.             if (piece::is_minor(pc) && rk >= square::RANK_5 && rk <= square::RANK_6 && fl >= square::FILE_C && fl <= square::FILE_F) { // outpost
  5288.                eval += eval_outpost(sq, sd, bd, pi) * 5;
  5289.             }
  5290.  
  5291.             if (piece::is_minor(pc) && rk >= square::RANK_5 && !bit::is_set(ai.all_attacks[sd], sq)) { // loose minor
  5292.                mg -= 10;
  5293.             }
  5294.  
  5295.             if (piece::is_minor(pc) && rk >= square::RANK_3 && rk <= square::RANK_4 && bd.square_is(square::stop(sq, sd), piece::PAWN, sd)) { // shielded minor
  5296.                mg += 10;
  5297.             }
  5298.  
  5299.             if (pc == piece::ROOK) { // open file
  5300.  
  5301.                int sc = pi.open[fl][sd];
  5302.  
  5303.                bit_t minors = bd.piece(piece::KNIGHT, xd) | bd.piece(piece::BISHOP, xd);
  5304.                if (true && sc >= 10 && (minors & bit::file(fl) & ~target) != 0) { // blocked by minor
  5305.                   sc = 5;
  5306.                }
  5307.  
  5308.                eval += sc - 10;
  5309.  
  5310.                if (sc >= 10 && std::abs(square::file(op_king) - fl) <= 1) { // open file on king
  5311.                   int weight = (square::file(op_king) == fl) ? 2 : 1;
  5312.                   mg += sc * weight / 2;
  5313.                }
  5314.             }
  5315.  
  5316.             if (pc == piece::ROOK && rk == square::RANK_7) { // 7th rank
  5317.  
  5318.                bit_t pawns = bd.piece(piece::PAWN, xd) & bit::rank(square::rank(sq));
  5319.  
  5320.                if (square::rank(op_king, sd) >= square::RANK_7 || pawns != 0) {
  5321.                   mg += 10;
  5322.                   eg += 20;
  5323.                }
  5324.             }
  5325.  
  5326.             if (pc == piece::KING) { // king out
  5327.  
  5328.                int dl = (pi.left_file - 1) - fl;
  5329.                if (dl > 0) eg -= dl * 20;
  5330.  
  5331.                int dr = fl - (pi.right_file + 1);
  5332.                if (dr > 0) eg -= dr * 20;
  5333.             }
  5334.          }
  5335.       }
  5336.  
  5337.       if (bd.count(piece::BISHOP, sd) >= 2) {
  5338.          mg += 30;
  5339.          eg += 50;
  5340.       }
  5341.  
  5342.       mg += shelter[sd];
  5343.       mg += mul_shift(king_score(king_power * 30, king_n), 32 - shelter[xd], 5);
  5344.  
  5345.       eval = -eval;
  5346.       mg = -mg;
  5347.       eg = -eg;
  5348.    }
  5349.  
  5350.    mg += pi.mg;
  5351.    eg += pi.eg;
  5352.  
  5353.    eval += eval_pattern(bd);
  5354.  
  5355.    eval += material::interpolation(mg, eg, bd);
  5356.  
  5357.    if (eval != 0) { // draw multiplier
  5358.       int winner = (eval > 0) ? side::WHITE : side::BLACK;
  5359.       eval = mul_shift(eval, draw_mul(winner, bd, pi), 4);
  5360.    }
  5361.  
  5362.    assert(eval >= score::EVAL_MIN && eval <= score::EVAL_MAX);
  5363.    return eval;
  5364. }
  5365.  
  5366. int eval(board::Board & bd, Table & table, pawn::Table & pawn_table) {
  5367.    return score::side_score(table.eval(bd, pawn_table), bd.turn());
  5368. }
  5369.  
  5370. void init() {
  5371.  
  5372.    small_centre  = 0;
  5373.    medium_centre = 0;
  5374.    large_centre  = 0;
  5375.  
  5376.    for (int sq = 0; sq < square::SIZE; sq++) {
  5377.  
  5378.       int fl = square::file(sq);
  5379.       int rk = square::rank(sq);
  5380.  
  5381.       if (fl >= square::FILE_D && fl <= square::FILE_E && rk >= square::RANK_4 && rk <= square::RANK_5) {
  5382.          bit::set(small_centre, sq);
  5383.       }
  5384.  
  5385.       if (fl >= square::FILE_C && fl <= square::FILE_F && rk >= square::RANK_3 && rk <= square::RANK_6) {
  5386.          bit::set(medium_centre, sq);
  5387.       }
  5388.  
  5389.       if (fl >= square::FILE_B && fl <= square::FILE_G && rk >= square::RANK_2 && rk <= square::RANK_7) {
  5390.          bit::set(large_centre, sq);
  5391.       }
  5392.    }
  5393.  
  5394.    large_centre  &= ~medium_centre;
  5395.    medium_centre &= ~small_centre;
  5396.  
  5397.    centre_0 = small_centre | large_centre;
  5398.    centre_1 = small_centre | medium_centre;
  5399.  
  5400.    side_area[side::WHITE] = 0;
  5401.    side_area[side::BLACK] = 0;
  5402.  
  5403.    for (int sq = 0; sq < square::SIZE; sq++) {
  5404.       if (square::rank(sq) <= square::RANK_4) {
  5405.          bit::set(side_area[side::WHITE], sq);
  5406.       } else {
  5407.          bit::set(side_area[side::BLACK], sq);
  5408.       }
  5409.    }
  5410.  
  5411.    for (int ks = 0; ks < square::SIZE; ks++) {
  5412.  
  5413.       king_area[side::WHITE][ks] = 0;
  5414.       king_area[side::BLACK][ks] = 0;
  5415.  
  5416.       for (int as = 0; as < square::SIZE; as++) {
  5417.  
  5418.          int df = square::file(as) - square::file(ks);
  5419.          int dr = square::rank(as) - square::rank(ks);
  5420.  
  5421.          if (std::abs(df) <= 1 && dr >= -1 && dr <= +2) {
  5422.             bit::set(king_area[side::WHITE][ks], as);
  5423.          }
  5424.  
  5425.          if (std::abs(df) <= 1 && dr >= -2 && dr <= +1) {
  5426.             bit::set(king_area[side::BLACK][ks], as);
  5427.          }
  5428.       }
  5429.    }
  5430.  
  5431.    for (int i = 0; i < 32; i++) {
  5432.       double x = double(i) * 0.5;
  5433.       double y = 1.0 - std::exp(-x);
  5434.       mob_weight[i] = util::round(y * 512.0) - 256;
  5435.    }
  5436.  
  5437.    for (int i = 0; i < 8; i++) {
  5438.       double x = double(i) - 3.0;
  5439.       double y = 1.0 / (1.0 + std::exp(-x));
  5440.       dist_weight[i] = util::round(y * 7.0 * 256.0);
  5441.    }
  5442. }
  5443.  
  5444. }
  5445.  
  5446. namespace uci {
  5447.  
  5448. bool infinite; // for UCI-design mistake :(
  5449.  
  5450. }
  5451.  
  5452. namespace search {
  5453.  
  5454. const int MAX_DEPTH = 100;
  5455. const int MAX_PLY = 100;
  5456. const int NODE_PERIOD = 1024;
  5457.  
  5458. const int MAX_THREADS = 16;
  5459.  
  5460. class Abort : public std::exception { // SP fail-high exception
  5461.  
  5462. };
  5463.  
  5464. void update_current ();
  5465.  
  5466. class PV {
  5467.  
  5468. private:
  5469.  
  5470.    static const int SIZE = MAX_PLY;
  5471.  
  5472.    int p_size;
  5473.    int p_move[SIZE];
  5474.  
  5475. public:
  5476.  
  5477.    PV() {
  5478.       clear();
  5479.    }
  5480.  
  5481.    void operator=(const PV & pv) {
  5482.       clear();
  5483.       add(pv);
  5484.    }
  5485.  
  5486.    void clear() {
  5487.       p_size = 0;
  5488.    }
  5489.  
  5490.    void add(int mv) {
  5491.       if (p_size < SIZE) {
  5492.          p_move[p_size++] = mv;
  5493.       }
  5494.    }
  5495.  
  5496.    void add(const PV & pv) {
  5497.       for (int pos = 0; pos < pv.size(); pos++) {
  5498.          int mv = pv.move(pos);
  5499.          add(mv);
  5500.       }
  5501.    }
  5502.  
  5503.    void cat(int mv, const PV & pv) {
  5504.       clear();
  5505.       add(mv);
  5506.       add(pv);
  5507.    }
  5508.  
  5509.    int size() const {
  5510.       return p_size;
  5511.    }
  5512.  
  5513.    int move(int pos) const {
  5514.       return p_move[pos];
  5515.    }
  5516.  
  5517.    std::string to_can() const {
  5518.  
  5519.       std::string s;
  5520.  
  5521.       for (int pos = 0; pos < size(); pos++) {
  5522.          int mv = move(pos);
  5523.          if (pos != 0) s += " ";
  5524.          s += move::to_can(mv);
  5525.       }
  5526.  
  5527.       return s;
  5528.    }
  5529.  
  5530. };
  5531.  
  5532. struct Time {
  5533.    bool depth_limited;
  5534.    bool node_limited;
  5535.    bool time_limited;
  5536.    int depth_limit;
  5537.    int64 node_limit;
  5538.    int64 time_limit;
  5539.    bool smart;
  5540.    bool ponder;
  5541.    bool flag;
  5542.    int64 limit_0;
  5543.    int64 limit_1;
  5544.    int64 limit_2;
  5545.    int last_score;
  5546.    bool drop;
  5547.    util::Timer timer;
  5548. };
  5549.  
  5550. struct Current {
  5551.  
  5552.    int depth;
  5553.    int max_ply;
  5554.    int64 node;
  5555.    int time;
  5556.    int speed;
  5557.  
  5558.    int move;
  5559.    int pos;
  5560.    int size;
  5561.    bool fail_high;
  5562.  
  5563.    int last_time;
  5564. };
  5565.  
  5566. struct Best {
  5567.    int depth;
  5568.    int move;
  5569.    int score;
  5570.    int flags;
  5571.    PV pv;
  5572. };
  5573.  
  5574. Time p_time;
  5575. Current current;
  5576. Best best;
  5577.  
  5578. class Search_Global : public util::Lockable {
  5579.  
  5580. public:
  5581.  
  5582.    trans::Table trans;
  5583.    sort::History history;
  5584.  
  5585. };
  5586.  
  5587. Search_Global sg;
  5588.  
  5589. class SMP : public util::Lockable {
  5590.  
  5591. };
  5592.  
  5593. SMP smp;
  5594.  
  5595. class Search_Local;
  5596. class Split_Point;
  5597.  
  5598. //void clear_iteration(Search_Local & sl); // Pierre-Marie Baty -- function not found
  5599. void search_root(Search_Local & sl, gen::List & ml, int depth, int alpha, int beta);
  5600. int search(Search_Local & sl, int depth, int alpha, int beta, PV & pv);
  5601. int split(Search_Local & sl, int depth, int old_alpha, int alpha, int beta, PV & pv, gen_sort::List & todo, const gen::List & done, int bs, int bm);
  5602. void master_split_point(Search_Local & sl, Split_Point & sp);
  5603. void search_split_point(Search_Local & sl, Split_Point & sp);
  5604. int qs_static(Search_Local & sl, int beta, int gain);
  5605. void inc_node(Search_Local & sl);
  5606. bool poll();
  5607. void move(Search_Local & sl, int mv);
  5608. void undo(Search_Local & sl);
  5609. int eval(Search_Local & sl);
  5610. int extension(Search_Local & sl, int mv, int depth, bool pv_node);
  5611. static int reduction(Search_Local & sl, int mv, int depth, bool pv_node, bool in_check, int searched_size, bool dangerous);
  5612. void gen_sort(Search_Local & sl, gen::List & ml);
  5613.  
  5614. void sg_abort ();
  5615.  
  5616. void          sl_init_early (Search_Local & sl, int id);
  5617. void          sl_init_late  (Search_Local & sl);
  5618. void          sl_set_root   (Search_Local & sl, const board::Board & bd);
  5619. void          sl_signal     (Search_Local & sl);
  5620. bool          sl_stop       (const Search_Local & sl);
  5621. bool          sl_idle       (const Search_Local & sl, Split_Point * sp);
  5622. void          sl_push       (Search_Local & sl, Split_Point & sp);
  5623. void          sl_pop        (Search_Local & sl);
  5624. Split_Point & sl_top        (const Search_Local & sl);
  5625.  
  5626. class Split_Point : public util::Lockable {
  5627.  
  5628. private:
  5629.  
  5630.    Search_Local * p_master;
  5631.    Split_Point * p_parent;
  5632.  
  5633.    board::Board p_board;
  5634.    int p_depth;
  5635.    int p_old_alpha;
  5636.    int volatile p_alpha;
  5637.    int p_beta;
  5638.  
  5639.    gen::List p_todo;
  5640.    gen::List p_done;
  5641.  
  5642.    int volatile p_workers;
  5643.    int volatile p_sent;
  5644.    int volatile p_received;
  5645.  
  5646.    int volatile p_bs;
  5647.    int volatile p_bm;
  5648.    PV p_pv;
  5649.  
  5650. public:
  5651.  
  5652.    void init_root(Search_Local & master) {
  5653.  
  5654.       p_master = &master;
  5655.       p_parent = NULL;
  5656.  
  5657.       p_bs = score::NONE;
  5658.       p_beta = score::MAX;
  5659.       p_todo.clear();
  5660.  
  5661.       p_workers = 1;
  5662.       p_received = -1; // HACK
  5663.    }
  5664.  
  5665.    void init(Search_Local & master, Split_Point & parent, const board::Board & bd, int depth, int old_alpha, int alpha, int beta, gen_sort::List & todo, const gen::List & done, int bs, int bm, const PV & pv) {
  5666.  
  5667.       assert(depth > 4);
  5668.       assert(old_alpha <= alpha);
  5669.       assert(alpha < beta);
  5670.       assert(done.size() != 0);
  5671.       assert(bs != score::NONE);
  5672.  
  5673.       p_master = &master;
  5674.       p_parent = &parent;
  5675.  
  5676.       p_board = bd;
  5677.       p_depth = depth;
  5678.       p_old_alpha = old_alpha;
  5679.       p_alpha = alpha;
  5680.       p_beta = beta;
  5681.  
  5682.       p_todo.clear();
  5683.  
  5684.       for (int mv = todo.next(); mv != move::NONE; mv = todo.next()) {
  5685.          p_todo.add(mv);
  5686.       }
  5687.  
  5688.       p_done = done;
  5689.  
  5690.       p_workers = 0;
  5691.       p_sent = 0;
  5692.       p_received = 0;
  5693.  
  5694.       p_bs = bs;
  5695.       p_bm = bm;
  5696.       p_pv = pv;
  5697.    }
  5698.  
  5699.    void enter() {
  5700.       lock();
  5701.       p_workers++;
  5702.       unlock();
  5703.    }
  5704.  
  5705.    void leave() {
  5706.  
  5707.       lock();
  5708.  
  5709.       assert(p_workers > 0);
  5710.       p_workers--;
  5711.  
  5712.       if (p_workers == 0) sl_signal(*p_master);
  5713.  
  5714.       unlock();
  5715.    }
  5716.  
  5717.    int next_move() {
  5718.  
  5719.       // lock();
  5720.  
  5721.       int mv = move::NONE;
  5722.  
  5723.       if (p_bs < p_beta && p_sent < p_todo.size()) {
  5724.          mv = p_todo.move(p_sent++);
  5725.       }
  5726.  
  5727.       // unlock();
  5728.  
  5729.       return mv;
  5730.    }
  5731.  
  5732.    void update_root() {
  5733.       lock();
  5734.       p_received = 0;
  5735.       p_workers = 0;
  5736.       unlock();
  5737.    }
  5738.  
  5739.    void update(int mv, int sc, const PV & pv) {
  5740.  
  5741.       lock();
  5742.  
  5743.       p_done.add(mv);
  5744.  
  5745.       assert(p_received < p_todo.size());
  5746.       p_received++;
  5747.  
  5748.       if (sc > p_bs) {
  5749.  
  5750.          p_bs = sc;
  5751.          p_pv.cat(mv, pv);
  5752.  
  5753.          if (sc > p_alpha) {
  5754.             p_bm = mv;
  5755.             p_alpha = sc;
  5756.          }
  5757.       }
  5758.  
  5759.       unlock();
  5760.    }
  5761.  
  5762.    const board::Board & board() const { return p_board; }
  5763.  
  5764.    Split_Point * parent() const { return p_parent; }
  5765.  
  5766.    int  depth()     const { return p_depth; }
  5767.    int  alpha()     const { return p_alpha; }
  5768.    int  beta()      const { return p_beta; }
  5769.    int  old_alpha() const { return p_old_alpha; }
  5770.    int  bs()        const { return p_bs; }
  5771.    int  bm()        const { return p_bm; }
  5772.    bool solved()    const { return p_bs >= p_beta || p_received == p_todo.size(); }
  5773.    bool free()      const { return p_workers == 0; }
  5774.  
  5775.    const gen::List & searched() const { return p_done; }
  5776.    int searched_size() const { return p_done.size(); }
  5777.  
  5778.    int result(PV & pv) const {
  5779.       pv = p_pv;
  5780.       return p_bs;
  5781.    }
  5782.  
  5783. };
  5784.  
  5785. Split_Point root_sp;
  5786.  
  5787. class Search_Local : public util::Waitable {
  5788.  
  5789. public:
  5790.  
  5791.    int id;
  5792.    std::thread thread;
  5793.  
  5794.    bool volatile todo;
  5795.    Split_Point * volatile todo_sp;
  5796.  
  5797.    board::Board board;
  5798.    sort::Killer killer;
  5799.    pawn::Table pawn_table;
  5800.    eval::Table eval_table;
  5801.  
  5802.    int64 volatile node;
  5803.    int volatile max_ply;
  5804.  
  5805.    Split_Point msp_stack[16];
  5806.    int msp_stack_size;
  5807.  
  5808.    Split_Point * ssp_stack[64];
  5809.    int ssp_stack_size;
  5810. };
  5811.  
  5812. Search_Local p_sl[MAX_THREADS];
  5813.  
  5814. void new_search() {
  5815.  
  5816.    p_time.depth_limited = true;
  5817.    p_time.node_limited = false;
  5818.    p_time.time_limited = false;
  5819.  
  5820.    p_time.depth_limit = MAX_DEPTH - 1;
  5821.  
  5822.    p_time.smart = false;
  5823.    p_time.ponder = false;
  5824. }
  5825.  
  5826. void set_depth_limit(int depth) {
  5827.    p_time.depth_limited = true;
  5828.    p_time.depth_limit = depth;
  5829. }
  5830.  
  5831. void set_node_limit(int64 node) {
  5832.    p_time.node_limited = true;
  5833.    p_time.node_limit = node;
  5834. }
  5835.  
  5836. void set_time_limit(int64 time) {
  5837.    p_time.time_limited = true;
  5838.    p_time.time_limit = time;
  5839. }
  5840.  
  5841. void set_ponder() {
  5842.    p_time.ponder = true;
  5843. }
  5844.  
  5845. void clear() {
  5846.  
  5847.    p_time.flag = false;
  5848.    p_time.timer.reset();
  5849.    p_time.timer.start();
  5850.  
  5851.    current.depth = 0;
  5852.    current.max_ply = 0;
  5853.    current.node = 0;
  5854.    current.time = 0;
  5855.    current.speed = 0;
  5856.  
  5857.    current.move = move::NONE;
  5858.    current.pos = 0;
  5859.    current.size = 0;
  5860.    current.fail_high = false;
  5861.  
  5862.    current.last_time = 0;
  5863.  
  5864.    best.depth = 0;
  5865.    best.move = move::NONE;
  5866.    best.score = score::NONE;
  5867.    best.flags = score::FLAGS_NONE;
  5868.    best.pv.clear();
  5869. }
  5870.  
  5871. void update_current() {
  5872.  
  5873.    int64 node = 0;
  5874.    int max_ply = 0;
  5875.  
  5876.    for (int id = 0; id < engine::engine.threads; id++) {
  5877.  
  5878.       Search_Local & sl = p_sl[id];
  5879.  
  5880.       node += sl.node;
  5881.       if (sl.max_ply > max_ply) max_ply = sl.max_ply;
  5882.    }
  5883.  
  5884.    current.node = node;
  5885.    current.max_ply = max_ply;
  5886.  
  5887.    current.time = p_time.timer.elapsed();
  5888.    current.speed = (current.time < 10) ? 0 : int(current.node * 1000 / current.time);
  5889. }
  5890.  
  5891. void write_pv(Best & best) {
  5892.  
  5893.    sg.lock();
  5894.  
  5895.    std::cout << "info";
  5896.    std::cout << " depth " << best.depth;
  5897.    std::cout << " seldepth " << current.max_ply;
  5898.    std::cout << " nodes " << current.node;
  5899.    std::cout << " time " << current.time;
  5900.  
  5901.    if (score::is_mate(best.score)) {
  5902.       std::cout << " score mate " << score::signed_mate(best.score);
  5903.    } else {
  5904.       std::cout << " score cp " << best.score;
  5905.    }
  5906.    if (best.flags == score::FLAGS_LOWER) std::cout << " lowerbound";
  5907.    if (best.flags == score::FLAGS_UPPER) std::cout << " upperbound";
  5908.  
  5909.    std::cout << " pv " << best.pv.to_can();
  5910.    std::cout << std::endl;
  5911.  
  5912.    sg.unlock();
  5913. }
  5914.  
  5915. void write_info() {
  5916.  
  5917.    sg.lock();
  5918.  
  5919.    std::cout << "info";
  5920.    std::cout << " depth " << current.depth;
  5921.    std::cout << " seldepth " << current.max_ply;
  5922.    std::cout << " currmove " << move::to_can(current.move);
  5923.    std::cout << " currmovenumber " << current.pos + 1;
  5924.    std::cout << " nodes " << current.node;
  5925.    std::cout << " time " << current.time;
  5926.    if (current.speed != 0) std::cout << " nps " << current.speed;
  5927.    std::cout << " hashfull " << sg.trans.used();
  5928.    std::cout << std::endl;
  5929.  
  5930.    sg.unlock();
  5931. }
  5932.  
  5933. void write_info_opt() {
  5934.  
  5935.    int time = current.time;
  5936.  
  5937.    if (time >= current.last_time + 1000) {
  5938.       write_info();
  5939.       current.last_time = time - time % 1000;
  5940.    }
  5941. }
  5942.  
  5943. void depth_start(int depth) {
  5944.    current.depth = depth;
  5945. }
  5946.  
  5947. void depth_end() {
  5948. }
  5949.  
  5950. void move_start(int mv, int pos, int size) {
  5951.  
  5952.    assert(size > 0);
  5953.    assert(pos < size);
  5954.  
  5955.    current.move = mv;
  5956.    current.pos = pos;
  5957.    current.size = size;
  5958.  
  5959.    current.fail_high = false;
  5960. }
  5961.  
  5962. void move_fail_high() {
  5963.    current.fail_high = true;
  5964.    p_time.flag = false;
  5965. }
  5966.  
  5967. void move_end() {
  5968.    current.fail_high = false;
  5969. }
  5970.  
  5971. void update_best(Best & best, int sc, int flags, const PV & pv) {
  5972.  
  5973.    assert(sc != score::NONE);
  5974.    assert(pv.size() != 0);
  5975.  
  5976.    p_time.drop = flags == score::FLAGS_UPPER || (sc <= p_time.last_score - 30 && current.size > 1);
  5977.  
  5978.    if (pv.move(0) != best.move || p_time.drop) {
  5979.       p_time.flag = false;
  5980.    }
  5981.  
  5982.    best.depth = current.depth;
  5983.    best.move = pv.move(0);
  5984.    best.score = sc;
  5985.    best.flags = flags;
  5986.    best.pv = pv;
  5987. }
  5988.  
  5989. void search_end() {
  5990.    p_time.timer.stop();
  5991.    update_current();
  5992.    write_info();
  5993. }
  5994.  
  5995. void idle_loop(Search_Local & sl, Split_Point & wait_sp) {
  5996.  
  5997.    sl_push(sl, wait_sp);
  5998.  
  5999.    while (true) {
  6000.  
  6001.       sl.lock();
  6002.  
  6003.       assert(sl.todo);
  6004.       assert(sl.todo_sp == NULL);
  6005.  
  6006.       sl.todo = false;
  6007.       sl.todo_sp = NULL;
  6008.  
  6009.       while (!wait_sp.free() && sl.todo_sp == NULL) {
  6010.          sl.wait();
  6011.       }
  6012.  
  6013.       Split_Point & sp = *sl.todo_sp;
  6014.       sl.todo = true;
  6015.       sl.todo_sp = NULL;
  6016.  
  6017.       sl.unlock();
  6018.  
  6019.       if (&sp == NULL) {
  6020.          break;
  6021.       }
  6022.  
  6023.       // sp.enter();
  6024.  
  6025.       sl_push(sl, sp);
  6026.  
  6027.       try {
  6028.          search_split_point(sl, sp);
  6029.       } catch (const Abort & /* abort */) {
  6030.          // no-op
  6031.       }
  6032.  
  6033.       sl_pop(sl);
  6034.  
  6035.       sp.leave();
  6036.    }
  6037.  
  6038.    sl_pop(sl);
  6039. }
  6040.  
  6041. void helper_program(Search_Local * sl) {
  6042.    sl_init_late(*sl);
  6043.    idle_loop(*sl, root_sp);
  6044. }
  6045.  
  6046. bool can_split(Search_Local & master, Split_Point & parent) {
  6047.  
  6048.    if (engine::engine.threads == 1) return false;
  6049.    if (master.msp_stack_size >= 16) return false;
  6050.    if (sl_stop(master)) return false;
  6051.  
  6052.    for (int id = 0; id < engine::engine.threads; id++) {
  6053.       Search_Local & worker = p_sl[id];
  6054.       if (&worker != &master && sl_idle(worker, &parent)) return true;
  6055.    }
  6056.  
  6057.    return false;
  6058. }
  6059.  
  6060. void send_work(Search_Local & worker, Split_Point & sp) {
  6061.  
  6062.    worker.lock();
  6063.  
  6064.    if (sl_idle(worker, sp.parent())) {
  6065.  
  6066.       sp.enter();
  6067.  
  6068.       worker.todo = true;
  6069.       worker.todo_sp = &sp;
  6070.       worker.signal();
  6071.    }
  6072.  
  6073.    worker.unlock();
  6074. }
  6075.  
  6076. void init_sg() {
  6077.    sg.history.clear();
  6078. }
  6079.  
  6080. void search_root(Search_Local & sl, gen::List & ml, int depth, int alpha, int beta) {
  6081.  
  6082.    assert(depth > 0 && depth < MAX_DEPTH);
  6083.    assert(alpha < beta);
  6084.  
  6085.    board::Board & bd = sl.board;
  6086.    assert(attack::is_legal(bd));
  6087.  
  6088.    bool pv_node = true;
  6089.  
  6090.    int bs = score::NONE;
  6091.    int bm = move::NONE;
  6092.    int old_alpha = alpha;
  6093.  
  6094.    // transposition table
  6095.  
  6096.    hash_t key = 0;
  6097.  
  6098.    if (depth >= 0) {
  6099.       key = bd.key();
  6100.    }
  6101.  
  6102.    // move loop
  6103.  
  6104.    bool in_check = attack::is_in_check(bd);
  6105.  
  6106.    int searched_size = 0;
  6107.  
  6108.    for (int pos = 0; pos < ml.size(); pos++) {
  6109.  
  6110.       int mv = ml.move(pos);
  6111.  
  6112.       bool dangerous = in_check || move::is_tactical(mv) || move::is_check(mv, bd) || move::is_castling(mv) || move::is_pawn_push(mv, bd);
  6113.  
  6114.       int ext = extension(sl, mv, depth, pv_node);
  6115.       int red = reduction(sl, mv, depth, pv_node, in_check, searched_size, dangerous); // LMR
  6116.  
  6117.       if (ext != 0) red = 0;
  6118.       assert(ext == 0 || red == 0);
  6119.  
  6120.       int sc;
  6121.       PV npv;
  6122.  
  6123.       move_start(mv, pos, ml.size());
  6124.  
  6125.       move(sl, mv);
  6126.  
  6127.       if ((pv_node && searched_size != 0) || red != 0) {
  6128.  
  6129.          sc = -search(sl, depth + ext - red - 1, -alpha - 1, -alpha, npv);
  6130.  
  6131.          if (sc > alpha) { // PVS/LMR re-search
  6132.             move_fail_high();
  6133.             sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6134.          }
  6135.  
  6136.       } else {
  6137.  
  6138.          sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6139.       }
  6140.  
  6141.       undo(sl);
  6142.  
  6143.       move_end();
  6144.  
  6145.       searched_size++;
  6146.  
  6147.       if (sc > bs) {
  6148.  
  6149.          bs = sc;
  6150.  
  6151.          PV pv;
  6152.          pv.cat(mv, npv);
  6153.  
  6154.          update_best(best, sc, score::flags(sc, alpha, beta), pv);
  6155.  
  6156.          update_current();
  6157.          write_pv(best);
  6158.  
  6159.          if (sc > alpha) {
  6160.  
  6161.             bm = mv;
  6162.             alpha = sc;
  6163.  
  6164.             // ml.set_score(pos, sc); // not needed
  6165.             ml.move_to_front(pos);
  6166.  
  6167.             if (depth >= 0) {
  6168.                sg.trans.store(key, depth, bd.ply(), mv, sc, score::FLAGS_LOWER);
  6169.             }
  6170.  
  6171.             if (sc >= beta) return;
  6172.          }
  6173.       }
  6174.    }
  6175.  
  6176.    assert(bs != score::NONE);
  6177.    assert(bs < beta);
  6178.  
  6179.    if (depth >= 0) {
  6180.       int flags = score::flags(bs, old_alpha, beta);
  6181.       sg.trans.store(key, depth, bd.ply(), bm, bs, flags);
  6182.    }
  6183. }
  6184.  
  6185. int search(Search_Local & sl, int depth, int alpha, int beta, PV & pv) {
  6186.  
  6187.    assert(depth < MAX_DEPTH);
  6188.    assert(alpha < beta);
  6189.  
  6190.    board::Board & bd = sl.board;
  6191.    assert(attack::is_legal(bd));
  6192.  
  6193.    pv.clear();
  6194.  
  6195.    bool pv_node = depth > 0 && beta != alpha + 1;
  6196.  
  6197.    // mate-distance pruning
  6198.  
  6199.    {
  6200.       int sc = score::from_trans(score::MATE - 1, bd.ply());
  6201.  
  6202.       if (sc < beta) {
  6203.  
  6204.          beta = sc;
  6205.  
  6206.          if (sc <= alpha) {
  6207.             return sc;
  6208.          }
  6209.       }
  6210.    }
  6211.  
  6212.    // transposition table
  6213.  
  6214.    if (bd.is_draw()) return 0;
  6215.  
  6216.    attack::Attacks attacks;
  6217.    attack::init_attacks(attacks, bd);
  6218.    bool in_check = attacks.size != 0;
  6219.  
  6220.    bool use_trans = depth >= 0;
  6221.    int trans_depth = depth;
  6222.  
  6223.    if (depth < 0 && in_check) {
  6224.       use_trans = true;
  6225.       trans_depth = 0;
  6226.    }
  6227.  
  6228.    hash_t key = 0;
  6229.    int trans_move = move::NONE;
  6230.  
  6231.    if (use_trans) {
  6232.  
  6233.       key = bd.key();
  6234.  
  6235.       int score;
  6236.       int flags;
  6237.  
  6238.       if (sg.trans.retrieve(key, trans_depth, bd.ply(), trans_move, score, flags) && !pv_node) { // assigns trans_move #
  6239.          if (flags == score::FLAGS_LOWER && score >= beta)  return score;
  6240.          if (flags == score::FLAGS_UPPER && score <= alpha) return score;
  6241.          if (flags == score::FLAGS_EXACT) return score;
  6242.       }
  6243.    }
  6244.  
  6245.    // ply limit
  6246.  
  6247.    if (bd.ply() >= MAX_PLY) return eval(sl);
  6248.  
  6249.    // beta pruning
  6250.  
  6251.    if (!pv_node && depth > 0 && depth <= 3 && !score::is_mate(beta) && !in_check) {
  6252.  
  6253.       int sc = eval(sl) - depth * 50;
  6254.  
  6255.       if (sc >= beta) {
  6256.          return sc;
  6257.       }
  6258.    }
  6259.  
  6260.    // null-move pruning
  6261.  
  6262.    if (!pv_node && depth > 0 && !score::is_mate(beta) && !in_check && !material::lone_king(bd.turn(), bd) && eval(sl) >= beta) {
  6263.  
  6264.       bd.move_null(); // TODO: use sl?
  6265.  
  6266.        int sc = score::MIN;
  6267.  
  6268.       if (depth <= 3) { // static
  6269.          sc = -qs_static(sl, -beta + 1, 100);
  6270.       } else { // dynamic
  6271.          PV npv;
  6272.          sc = -search(sl, depth - 3 - 1, -beta, -beta + 1, npv);
  6273.       }
  6274.  
  6275.       bd.undo_null(); // TODO: use sl?
  6276.  
  6277.       if (sc >= beta) {
  6278.  
  6279.          if (use_trans) {
  6280.             sg.trans.store(key, trans_depth, bd.ply(), move::NONE, sc, score::FLAGS_LOWER);
  6281.          }
  6282.  
  6283.          return sc;
  6284.       }
  6285.    }
  6286.  
  6287.    // stand pat
  6288.  
  6289.    int bs = score::NONE;
  6290.    int bm = move::NONE;
  6291.    int old_alpha = alpha;
  6292.    int val = score::NONE; // for delta pruning
  6293.  
  6294.    if (depth <= 0 && !in_check) {
  6295.  
  6296.       bs = eval(sl);
  6297.       val = bs + 100; // QS-DP margin
  6298.  
  6299.       if (bs > alpha) {
  6300.  
  6301.          alpha = bs;
  6302.  
  6303.          if (bs >= beta) {
  6304.             return bs;
  6305.          }
  6306.       }
  6307.    }
  6308.  
  6309.    // futility-pruning condition
  6310.  
  6311.    bool use_fp = false;
  6312.  
  6313.    if (depth > 0 && depth <= 8 && !score::is_mate(alpha) && !in_check) {
  6314.  
  6315.       int sc = eval(sl) + depth * 40;
  6316.       val = sc + 50; // FP-DP margin, extra 50 for captures
  6317.  
  6318.       if (sc <= alpha) {
  6319.          bs = sc;
  6320.          use_fp = true;
  6321.       }
  6322.    }
  6323.  
  6324.    if (depth <= 0 && !in_check) { // unify FP and QS
  6325.       use_fp = true;
  6326.    }
  6327.  
  6328.    // IID
  6329.  
  6330.    if (pv_node && depth >= 3 && trans_move == move::NONE) {
  6331.  
  6332.       PV npv;
  6333.       int sc = search(sl, depth - 2, alpha, beta, npv); // to keep PV-node property
  6334.  
  6335.       if (sc > alpha && npv.size() != 0) {
  6336.          trans_move = npv.move(0);
  6337.       }
  6338.    }
  6339.  
  6340.    // move loop
  6341.  
  6342.    gen_sort::List ml;
  6343.    ml.init(depth, bd, attacks, trans_move, sl.killer, sg.history, use_fp);
  6344.  
  6345.    gen::List searched;
  6346.  
  6347.    for (int mv = ml.next(); mv != move::NONE; mv = ml.next()) {
  6348.  
  6349.       bool dangerous = in_check || move::is_tactical(mv) || move::is_check(mv, bd) || move::is_castling(mv) || move::is_pawn_push(mv, bd) || ml.is_candidate();
  6350.  
  6351.       if (use_fp && move::is_tactical(mv) && !move::is_check(mv, bd) && val + move::see_max(mv) <= alpha) { // delta pruning
  6352.          continue;
  6353.       }
  6354.  
  6355.       if (use_fp && !move::is_safe(mv, bd)) { // SEE pruning
  6356.          continue;
  6357.       }
  6358.  
  6359.       if (!pv_node && depth > 0 && depth <= 3 && !score::is_mate(bs) && searched.size() >= depth * 4 && !dangerous) { // late-move pruning
  6360.          continue;
  6361.       }
  6362.  
  6363.       int ext = extension(sl, mv, depth, pv_node);
  6364.       int red = reduction(sl, mv, depth, pv_node, in_check, searched.size(), dangerous); // LMR
  6365.  
  6366.       if (ext != 0) red = 0;
  6367.       assert(ext == 0 || red == 0);
  6368.  
  6369.       int sc;
  6370.       PV npv;
  6371.  
  6372.       move(sl, mv);
  6373.  
  6374.       if ((pv_node && searched.size() != 0) || red != 0) {
  6375.  
  6376.          sc = -search(sl, depth + ext - red - 1, -alpha - 1, -alpha, npv);
  6377.  
  6378.          if (sc > alpha) { // PVS/LMR re-search
  6379.             sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6380.          }
  6381.  
  6382.       } else {
  6383.  
  6384.          sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6385.       }
  6386.  
  6387.       undo(sl);
  6388.  
  6389.       searched.add(mv);
  6390.  
  6391.       if (sc > bs) {
  6392.  
  6393.          bs = sc;
  6394.          pv.cat(mv, npv);
  6395.  
  6396.          if (sc > alpha) {
  6397.  
  6398.             bm = mv;
  6399.             alpha = sc;
  6400.  
  6401.             if (use_trans) {
  6402.                sg.trans.store(key, trans_depth, bd.ply(), mv, sc, score::FLAGS_LOWER);
  6403.             }
  6404.  
  6405.             if (sc >= beta) {
  6406.  
  6407.                if (depth > 0 && !in_check && !move::is_tactical(mv)) {
  6408.                   sl.killer.add(mv, bd.ply());
  6409.                   sg.history.add(mv, searched, bd);
  6410.                }
  6411.  
  6412.                return sc;
  6413.             }
  6414.          }
  6415.       }
  6416.  
  6417.       if (depth >= 6 && !in_check && !use_fp && can_split(sl, sl_top(sl))) {
  6418.          return split(sl, depth, old_alpha, alpha, beta, pv, ml, searched, bs, bm);
  6419.       }
  6420.    }
  6421.  
  6422.    if (bs == score::NONE) {
  6423.       assert(depth > 0 || in_check);
  6424.       return in_check ? -score::MATE + bd.ply() : 0;
  6425.    }
  6426.  
  6427.    assert(bs < beta);
  6428.  
  6429.    if (use_trans) {
  6430.       int flags = score::flags(bs, old_alpha, beta);
  6431.       sg.trans.store(key, trans_depth, bd.ply(), bm, bs, flags);
  6432.    }
  6433.  
  6434.    return bs;
  6435. }
  6436.  
  6437. int split(Search_Local & master, int depth, int old_alpha, int alpha, int beta, PV & pv, gen_sort::List & todo, const gen::List & done, int bs, int bm) {
  6438.  
  6439.    smp.lock();
  6440.  
  6441.    assert(master.msp_stack_size < 16);
  6442.    Split_Point & sp = master.msp_stack[master.msp_stack_size++];
  6443.  
  6444.    Split_Point & parent = sl_top(master);
  6445.  
  6446.    sp.init(master, parent, master.board, depth, old_alpha, alpha, beta, todo, done, bs, bm, pv);
  6447.  
  6448.    for (int id = 0; id < engine::engine.threads; id++) {
  6449.  
  6450.       Search_Local & worker = p_sl[id];
  6451.  
  6452.       if (&worker != &master && sl_idle(worker, &parent)) {
  6453.          send_work(worker, sp);
  6454.       }
  6455.    }
  6456.  
  6457.    smp.unlock();
  6458.  
  6459.    try {
  6460.       master_split_point(master, sp);
  6461.    } catch (const Abort & /* abort */) {
  6462.       // no-op
  6463.    }
  6464.  
  6465.    assert(master.msp_stack_size > 0);
  6466.    assert(&master.msp_stack[master.msp_stack_size - 1] == &sp);
  6467.    master.msp_stack_size--;
  6468.  
  6469.    return sp.result(pv);
  6470. }
  6471.  
  6472. void master_split_point(Search_Local & sl, Split_Point & sp) {
  6473.  
  6474.    sp.enter();
  6475.  
  6476.    sl_push(sl, sp);
  6477.  
  6478.    try {
  6479.       search_split_point(sl, sp);
  6480.    } catch (const Abort & /* abort */) {
  6481.       // no-op
  6482.    }
  6483.  
  6484.    sl_pop(sl);
  6485.  
  6486.    sp.leave();
  6487.  
  6488.    idle_loop(sl, sp);
  6489.    sl.board = sp.board();
  6490.  
  6491.    assert(sp.free());
  6492.  
  6493.    // update move-ordering tables
  6494.  
  6495.    board::Board & bd = sl.board;
  6496.  
  6497.    int depth = sp.depth();
  6498.    int ply = bd.ply();
  6499.  
  6500.    int bs = sp.bs();
  6501.    int bm = sp.bm();
  6502.  
  6503.    assert(bs != score::NONE);
  6504.  
  6505.    if (bs >= sp.beta() && depth > 0 && !attack::is_in_check(bd) && !move::is_tactical(bm)) {
  6506.       sl.killer.add(bm, ply);
  6507.       sg.history.add(bm, sp.searched(), bd);
  6508.    }
  6509.  
  6510.    if (depth >= 0) {
  6511.       int flags = score::flags(bs, sp.old_alpha(), sp.beta());
  6512.       sg.trans.store(bd.key(), depth, ply, bm, bs, flags);
  6513.    }
  6514. }
  6515.  
  6516. void search_split_point(Search_Local & sl, Split_Point & sp) {
  6517.  
  6518.    board::Board & bd = sl.board;
  6519.    bd = sp.board();
  6520.  
  6521.    int depth = sp.depth();
  6522.    int old_alpha = sp.old_alpha();
  6523.    int beta = sp.beta();
  6524.  
  6525.    bool pv_node = depth > 0 && beta != old_alpha + 1;
  6526.  
  6527.    bool in_check = attack::is_in_check(bd);
  6528.  
  6529.    while (true) {
  6530.  
  6531.       sp.lock();
  6532.       int mv = sp.next_move();
  6533.       int alpha = sp.alpha();
  6534.       int searched_size = sp.searched_size();
  6535.       sp.unlock();
  6536.  
  6537.       if (mv == move::NONE) {
  6538.          break;
  6539.       }
  6540.  
  6541.       assert(alpha < beta);
  6542.  
  6543.       bool dangerous = in_check || move::is_tactical(mv) || move::is_check(mv, bd) || move::is_castling(mv) || move::is_pawn_push(mv, bd);
  6544.  
  6545.       int ext = extension(sl, mv, depth, pv_node);
  6546.       int red = reduction(sl, mv, depth, pv_node, in_check, searched_size, dangerous); // LMR
  6547.  
  6548.       if (ext != 0) red = 0;
  6549.       assert(ext == 0 || red == 0);
  6550.  
  6551.       int sc;
  6552.       PV npv;
  6553.  
  6554.       move(sl, mv);
  6555.  
  6556.       if ((pv_node && searched_size != 0) || red != 0) {
  6557.  
  6558.          sc = -search(sl, depth + ext - red - 1, -alpha - 1, -alpha, npv);
  6559.  
  6560.          if (sc > alpha) { // PVS/LMR re-search
  6561.             sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6562.          }
  6563.  
  6564.       } else {
  6565.  
  6566.          sc = -search(sl, depth + ext - 1, -beta, -alpha, npv);
  6567.       }
  6568.  
  6569.       undo(sl);
  6570.  
  6571.       sp.update(mv, sc, npv);
  6572.    }
  6573. }
  6574.  
  6575. int qs_static(Search_Local & sl, int beta, int gain) { // for static NMP
  6576.  
  6577.    board::Board & bd = sl.board;
  6578.  
  6579.    assert(attack::is_legal(bd));
  6580.    // assert(!attack::is_in_check()); // triggers for root move ordering
  6581.  
  6582.    // stand pat
  6583.  
  6584.    int bs = eval(sl);
  6585.    int val = bs + gain;
  6586.  
  6587.    if (bs >= beta) {
  6588.       return bs;
  6589.    }
  6590.  
  6591.    // move loop
  6592.  
  6593.    attack::Attacks attacks;
  6594.    attack::init_attacks(attacks, bd);
  6595.  
  6596.    gen_sort::List ml;
  6597.    ml.init(-1, bd, attacks, move::NONE, sl.killer, sg.history, false); // QS move generator
  6598.  
  6599.    bit_t done = 0;
  6600.  
  6601.    for (int mv = ml.next(); mv != move::NONE; mv = ml.next()) {
  6602.  
  6603.       if (bit::is_set(done, move::to(mv))) { // process only LVA capture for each opponent piece
  6604.          continue;
  6605.       }
  6606.  
  6607.       bit::set(done, move::to(mv));
  6608.  
  6609.       int see = move::see(mv, 0, score::EVAL_MAX, bd); // TODO: beta - val?
  6610.       if (see <= 0) continue; // don't consider equal captures as "threats"
  6611.  
  6612.       int sc = val + see;
  6613.  
  6614.       if (sc > bs) {
  6615.  
  6616.          bs = sc;
  6617.  
  6618.         if (sc >= beta) {
  6619.             return sc;
  6620.          }
  6621.       }
  6622.    }
  6623.  
  6624.    assert(bs < beta);
  6625.  
  6626.    return bs;
  6627. }
  6628.  
  6629. void inc_node(Search_Local & sl) {
  6630.  
  6631.    sl.node++;
  6632.  
  6633.    if (sl.node % NODE_PERIOD == 0) {
  6634.  
  6635.       bool abort = false;
  6636.  
  6637.       update_current();
  6638.  
  6639.       if (poll()) abort = true;
  6640.  
  6641.       if (p_time.node_limited && current.node >= p_time.node_limit) {
  6642.          abort = true;
  6643.       }
  6644.  
  6645.       if (p_time.time_limited && current.time >= p_time.time_limit) {
  6646.          abort = true;
  6647.       }
  6648.  
  6649.       if (p_time.smart && current.depth > 1 && current.time >= p_time.limit_0) {
  6650.          if (current.pos == 0 || current.time >= p_time.limit_1) {
  6651.             if (!(p_time.drop || current.fail_high) || current.time >= p_time.limit_2) {
  6652.                if (p_time.ponder) {
  6653.                   p_time.flag = true;
  6654.                } else {
  6655.                   abort = true;
  6656.                }
  6657.             }
  6658.          }
  6659.       }
  6660.  
  6661.       if (p_time.smart && current.depth > 1 && current.size == 1 && current.time >= p_time.limit_0 / 8) {
  6662.          if (p_time.ponder) {
  6663.             p_time.flag = true;
  6664.          } else {
  6665.             abort = true;
  6666.          }
  6667.       }
  6668.  
  6669.       if (abort) sg_abort();
  6670.    }
  6671.  
  6672.    if (sl_stop(sl)) throw Abort();
  6673. }
  6674.  
  6675. bool poll() {
  6676.  
  6677.    write_info_opt();
  6678.  
  6679.    sg.lock();
  6680.  
  6681.    if (!input::input.has_input()) {
  6682.       sg.unlock();
  6683.       return false;
  6684.    }
  6685.  
  6686.    std::string line;
  6687.    bool eof = !input::input.get_line(line);
  6688.    if (engine::engine.log) util::log(line);
  6689.  
  6690.    sg.unlock();
  6691.  
  6692.    if (false) {
  6693.    } else if (eof) {
  6694.       std::exit(EXIT_SUCCESS);
  6695.    } else if (line == "isready") {
  6696.       std::cout << "readyok" << std::endl;
  6697.       return false;
  6698.    } else if (line == "stop") {
  6699.       uci::infinite = false;
  6700.       return true;
  6701.    } else if (line == "ponderhit") {
  6702.       uci::infinite = false;
  6703.       p_time.ponder = false;
  6704.       return p_time.flag;
  6705.    } else if (line == "quit") {
  6706. #ifdef _MSC_VER
  6707.       ExitProcess (0); // Pierre-Marie Baty -- use ExitProcess() instead of std::exit() on Win32 apps
  6708. #else // !_MSC_VER
  6709.       std::exit (EXIT_SUCCESS);
  6710. #endif // _MSC_VER
  6711.    }
  6712.  
  6713.    return false;
  6714. }
  6715.  
  6716. void move(Search_Local & sl, int mv) {
  6717.  
  6718.    board::Board & bd = sl.board;
  6719.  
  6720.    inc_node(sl);
  6721.    bd.move(mv);
  6722.  
  6723.    int ply = bd.ply();
  6724.  
  6725.    if (ply > sl.max_ply) {
  6726.       assert(ply <= MAX_PLY);
  6727.       sl.max_ply = ply;
  6728.    }
  6729. }
  6730.  
  6731. void undo(Search_Local & sl) {
  6732.    board::Board & bd = sl.board;
  6733.    bd.undo();
  6734. }
  6735.  
  6736. int eval(Search_Local & sl) {
  6737.    board::Board & bd = sl.board;
  6738.    return eval::eval(bd, sl.eval_table, sl.pawn_table);
  6739. }
  6740.  
  6741. int extension(Search_Local & sl, int mv, int depth, bool pv_node) {
  6742.  
  6743.    board::Board & bd = sl.board;
  6744.  
  6745.    if ((depth <= 4 && move::is_check(mv, bd))
  6746.     || (depth <= 4 && move::is_recapture(mv, bd))
  6747.     || (pv_node && move::is_check(mv, bd))
  6748.     || (pv_node && move::is_tactical(mv) && move::is_win(mv, bd))
  6749.     || (pv_node && move::is_pawn_push(mv, bd))) {
  6750.       return 1;
  6751.    } else {
  6752.       return 0;
  6753.    }
  6754. }
  6755.  
  6756. int reduction(Search_Local & /* sl */, int /* mv */, int depth, bool /* pv_node */, bool /* in_check */, int searched_size, bool dangerous) {
  6757.  
  6758.    int red = 0;
  6759.  
  6760.    if (depth >= 3 && searched_size >= 3 && !dangerous) {
  6761.       red = (searched_size >= 6) ? depth / 3 : 1;
  6762.    }
  6763.  
  6764.    return red;
  6765. }
  6766.  
  6767. void gen_sort(Search_Local & sl, gen::List & ml) {
  6768.  
  6769.    board::Board & bd = sl.board;
  6770.  
  6771.    gen::gen_legals(ml, bd);
  6772.  
  6773.    int v = eval(sl);
  6774.  
  6775.    for (int pos = 0; pos < ml.size(); pos++) {
  6776.  
  6777.       int mv = ml.move(pos);
  6778.  
  6779.       move(sl, mv);
  6780.       int sc = -qs_static(sl, score::MAX, 0);
  6781.       undo(sl);
  6782.  
  6783.       sc = ((sc - v) / 4) + 1024; // HACK for unsigned 11-bit move-list scores
  6784.       assert(sc >= 0 && sc < move::SCORE_SIZE);
  6785.  
  6786.       ml.set_score(pos, sc);
  6787.    }
  6788.  
  6789.    ml.sort();
  6790. }
  6791.  
  6792. void sl_init_early(Search_Local & sl, int id) {
  6793.  
  6794.    sl.id = id;
  6795.  
  6796.    sl.todo = true;
  6797.    sl.todo_sp = NULL;
  6798.  
  6799.    sl.node = 0;
  6800.    sl.max_ply = 0;
  6801.  
  6802.    sl.msp_stack_size = 0;
  6803.    sl.ssp_stack_size = 0;
  6804. }
  6805.  
  6806. void sl_init_late(Search_Local & sl) {
  6807.    sl.killer.clear();
  6808.    sl.pawn_table.clear(); // pawn-eval cache
  6809.    sl.eval_table.clear(); // eval cache
  6810. }
  6811.  
  6812. void sl_set_root(Search_Local & sl, const board::Board & bd) {
  6813.    sl.board = bd;
  6814.    sl.board.set_root();
  6815. }
  6816.  
  6817. void sl_signal(Search_Local & sl) {
  6818.    sl.lock();
  6819.    sl.signal();
  6820.    sl.unlock();
  6821. }
  6822.  
  6823. bool sl_stop(const Search_Local & sl) {
  6824.  
  6825.    for (Split_Point * sp = &sl_top(sl); sp != NULL; sp = sp->parent()) {
  6826.       if (sp->solved()) return true;
  6827.    }
  6828.  
  6829.    return false;
  6830. }
  6831.  
  6832. bool sl_idle(const Search_Local & worker, Split_Point * sp) {
  6833.  
  6834.    assert(sp != NULL);
  6835.  
  6836.    if (worker.todo) return false;
  6837.    if (worker.todo_sp != NULL) return false;
  6838.  
  6839.    Split_Point & wait_sp = sl_top(worker);
  6840.  
  6841.    for (; sp != NULL; sp = sp->parent()) {
  6842.       if (sp == &wait_sp) return true;
  6843.    }
  6844.  
  6845.    return false;
  6846. }
  6847.  
  6848. void sl_push(Search_Local & sl, Split_Point & sp) {
  6849.    assert(sl.ssp_stack_size < 16);
  6850.    sl.ssp_stack[sl.ssp_stack_size++] = &sp;
  6851. }
  6852.  
  6853. void sl_pop(Search_Local & sl) {
  6854.    assert(sl.ssp_stack_size > 0);
  6855.    sl.ssp_stack_size--;
  6856. }
  6857.  
  6858. Split_Point & sl_top(const Search_Local & sl) {
  6859.    assert(sl.ssp_stack_size > 0);
  6860.    return *sl.ssp_stack[sl.ssp_stack_size - 1];
  6861. }
  6862.  
  6863. void sg_abort() {
  6864.  
  6865.    root_sp.update_root();
  6866.  
  6867.    for (int id = 0; id < engine::engine.threads; id++) {
  6868.       sl_signal(p_sl[id]);
  6869.    }
  6870. }
  6871.  
  6872. void search_asp(gen::List & ml, int depth) {
  6873.  
  6874.    Search_Local & sl = p_sl[0];
  6875.  
  6876.    assert(depth <= 1 || p_time.last_score == best.score);
  6877.  
  6878.    if (depth >= 6 && !score::is_mate(p_time.last_score)) {
  6879.  
  6880.       for (int margin = 10; margin < 500; margin *= 2) {
  6881.  
  6882.          int a = p_time.last_score - margin;
  6883.          int b = p_time.last_score + margin;
  6884.          assert(score::EVAL_MIN <= a && a < b && b <= score::EVAL_MAX);
  6885.  
  6886.          search_root(sl, ml, depth, a, b);
  6887.  
  6888.          if (best.score > a && best.score < b) {
  6889.             return;
  6890.          } else if (score::is_mate(best.score)) {
  6891.             break;
  6892.          }
  6893.       }
  6894.    }
  6895.  
  6896.    search_root(sl, ml, depth, score::MIN, score::MAX);
  6897. }
  6898.  
  6899. void search_id(const board::Board & bd) {
  6900.  
  6901.    Search_Local & sl = p_sl[0];
  6902.  
  6903.    sl_set_root(sl, bd);
  6904.  
  6905.    sl_push(sl, root_sp);
  6906.  
  6907.    // move generation
  6908.  
  6909.    gen::List ml;
  6910.    gen_sort(sl, ml);
  6911.    assert(ml.size() != 0);
  6912.  
  6913.    best.move = ml.move(0);
  6914.    best.score = 0;
  6915.  
  6916.    bool easy = (ml.size() == 1 || (ml.size() > 1 && ml.score(0) - ml.score(1) >= 50 / 4)); // HACK: uses gen_sort() internals
  6917.    int easy_move = ml.move(0);
  6918.  
  6919.    p_time.last_score = score::NONE;
  6920.  
  6921.    // iterative deepening
  6922.  
  6923.    assert(p_time.depth_limited);
  6924.  
  6925.    for (int depth = 1; depth <= p_time.depth_limit; depth++) {
  6926.  
  6927.       depth_start(depth);
  6928.       search_asp(ml, depth);
  6929.       depth_end();
  6930.  
  6931.       // p_time.drop = (best.score <= p_time.last_score - 50); // moved to update_best()
  6932.       p_time.last_score = best.score;
  6933.  
  6934.       if (best.move != easy_move || p_time.drop) {
  6935.          easy = false;
  6936.       }
  6937.  
  6938.       if (p_time.smart && !p_time.drop) {
  6939.  
  6940.          bool abort = false;
  6941.  
  6942.          update_current();
  6943.  
  6944.          if (ml.size() == 1 && current.time >= p_time.limit_0 / 16) {
  6945.             abort = true;
  6946.          }
  6947.  
  6948.          if (easy && current.time >= p_time.limit_0 / 4) {
  6949.             abort = true;
  6950.          }
  6951.  
  6952.          if (current.time >= p_time.limit_0 / 2) {
  6953.             abort = true;
  6954.          }
  6955.  
  6956.          if (abort) {
  6957.             if (p_time.ponder) {
  6958.                p_time.flag = true;
  6959.             } else {
  6960.                break;
  6961.             }
  6962.          }
  6963.       }
  6964.    }
  6965.  
  6966.    sl_pop(sl);
  6967. }
  6968.  
  6969. void search_go(const board::Board & bd) {
  6970.  
  6971.    clear();
  6972.  
  6973.    init_sg();
  6974.    sg.trans.inc_date();
  6975.  
  6976.    for (int id = 0; id < engine::engine.threads; id++) {
  6977.       sl_init_early(p_sl[id], id);
  6978.    }
  6979.  
  6980.    root_sp.init_root(p_sl[0]);
  6981.  
  6982.    for (int id = 1; id < engine::engine.threads; id++) { // skip 0
  6983.       p_sl[id].thread = std::thread(helper_program, &p_sl[id]);
  6984.    }
  6985.  
  6986.    sl_init_late(p_sl[0]);
  6987.  
  6988.    try {
  6989.       search_id(bd);
  6990.    } catch (const Abort & /* abort */) {
  6991.       // no-op
  6992.    }
  6993.  
  6994.    sg_abort();
  6995.  
  6996.    for (int id = 1; id < engine::engine.threads; id++) { // skip 0
  6997.       p_sl[id].thread.join();
  6998.    }
  6999.  
  7000.    search_end();
  7001. }
  7002.  
  7003. void search_dumb(const board::Board & bd) {
  7004.  
  7005.    p_time.smart = false;
  7006.    p_time.last_score = score::NONE;
  7007.    p_time.drop = false;
  7008.  
  7009.    search_go(bd);
  7010. }
  7011.  
  7012. void search_smart(const board::Board & bd, int moves, int64 time, int64 inc) {
  7013.  
  7014.    if (moves == 0) moves = 40;
  7015.    moves = std::min(moves, material::interpolation(35, 15, bd));
  7016.    assert(moves > 0);
  7017.  
  7018.    int64 total = time + inc * (moves - 1);
  7019.    int factor = engine::engine.ponder ? 140 : 120;
  7020.    int64 alloc = total / moves * factor / 100;
  7021.    int64 reserve = total * (moves - 1) / 40;
  7022.    int64 max = std::min(time, total - reserve);
  7023.    max = std::min(max - 60, max * 95 / 100); // 60ms for lag
  7024.  
  7025.    alloc = std::max(alloc, I64(0));
  7026.    max = std::max(max, I64(0));
  7027.  
  7028.    p_time.smart = true;
  7029.    p_time.limit_0 = std::min(alloc, max);
  7030.    p_time.limit_1 = std::min(alloc * 4, max);
  7031.    p_time.limit_2 = max;
  7032.    p_time.last_score = score::NONE;
  7033.    p_time.drop = false;
  7034.  
  7035.    assert(0 <= p_time.limit_0 && p_time.limit_0 <= p_time.limit_1 && p_time.limit_1 <= p_time.limit_2);
  7036.  
  7037.    search_go(bd);
  7038. }
  7039.  
  7040. void init() {
  7041.    sg.trans.set_size(engine::engine.hash);
  7042.    sg.trans.alloc();
  7043. }
  7044.  
  7045. }
  7046.  
  7047. namespace uci {
  7048.  
  7049. board::Board bd;
  7050. bool delay;
  7051.  
  7052. class Scanner {
  7053.  
  7054. private:
  7055.  
  7056.   std::stringstream * p_ss;
  7057.   std::vector<std::string> p_keywords;
  7058.  
  7059.   bool p_undo;
  7060.   std::string p_word;
  7061.  
  7062.    bool is_keyword(const std::string & word) const {
  7063.  
  7064.       for (int i = 0; i < int(p_keywords.size()); i++) {
  7065.          if (p_keywords[i] == word) return true;
  7066.       }
  7067.  
  7068.       return false;
  7069.    }
  7070.  
  7071. public:
  7072.  
  7073.    Scanner(std::stringstream & ss) {
  7074.       p_ss = &ss;
  7075.       p_undo = false;
  7076.       add_keyword("");
  7077.    }
  7078.  
  7079.    void add_keyword(const std::string & keyword) {
  7080.       p_keywords.push_back(keyword);
  7081.    }
  7082.  
  7083.    std::string get_keyword() {
  7084.  
  7085.       std::string word = get_word();
  7086.       assert(is_keyword(word));
  7087.  
  7088.       return word;
  7089.    }
  7090.  
  7091.    std::string get_args() {
  7092.  
  7093.       std::string args;
  7094.       std::string word;
  7095.  
  7096.       while (true) {
  7097.  
  7098.          std::string word = get_word();
  7099.  
  7100.          if (is_keyword(word)) {
  7101.             unget_word();
  7102.             break;
  7103.          }
  7104.  
  7105.          if (args != "") args += " ";
  7106.          args += word;
  7107.       }
  7108.  
  7109.       return args;
  7110.    }
  7111.  
  7112.    std::string get_word() {
  7113.  
  7114.       if (p_undo) {
  7115.          p_undo = false;
  7116.       } else if (!(*p_ss >> p_word)) { // NOTE: reads as a side effect
  7117.          p_word = "";
  7118.       }
  7119.  
  7120.       return p_word;
  7121.    }
  7122.  
  7123.    void unget_word() {
  7124.       assert(!p_undo);
  7125.       p_undo = true;
  7126.    }
  7127.  
  7128. };
  7129.  
  7130. void fen(const std::string & fen) {
  7131.    bd.init_fen(fen);
  7132. }
  7133.  
  7134. void move(const std::string & move) {
  7135.    int mv = move::from_string(move, bd);
  7136.    bd.move(mv);
  7137. }
  7138.  
  7139. void send_bestmove() {
  7140.  
  7141.    std::cout << "bestmove " << move::to_can(search::best.move);
  7142.    if (search::best.pv.size() > 1) std::cout << " ponder " << move::to_can(search::best.pv.move(1));
  7143.    std::cout << std::endl;
  7144.  
  7145.    delay = false;
  7146. }
  7147.  
  7148. void command(Scanner & scan) {
  7149.  
  7150.    std::string command = scan.get_word();
  7151.  
  7152.    if (false) {
  7153.  
  7154.    } else if (command == "uci") {
  7155.  
  7156.       std::cout << "id name Senpai 1.0" << std::endl;
  7157.       std::cout << "id author Fabien Letouzey" << std::endl;
  7158.  
  7159.       std::cout << "option name Hash type spin default " << engine::engine.hash << " min 16 max 16384" << std::endl;
  7160.       std::cout << "option name Ponder type check default " << engine::engine.ponder << std::endl;
  7161.       std::cout << "option name Threads type spin default " << engine::engine.threads << " min 1 max 16" << std::endl;
  7162.       std::cout << "option name Log File type check default " << engine::engine.log << std::endl;
  7163.  
  7164.       std::cout << "uciok" << std::endl;
  7165.  
  7166.    } else if (command == "isready") {
  7167.  
  7168.       std::cout << "readyok" << std::endl;
  7169.  
  7170.    } else if (command == "setoption") {
  7171.  
  7172.       scan.add_keyword("name");
  7173.       scan.add_keyword("value");
  7174.  
  7175.       std::string name;
  7176.       std::string value;
  7177.  
  7178.       std::string part;
  7179.  
  7180.       while ((part = scan.get_keyword()) != "") {
  7181.  
  7182.          if (false) {
  7183.          } else if (part == "name") {
  7184.             name = scan.get_args();
  7185.          } else if (part == "value") {
  7186.             value = scan.get_args();
  7187.          }     
  7188.       }
  7189.  
  7190.       if (false) {
  7191.       } else if (util::string_case_equal(name, "Hash")) {
  7192.          engine::engine.hash = int(util::to_int(value));
  7193.          search::sg.trans.set_size(engine::engine.hash);
  7194.       } else if (util::string_case_equal(name, "Ponder")) {
  7195.          engine::engine.ponder = util::to_bool(value);
  7196.       } else if (util::string_case_equal(name, "Threads") || util::string_case_equal(name, "Cores")) {
  7197.          engine::engine.threads = int(util::to_int(value));
  7198.       } else if (util::string_case_equal(name, "Log File")) {
  7199.          engine::engine.log = util::to_bool(value);
  7200.       }
  7201.  
  7202.    } else if (command == "ucinewgame") {
  7203.  
  7204.       search::sg.trans.clear();
  7205.  
  7206.    } else if (command == "position") {
  7207.  
  7208.       scan.add_keyword("fen");
  7209.       scan.add_keyword("startpos");
  7210.       scan.add_keyword("moves");
  7211.  
  7212.       std::string part;
  7213.  
  7214.       while ((part = scan.get_keyword()) != "") {
  7215.  
  7216.          if (false) {
  7217.  
  7218.          } else if (part == "fen") {
  7219.  
  7220.             fen(scan.get_args());
  7221.  
  7222.          } else if (part == "startpos") {
  7223.  
  7224.             fen(board::start_fen);
  7225.  
  7226.          } else if (part == "moves") {
  7227.  
  7228.             std::string arg;
  7229.  
  7230.             while ((arg = scan.get_word()) != "") {
  7231.                uci::move(arg);
  7232.             }
  7233.          }
  7234.       }
  7235.  
  7236.    } else if (command == "go") {
  7237.  
  7238.       scan.add_keyword("searchmoves");
  7239.       scan.add_keyword("ponder");
  7240.       scan.add_keyword("wtime");
  7241.       scan.add_keyword("btime");
  7242.       scan.add_keyword("winc");
  7243.       scan.add_keyword("binc");
  7244.       scan.add_keyword("movestogo");
  7245.       scan.add_keyword("depth");
  7246.       scan.add_keyword("nodes");
  7247.       scan.add_keyword("mate");
  7248.       scan.add_keyword("movetime");
  7249.       scan.add_keyword("infinite");
  7250.  
  7251.       search::new_search();
  7252.  
  7253.       infinite = false;
  7254.       delay = false;
  7255.  
  7256.       bool smart = false;
  7257.       int time = 60000;
  7258.       int inc = 0;
  7259.       int movestogo = 0;
  7260.  
  7261.       std::string part;
  7262.  
  7263.       while ((part = scan.get_keyword()) != "") {
  7264.  
  7265.          std::string args = scan.get_args();
  7266.  
  7267.          if (false) {
  7268.  
  7269.          } else if (part == "ponder") {
  7270.  
  7271.             infinite = true;
  7272.             search::set_ponder();
  7273.  
  7274.          } else if (part == "wtime") {
  7275.  
  7276.             if (bd.turn() == side::WHITE) {
  7277.                smart = true;
  7278.                time = int(util::to_int(args));
  7279.             }
  7280.  
  7281.          } else if (part == "btime") {
  7282.  
  7283.             if (bd.turn() == side::BLACK) {
  7284.                smart = true;
  7285.                time = int(util::to_int(args));
  7286.             }
  7287.  
  7288.          } else if (part == "winc") {
  7289.  
  7290.             if (bd.turn() == side::WHITE) {
  7291.                smart = true;
  7292.                inc = int(util::to_int(args));
  7293.             }
  7294.  
  7295.          } else if (part == "binc") {
  7296.  
  7297.             if (bd.turn() == side::BLACK) {
  7298.                smart = true;
  7299.                inc = int(util::to_int(args));
  7300.             }
  7301.  
  7302.          } else if (part == "movestogo") {
  7303.  
  7304.             smart = true;
  7305.             movestogo = int(util::to_int(args));
  7306.  
  7307.          } else if (part == "depth") {
  7308.  
  7309.             search::set_depth_limit(int(util::to_int(args)));
  7310.  
  7311.          } else if (part == "nodes") {
  7312.  
  7313.             search::set_node_limit(util::to_int(args));
  7314.  
  7315.          } else if (part == "movetime") {
  7316.  
  7317.             search::set_time_limit(int(util::to_int(args)));
  7318.  
  7319.          } else if (part == "infinite") {
  7320.  
  7321.             infinite = true;
  7322.          }
  7323.       }
  7324.  
  7325.       if (smart) {
  7326.          search::search_smart(bd, movestogo, time, inc);
  7327.       } else {
  7328.          search::search_dumb(bd);
  7329.       }
  7330.  
  7331.       if (infinite) { // let's implement the UCI-design mistake :(
  7332.          delay = true;
  7333.       } else {
  7334.          send_bestmove();
  7335.       }
  7336.  
  7337.    } else if (command == "stop") {
  7338.  
  7339.       if (delay) send_bestmove();
  7340.  
  7341.    } else if (command == "ponderhit") {
  7342.  
  7343.       if (delay) send_bestmove();
  7344.  
  7345.    } else if (command == "quit") {
  7346. #ifdef _MSC_VER
  7347.       ExitProcess(0); // Pierre-Marie Baty -- use ExitProcess() instead of exit() on Win32 apps
  7348. #else // !_MSC_VER
  7349.       std::exit(EXIT_SUCCESS);
  7350. #endif // _MSC_VER
  7351.    }
  7352. }
  7353.  
  7354. void line(const std::string & line) {
  7355.  
  7356.    if (engine::engine.log) util::log(line);
  7357.  
  7358.    std::stringstream args(line);
  7359.    Scanner scan(args);
  7360.    command(scan);
  7361. }
  7362.  
  7363. void loop() {
  7364.  
  7365.    std::cout << std::boolalpha;
  7366.  
  7367.    infinite = false;
  7368.    delay = false;
  7369.  
  7370.    fen(board::start_fen);
  7371.  
  7372.    std::string line;
  7373.  
  7374.    while (input::input.get_line(line)) {
  7375.       uci::line(line);
  7376.    }
  7377. }
  7378.  
  7379. }
  7380.  
  7381. int main(int /* argc */, char * /* argv */ []) {
  7382.  
  7383.    assert(sizeof(uint8)  == 1);
  7384.    assert(sizeof(uint16) == 2);
  7385.    assert(sizeof(uint32) == 4);
  7386.    assert(sizeof(uint64) == 8);
  7387.  
  7388.    input::init();
  7389.    bit::init();
  7390.    hash::init();
  7391.    castling::init();
  7392.    attack::init();
  7393.    engine::init();
  7394.    material::init();
  7395.    pst::init();
  7396.    pawn::init();
  7397.    eval::init();
  7398.    search::init();
  7399.  
  7400.    uci::loop();
  7401.  
  7402.    return EXIT_SUCCESS;
  7403. }
  7404.  
  7405.