Advertisement
Guest User

Clobber

a guest
Apr 29th, 2021
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.43 KB | None | 0 0
  1. // *** Start of: /home/olaf/clobber/main.cpp ***
  2. #pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
  3. #pragma GCC option("march=native","tune=native","no-zero-upper")
  4. #pragma GCC target("avx")
  5.  
  6. #include <bits/stdc++.h>
  7.  
  8.  // *** Start of: /home/olaf/clobber/MCTS/mcts.h ***
  9.  
  10.  #include <iostream>
  11.  
  12.   // *** Start of: /home/olaf/clobber/State/state.h ***
  13.  
  14.    // *** Start of: /home/olaf/clobber/Utils/types.h ***
  15.    
  16.    #include <string>
  17.    
  18.    typedef unsigned long long BB;
  19.    typedef unsigned long long Key;
  20.    typedef unsigned long long u64;
  21.    
  22.    typedef int8_t Color;
  23.    
  24.    const Color WHITE = 0;
  25.    const Color BLACK = 1;
  26.    const Color COLOR_NB = 2;
  27.    
  28.    typedef int16_t Action;
  29.    
  30.    inline Action make_action(const int &from, const int &to) {
  31.        return Action(from | (to << 6));
  32.    }
  33.    
  34.    inline int xy(int x, int y) {
  35.        return (x << 3) | y;
  36.    }
  37.    
  38.    inline Action from_string(std::string action) {
  39.     int fx = action[0] - 'a', fy = action[1] - '1';
  40.     int tx = action[2] - 'a', ty = action[3] - '1';
  41.     fy = 7 - fy;
  42.     ty = 7 - ty;
  43.     return make_action(xy(fy, fx), xy(ty, tx));
  44.    }
  45.    
  46.    inline std::string to_string(Action action) {
  47.     int fx = (action & 63) & 7, fy = (action & 63) >> 3;
  48.     int tx = (action >> 6) & 7, ty = (action >> 6) >> 3;
  49.    
  50.     fy = 7 - fy;
  51.     ty = 7 - ty;
  52.        
  53.     std::string res;
  54.    
  55.     res += char(fx + 'a');
  56.     res += char(fy + '1');
  57.     res += char(tx + 'a');
  58.     res += char(ty + '1');
  59.    
  60.     return res;
  61.    }
  62.    
  63.    // *** End of: /home/olaf/clobber/Utils/types.h ***
  64.    // *** Start of: /home/olaf/clobber/Utils/bits.h ***
  65.    
  66.    inline int lsb(const unsigned long long &b) {
  67.     return __builtin_ctzll(b);
  68.    }
  69.    
  70.    inline int lsb(const unsigned int &b) {
  71.     return __builtin_ctz(b);
  72.    }
  73.    
  74.    inline int pop_lsb(unsigned long long &b) {
  75.     const int s = lsb(b);
  76.     b &= b - 1;
  77.     return s;
  78.    }
  79.    
  80.    inline int pop_lsb(unsigned int &b) {
  81.     const int s = lsb(b);
  82.     b &= b - 1;
  83.     return s;
  84.    }
  85.    
  86.    inline int pop_cnt(const unsigned long long &b) {
  87.     return __builtin_popcountll(b);
  88.    }
  89.    
  90.    inline int pop_cnt(const unsigned int &b) {
  91.     return __builtin_popcount(b);
  92.    }
  93.    
  94.    inline void debug_bitboard(const unsigned long long &b) {
  95.     for(int i = 0; i < 8; i++) {
  96.         for(int j = 0; j < 8; j++) {
  97.             std::cerr << ((b & (1ULL << (i * 8 + j))) > 0);
  98.         }
  99.         std::cerr << '\n';
  100.     }
  101.    }
  102.    
  103.    // *** End of: /home/olaf/clobber/Utils/bits.h ***
  104.    // *** Start of: /home/olaf/clobber/Utils/random.h ***
  105.    
  106.    
  107.    static unsigned int g_seed = 2137;
  108.    
  109.    inline void fast_srand(int seed) {
  110.     g_seed = seed;
  111.    }
  112.    
  113.    inline int fast_rand() {
  114.     unsigned int z = (g_seed += 0x39A3689AU);
  115.     z = (z ^ (z >> 14)) * 0x108E8AB8;
  116.     z = (z ^ (z >> 13)) * 0x2CD01FD6;
  117.     return int((z ^ (z >> 15)) >> 1);
  118.    }
  119.    
  120.    inline int fast_rand(int a, int b) {
  121.        return a + fast_rand() % (b - a + 1);
  122.    }
  123.    
  124.    inline int random_set_bit(BB b) {
  125.        int bit = fast_rand() % pop_cnt(b);
  126.        while(bit--) {
  127.            b &= b - 1;
  128.        }
  129.        return lsb(b);
  130.    }
  131.    
  132.    // *** End of: /home/olaf/clobber/Utils/random.h ***
  133.  
  134.   BB attacks[64] = {
  135.     0x0000000000000102ULL, 0x0000000000000205ULL, 0x000000000000040aULL, 0x0000000000000814ULL, 0x0000000000001028ULL, 0x0000000000002050ULL, 0x00000000000040a0ULL, 0x0000000000008040ULL,
  136.     0x0000000000010201ULL, 0x0000000000020502ULL, 0x0000000000040a04ULL, 0x0000000000081408ULL, 0x0000000000102810ULL, 0x0000000000205020ULL, 0x000000000040a040ULL, 0x0000000000804080ULL,
  137.     0x0000000001020100ULL, 0x0000000002050200ULL, 0x00000000040a0400ULL, 0x0000000008140800ULL, 0x0000000010281000ULL, 0x0000000020502000ULL, 0x0000000040a04000ULL, 0x0000000080408000ULL,
  138.     0x0000000102010000ULL, 0x0000000205020000ULL, 0x000000040a040000ULL, 0x0000000814080000ULL, 0x0000001028100000ULL, 0x0000002050200000ULL, 0x00000040a0400000ULL, 0x0000008040800000ULL,
  139.     0x0000010201000000ULL, 0x0000020502000000ULL, 0x0000040a04000000ULL, 0x0000081408000000ULL, 0x0000102810000000ULL, 0x0000205020000000ULL, 0x000040a040000000ULL, 0x0000804080000000ULL,
  140.     0x0001020100000000ULL, 0x0002050200000000ULL, 0x00040a0400000000ULL, 0x0008140800000000ULL, 0x0010281000000000ULL, 0x0020502000000000ULL, 0x0040a04000000000ULL, 0x0080408000000000ULL,
  141.     0x0102010000000000ULL, 0x0205020000000000ULL, 0x040a040000000000ULL, 0x0814080000000000ULL, 0x1028100000000000ULL, 0x2050200000000000ULL, 0x40a0400000000000ULL, 0x8040800000000000ULL,
  142.     0x0201000000000000ULL, 0x0502000000000000ULL, 0x0a04000000000000ULL, 0x1408000000000000ULL, 0x2810000000000000ULL, 0x5020000000000000ULL, 0xa040000000000000ULL, 0x4080000000000000ULL,
  143.   };
  144.  
  145.   Key zobrist[COLOR_NB][64] = {
  146.       {
  147.           0xedfc338580f87eedULL, 0x230bd0318dda3dddULL, 0x41f936d52926448dULL, 0x10c2d113d49d3d77ULL, 0x865fff9fa61f9626ULL, 0x2cfc875358f845efULL, 0x6ffc31215e42c504ULL, 0x80f60e6ea8ae90c0ULL,
  148.           0xfd74a61730e66c66ULL, 0xdfc6529d408dbe17ULL, 0x288f3b12738b05caULL, 0x186df39b591f12c0ULL, 0xe498104f68234ab5ULL, 0x0a6a88e451b215e8ULL, 0xfb5efa71f13e99c6ULL, 0xd2ff1f4d01a0f91cULL,
  149.           0x12629cd4394a970aULL, 0xfaa25da3b6dddd80ULL, 0x803f57e24c43d1adULL, 0xa675f3768c9803b3ULL, 0x76b0152a521c60caULL, 0x98cc9ceb9c6c30f5ULL, 0xe60789726773a156ULL, 0x0229b503b3ca36c7ULL,
  150.           0x9c69d0a3ddfb4ce5ULL, 0x86deecc84c3a1912ULL, 0x43ea387628356b6eULL, 0x13eca1fa1c4e49cbULL, 0x53b16415e20c05c7ULL, 0xd06bcb222a037fd2ULL, 0x7fbc30b9030c66c5ULL, 0x01a31641252eac0aULL,
  151.           0xeec05c20ea726ee7ULL, 0x5408d862787529ceULL, 0xe181ea6b38f7a774ULL, 0x0acdb4f88e3b1d73ULL, 0x201b8bc2bd5d4125ULL, 0xbe5719ae8cd6890fULL, 0xf50dde5085d046e5ULL, 0x1d14adef65bc5ee9ULL,
  152.           0x092fd68e11c58d45ULL, 0x68fe3eb9b11cb202ULL, 0x8941178b4250766bULL, 0xd0ffaa327247f1abULL, 0xf11d1cd3663fcadcULL, 0x541e076d57f5b0d3ULL, 0x300431472fccfad1ULL, 0x6bb8387d066eb3f9ULL,
  153.           0x341d21243fbc1ec2ULL, 0x4befe097ed8b2600ULL, 0x53c079b68d756868ULL, 0xf3c3ae4f8822ba40ULL, 0x2da341ee2a2db5c5ULL, 0xe7fe1d1899786c2eULL, 0x4772147a9bf7a481ULL, 0x5578963ec87cb132ULL,
  154.           0xbd75f518465d1bf5ULL, 0xc876f3a8b79520d0ULL, 0xdf112a0aefddd835ULL, 0x6a2cf2b00233c83eULL, 0x89605d22b0072536ULL, 0x47ea26f6a500bbefULL, 0xe9862bbaf2feb9daULL, 0x5937dd7d0b2cba98ULL,
  155.       },
  156.       {
  157.           0xe5dc8d8997192c49ULL, 0x54431f7ca2040dc5ULL, 0xeec8c87039e1b26aULL, 0x00bd0a8c0dad4e07ULL, 0x64bd5370639d979cULL, 0xa6d86723a184bbfeULL, 0xdd655929bb7ccd4cULL, 0xf0b5ad4a415d73b3ULL,
  158.           0xdf9a45c29c13a1bcULL, 0xb82e5be2d9a65f98ULL, 0x2493fe005afa716cULL, 0x160747b0fda14b5eULL, 0x0f52f869302d6679ULL, 0x71a3ba9f5cfa7764ULL, 0x23246b366dc31a36ULL, 0xe72321e2e0ba2feeULL,
  159.           0x2ddaf38756bb428bULL, 0x8c96f32c4fbc2c0aULL, 0x4e559f3a6d2db820ULL, 0x901ddeaa8f12e2b4ULL, 0xfd96e5ffc18ffb88ULL, 0x55b5cb18ff41cbccULL, 0x6288ea844742dfe8ULL, 0x6ed62f154853c1e6ULL,
  160.           0x967e1a946355826fULL, 0x6ee4bc240e64b1e0ULL, 0x93a5aad23c617480ULL, 0x4414ec507876fee9ULL, 0xff83ed87214dce6eULL, 0xe3f78d99002bca48ULL, 0xffcbcaf7cbbb81f6ULL, 0x1b256eac079acfa4ULL,
  161.           0x3534833b496f15e2ULL, 0x4fdca0beb360abebULL, 0x747b4e372f380830ULL, 0x50009a44a2d8bd6cULL, 0xf6c197ddb8b65ffcULL, 0x2eb72ded1a5812d4ULL, 0xfe437d4402622cc5ULL, 0xf22ed5fb875b9460ULL,
  162.           0xb3144b5c91ac69daULL, 0xeff53dc89c5b6dddULL, 0xe3e9b829038b9d74ULL, 0x24a722e48c530fbbULL, 0x8426194f5ade638aULL, 0x7e16ebc9b48f8d36ULL, 0xb8bd5052e1a63353ULL, 0x741c0076e3f446f3ULL,
  163.           0x9fb9f014d662af30ULL, 0x4fbe97b01400380aULL, 0x3336ec180b0302ddULL, 0x6f6b0a80f9b1c0acULL, 0xb93f86a5f6418955ULL, 0x95e01f0931c291f3ULL, 0xf59665b7411432ecULL, 0xa29080c21daa4b7bULL,
  164.           0xf6dcb93f9f8f15b9ULL, 0x9e670153f067b5b9ULL, 0xf8321144c6efb7e3ULL, 0x5315bc36d00304cfULL, 0xbf809aa5d6598f22ULL, 0xc1e84fc7cad4ca19ULL, 0x68f7a04a28052fd9ULL, 0xc4b559df3477f757ULL,
  165.       },
  166.   };
  167.  
  168.   class State {
  169.   private:
  170.  
  171.       BB pieces[COLOR_NB];
  172.       Color us;
  173.       Color op;
  174.       Key hash;
  175.  
  176.   public:
  177.  
  178.       inline int score() const {
  179.          
  180.       }
  181.  
  182.       State() {
  183.           us = WHITE;
  184.           op = BLACK;
  185.           pieces[WHITE] = 0xaa55aa55aa55aa55ULL;
  186.           pieces[BLACK] = 0x55aa55aa55aa55aaULL;
  187.           for(int sq = 0; sq < 64; sq++) {
  188.               if(pieces[WHITE] & (1ULL << sq)) {
  189.                   hash ^= zobrist[WHITE][sq];
  190.               }
  191.               if(pieces[BLACK] & (1ULL << sq)) {
  192.                   hash ^= zobrist[BLACK][sq];
  193.               }
  194.           }
  195.       }
  196.  
  197.     inline void debug() const {
  198.         for(int i = 0; i < 8; i++) {
  199.             std::cerr << "  +---+---+---+---+---+---+---+---+\n";
  200.             std::cerr << 8 - i << " +";
  201.             for(int j = 0; j < 8; j++) {
  202.                 BB k = 1ULL << (i * 8 + j);
  203.                 std::cerr << ' ';
  204.                 if(pieces[WHITE] & k) {
  205.                     std::cerr << 'w';
  206.                   } else if(pieces[BLACK] & k) {
  207.                       std::cerr << 'b';
  208.                 } else {
  209.                     std::cerr << ' ';
  210.                 }
  211.                 std::cerr << ' ';
  212.                 if(j != 7)  std::cerr << "|";
  213.             }
  214.             std::cerr << "+\n";
  215.         }
  216.         std::cerr << "  +---+---+---+---+---+---+---+---+\n";
  217.         std::cerr << "    a   b   c   d   e   f   g   h  \n";
  218.     }    
  219.  
  220.  
  221.       inline void move(const int &from, const int &to) {
  222.           pieces[us] &= ~(1ULL << from);
  223.           pieces[us] |=   1ULL << to;
  224.           pieces[op] &= ~(1ULL << to);
  225.  
  226.           hash ^= zobrist[us][from];
  227.           hash ^= zobrist[op][to];
  228.           hash ^= zobrist[us][to];
  229.  
  230.           us ^= op ^= us ^= op;
  231.       }
  232.  
  233.       inline void move(Action action) {
  234.           move(action & 63, action >> 6);
  235.       }
  236.  
  237.       inline void undo(const int &from, const int &to) {
  238.           us ^= op ^= us ^= op;
  239.  
  240.           hash ^= zobrist[us][to];
  241.           hash ^= zobrist[op][to];
  242.           hash ^= zobrist[us][from];
  243.          
  244.           pieces[us] |=   1ULL << from;
  245.           pieces[us] &= ~(1ULL << to);
  246.           pieces[op] |=   1ULL << to;
  247.       }
  248.  
  249.       inline void undo(const Action &action) {
  250.           undo(action & 63, action >> 6);
  251.       }
  252.  
  253.       inline bool is_end() const {
  254.           return pop_cnt(get_active()) == 0;
  255.       }
  256.  
  257.       inline Color get_player() const {
  258.           return us;
  259.       }
  260.  
  261.       inline Color get_opponent() const {
  262.           return op;
  263.       }
  264.  
  265.       inline int pieces_count() const {
  266.           return pop_cnt(pieces[WHITE]) + pop_cnt(pieces[BLACK]);
  267.       }
  268.  
  269.       inline Key get_hash() const {
  270.           return hash;
  271.       }
  272.      
  273.       inline BB get_active() const {
  274.           return ((pieces[op] << 8) |
  275.                   (pieces[op] >> 8) |
  276.                  ((pieces[op] & 0x7f7f7f7f7f7f7f7fULL) << 1) |
  277.                  ((pieces[op] & 0xfefefefefefefefeULL) >> 1))
  278.                  & pieces[us];
  279.       }
  280.  
  281.       inline Action* get_actions(Action *list) const {
  282.           BB bb = get_active();
  283.  
  284.           while(bb) {
  285.               const int from = pop_lsb(bb);
  286.               BB to_mask = attacks[from] & pieces[op];
  287.               while(to_mask) {
  288.                   const int to = pop_lsb(to_mask);
  289.                   *list++ = make_action(from, to);
  290.               }
  291.           }
  292.           return list;
  293.       }
  294.  
  295.       inline Action get_random_action() const {
  296.           const int from = random_set_bit(get_active());
  297.           return make_action(from, random_set_bit(attacks[from] & pieces[op]));
  298.       }
  299.  
  300.   };
  301.  
  302.   // *** End of: /home/olaf/clobber/State/state.h ***
  303.   // *** Start of: /home/olaf/clobber/Search/search.h ***
  304.  
  305.   #include <bits/extc++.h>
  306.  
  307.   using namespace __gnu_pbds;
  308.  
  309.   inline Color get_loser(State &state) {
  310.       static gp_hash_table<Key, Color> cache_loser;
  311.  
  312.       auto it = cache_loser.find(state.get_hash());
  313.       if(it != cache_loser.end()) {
  314.           return it->second;
  315.       }
  316.  
  317.       Action actions[112];
  318.       Action* end = state.get_actions(actions);
  319.       for(Action *now = actions; now != end; now++) {
  320.           state.move(*now);
  321.  
  322.           Color loser = get_loser(state);
  323.  
  324.           state.undo(*now);
  325.  
  326.           if(loser != state.get_player()) {
  327.               return cache_loser[state.get_hash()] = loser;
  328.           }
  329.       }
  330.       return cache_loser[state.get_hash()] = state.get_player();
  331.   }
  332.  
  333.   // *** End of: /home/olaf/clobber/Search/search.h ***
  334.   // *** Start of: /home/olaf/clobber/MCTS/node.h ***
  335.  
  336.   #include <bits/stdc++.h>
  337.  
  338.    // *** Start of: /home/olaf/clobber/Utils/vector.h ***
  339.    
  340.    #include <algorithm>
  341.    
  342.    
  343.    template <typename T>
  344.    class vector {
  345.    private:
  346.        T*  m_data;
  347.        unsigned int m_memo;
  348.        unsigned int m_size;
  349.    
  350.    public:
  351.    
  352.        vector(int size = 0) : m_size(size), m_memo(1) {
  353.            while(m_memo < m_size)  m_memo <<= 1;
  354.            m_data = (T*) malloc(m_memo * sizeof(T));
  355.        }
  356.    
  357.        ~vector() {
  358.            free(m_data);
  359.        }
  360.    
  361.        inline void push_back(const T &value) {
  362.            m_data[m_size++] = value;
  363.            if(m_size >= m_memo) {
  364.                m_memo <<= 1;
  365.                m_data = (T*) realloc(m_data, m_memo * sizeof(T));
  366.            }
  367.        }
  368.    
  369.        inline void pop_back() {
  370.            m_size--;
  371.            if(m_size <= (m_memo >> 1)) {
  372.                m_memo >>= 1;
  373.                m_data = (T*) realloc(m_data, m_memo * sizeof(T));
  374.            }
  375.        }
  376.    
  377.        inline T& back() {
  378.            return *(m_data + m_size - 1);
  379.        }
  380.    
  381.        inline bool empty() const {
  382.            return m_size == 0;
  383.        }
  384.    
  385.        inline unsigned int size() const {
  386.            return m_size;
  387.        }
  388.    
  389.        inline void shuffle() {
  390.            for(int i = m_size - 1; i > 0; i--) {
  391.                std::swap(m_data[i], m_data[fast_rand(0, i)]);        
  392.            }
  393.        }
  394.      
  395.        const T& operator[] (unsigned int index) const {
  396.            return *(m_data + index);
  397.        }
  398.    
  399.    };
  400.    
  401.    // *** End of: /home/olaf/clobber/Utils/vector.h ***
  402.  
  403.   class Node {
  404.   private:
  405.       State state;
  406.       Node *parent;
  407.       Action last_action;
  408.       vector<Node*> children;
  409.       vector<Action> untried;
  410.  
  411.       int vis_cnt;
  412.       int win_cnt;
  413.  
  414.       float ucb_value;
  415.  
  416.   public:
  417.  
  418.       Node(Action _last = -1, State _state = State(), Node *_parent = nullptr) :
  419.           state(_state), parent(_parent), last_action(_last),
  420.           vis_cnt(0), win_cnt(0) {
  421.          
  422.           static Action actions[112];
  423.           Action *end = state.get_actions(actions);
  424.          
  425.           for(Action *now = actions; now != end; now++) {
  426.               untried.push_back(*now);
  427.           }
  428.  
  429.           untried.shuffle();
  430.          
  431.           ucb_value = std::numeric_limits<float>::max();
  432.       }
  433.  
  434.       inline Action get_last_action() const {
  435.           return last_action;
  436.       }
  437.  
  438.       inline int get_win_cnt() const {
  439.           return win_cnt;
  440.       }
  441.  
  442.       inline int get_vis_cnt() const {
  443.           return vis_cnt;
  444.       }
  445.  
  446.       inline bool is_fully_expanded() const {
  447.           return untried.empty();
  448.       }
  449.  
  450.       inline bool is_terminal() const {
  451.           return children.empty() && untried.empty();
  452.       }
  453.  
  454.       inline float get_ucb() const {
  455.           return ucb_value;
  456.       }
  457.  
  458.       inline State get_state() const {
  459.           return state;
  460.       }
  461.  
  462.       inline Node* expand() {
  463.           Action action = untried.back();
  464.           untried.pop_back();
  465.           state.move(action);
  466.  
  467.           Node* child_node = new Node(action, state, this);
  468.          
  469.           children.push_back(child_node);
  470.          
  471.           state.undo(action);
  472.  
  473.           return child_node;
  474.       }
  475.  
  476.       inline Node* select_by_uct() {
  477.           float best_ucb = -std::numeric_limits<float>::max();
  478.           Node* best_node = nullptr;
  479.  
  480.           for(unsigned int child_id = 0; child_id < children.size(); child_id++) {
  481.               Node* child = children[child_id];
  482.               if(child->get_ucb() > best_ucb) {
  483.                   best_ucb = child->get_ucb();
  484.                   best_node = child;
  485.               }
  486.           }
  487.  
  488.           return best_node;
  489.       }
  490.  
  491.       inline void recalculate_ucb() {
  492.           ucb_value = 1 - float(win_cnt) / vis_cnt + 1.41421356237f * sqrt(log(parent->vis_cnt) / vis_cnt);
  493.       }
  494.  
  495.       inline void backpropagate(Color loser) {
  496.           vis_cnt++;
  497.           if(loser != state.get_player()) {
  498.               win_cnt++;
  499.           }
  500.          
  501.           if(parent) {
  502.               parent->backpropagate(loser);
  503.               recalculate_ucb();
  504.           }
  505.       }
  506.  
  507.       inline Action get_best_action() const {
  508.           int best_vis_cnt = -1;
  509.           Action best_action = -1;        
  510.  
  511.           for(unsigned int child_id = 0; child_id < children.size(); child_id++) {
  512.               const Node* child = children[child_id];
  513.               if(child->get_vis_cnt() > best_vis_cnt) {    
  514.                   best_vis_cnt = child->get_vis_cnt();
  515.                   best_action = child->get_last_action();
  516.               }
  517.           }
  518.  
  519.           return best_action;
  520.       }
  521.  
  522.       inline Node* pass_action(Action action) const {
  523.           for(unsigned int child_id = 0; child_id < children.size(); child_id++) {
  524.               if(children[child_id]->get_last_action() == action) {
  525.                   return children[child_id];
  526.               }
  527.           }
  528.           return nullptr;
  529.       }
  530.  
  531.       inline void set_as_root() {
  532.           parent = nullptr;
  533.           last_action = -1;
  534.       }
  535.   };
  536.  
  537.   // *** End of: /home/olaf/clobber/MCTS/node.h ***
  538.  
  539.  class MCTS {
  540.  private:
  541.      Node *root;
  542.  
  543.  public:
  544.  
  545.      MCTS() {
  546.          root = new Node;
  547.          while(!root->is_fully_expanded()) {
  548.              root->expand();
  549.          }
  550.      }
  551.    
  552.      inline Node* select(Node *node) {
  553.          while(!node->is_terminal()) {
  554.              if(node->is_fully_expanded()) {
  555.                  node = node->select_by_uct();
  556.              } else {
  557.                  return node->expand();
  558.              }
  559.          }
  560.          return node;
  561.      }
  562.  
  563.      // returns loser color
  564.      inline Color simulate(Node *node) {
  565.          State state = node->get_state();
  566.          while(!state.is_end()) {
  567.              if(state.pieces_count() < 10) {
  568.                  return get_loser(state);
  569.              }
  570.  
  571.              const Action action = state.get_random_action();
  572.              state.move(action);
  573.          }
  574.          return state.get_player();
  575.      }
  576.  
  577.      inline Action get_best_action(int time_limit) {
  578.          clock_t start = clock();
  579.  
  580.          int iterations = 0;
  581.  
  582.          std::cerr << "start\n";
  583.          do {
  584.  
  585.              Node *node = select(root);
  586.  
  587.              Color loser = simulate(node);
  588.  
  589.              node->backpropagate(loser);
  590.  
  591.              iterations++;
  592.  
  593.          } while((clock() - start) * 1000 < CLOCKS_PER_SEC * time_limit * 90 / 100);
  594.  
  595.          std::cerr << "iterations: " << iterations << '\n';
  596.  
  597.          std::cerr << std::fixed << std::setprecision(6) << float(root->get_win_cnt()) / root->get_vis_cnt() * 100 << "%" << '\n';
  598.  
  599.          return root->get_best_action();
  600.      }
  601.  
  602.      inline void pass_action(Action action) {
  603.          root = root->pass_action(action);
  604.          root->set_as_root();
  605.      }
  606.  };
  607.  
  608.  // *** End of: /home/olaf/clobber/MCTS/mcts.h ***
  609.  
  610. MCTS mcts;
  611.  
  612. int main() {
  613.     int board_size;
  614.     std::cin >> board_size; std::cin.ignore();
  615.     std::string color;
  616.     std::cin >> color; std::cin.ignore();
  617.  
  618.     std::cerr << board_size << '\n';
  619.     std::cerr << color << '\n';
  620.  
  621.     int time_limit = 1000;
  622.     for(int turn = 0; ; turn += 2) {
  623.         for(int i = 0; i < board_size; i++) {
  624.             std::string line;
  625.             std::cin >> line; std::cin.ignore();
  626.             std::cerr << line << '\n';
  627.         }
  628.  
  629.         std::string last_action;
  630.         std::cin >> last_action; std::cin.ignore();
  631.         std::cerr << last_action << '\n';
  632.         int action_count;
  633.         std::cin >> action_count; std::cin.ignore();
  634.         std::cerr << action_count << '\n';
  635.  
  636.         if(last_action != "null") {
  637.             mcts.pass_action(from_string(last_action));
  638.         }
  639.        
  640.         Action best_action = mcts.get_best_action(time_limit);
  641.        
  642.         std::cout << to_string(best_action) << '\n';        
  643.        
  644.         mcts.pass_action(best_action);
  645.        
  646.         time_limit = 100;
  647.     }
  648. }
  649.  
  650. // *** End of: /home/olaf/clobber/main.cpp ***
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement