Subversion Repositories Games.Chess Giants

Rev

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