Advertisement
Hinski2

Untitled

May 21st, 2024
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.24 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. enum {black, white, blank};
  5. typedef pair<int, int> pii;
  6. typedef vector<vector<int>> vvi;
  7. const int max_tree_deep = 9;
  8. const int inf = 1e9 + 7;
  9. const int max_player = black;
  10. const int min_player = white;
  11.  
  12. struct State{
  13.     vvi board;
  14.     int deep;
  15.     int player;
  16.     int alfa;
  17.     int beta;
  18.     int val;
  19.     vector<pii> black_poss;
  20.     vector<pii> white_poss;
  21. };
  22.  
  23.  
  24. void set_initial_state(State &state, int player){
  25.     state.board.resize(8);
  26.     for(int i = 0; i < 8; i++){
  27.         state.board[i].resize(8);
  28.         for(int j = 0; j < 8; j++)
  29.             state.board[i][j] = blank;
  30.     }
  31.  
  32.     state.board[3][3] = state.board[4][4] = black;
  33.     state.board[3][4] = state.board[4][3] = white;
  34.     state.black_poss.push_back({3, 3});
  35.     state.black_poss.push_back({4, 4});
  36.     state.white_poss.push_back({3, 4});
  37.     state.white_poss.push_back({4, 3});
  38.    
  39.     state.deep = 0;
  40.     state.player = player;
  41.     state.alfa = -inf;
  42.     state.beta = inf;
  43.     state.val = (player == max_player ? -inf : inf);
  44. }
  45.  
  46. bool valid_coord(const pii &poss){
  47.     return 0 <= poss.first && poss.first < 8 && 0 <= poss.second && poss.second < 8;
  48. }
  49.  
  50. void make_move(State &child, const pii &move){
  51.     //zmiana na chwile
  52.     child.player ^= 1;
  53.  
  54.     const int &x = move.first, &y = move.second;
  55.     vector<pii> &my_poss = (child.player == black ? child.black_poss : child.white_poss);
  56.     vector<pii> &his_poss = (child.player == black ? child.white_poss : child.black_poss);
  57.  
  58.     child.board[x][y] = child.player;
  59.     my_poss.push_back(move);
  60.  
  61.     for(int i: {-1, 0, 1}){
  62.         for(int j: {-1, 0, 1}){
  63.             if(!i && !j) continue;
  64.             pii poss = {x + i, y + j};
  65.             vector<pii> to_flip;
  66.  
  67.             while(valid_coord(poss) && child.board[poss.first][poss.second] == child.player ^ 1){
  68.                 to_flip.push_back(poss);
  69.                 poss.first += i, poss.second += j;
  70.             }
  71.  
  72.             if(valid_coord(poss) && child.board[poss.first][poss.second] == child.player){
  73.                 for(auto [a, b]: to_flip){
  74.                     child.board[a][b] = child.player;
  75.                     my_poss.push_back({a, b});
  76.                     auto rm = find(his_poss.begin(), his_poss.end(), make_pair(a, b));
  77.  
  78.                     if(rm != his_poss.end()) his_poss.erase(rm);
  79.                 }
  80.             }
  81.         }
  82.     }
  83.  
  84.     child.player ^= 1;
  85. }
  86.  
  87. void make_child_from_state(const State &state, State &child, const pii &move){
  88.     child.board = state.board; // to jest kopia
  89.     child.deep = state.deep + 1;
  90.     child.player = state.player ^ 1;
  91.     child.alfa = state.alfa;
  92.     child.beta = state.beta;
  93.     child.val = (child.player == max_player ? -inf : inf);
  94.     child.black_poss = state.black_poss;
  95.     child.white_poss = state.white_poss;
  96.  
  97.     make_move(child, move);
  98. }
  99.  
  100. int eval_state(const State &state){
  101.     return state.black_poss.size() - state.white_poss.size();
  102. }
  103.  
  104.  
  105. vector<pii> generate_moves(const State &state){
  106.     vector<pii> possible_moves;
  107.     for(auto u: (state.player == black ? state.black_poss : state.white_poss)){
  108.         for(int i: {-1, 0, 1}){
  109.             for(int j: {-1, 0, 1}){
  110.                 if(!i and !j) continue;
  111.                 pii poss = {u.first + i, u.second + j};
  112.                 bool captured = false;
  113.  
  114.                 while(valid_coord(poss) && state.board[poss.first][poss.second] == (state.player ^ 1))
  115.                     captured = true, poss.first += i, poss.second += j;
  116.  
  117.                 if(valid_coord(poss) && state.board[poss.first][poss.second] == blank && captured)
  118.                     possible_moves.push_back(poss);
  119.             }
  120.         }
  121.     }
  122.  
  123.     return possible_moves;
  124. }
  125.  
  126. State min_max(State state){
  127.     // sprawdzanie czy można grać
  128.     if(state.deep >= max_tree_deep){
  129.         state.val = eval_state(state);
  130.         return state;
  131.     }
  132.  
  133.     vector<pii> possible_moves = generate_moves(state);
  134.     if(possible_moves.size() == 0){
  135.         state.val = eval_state(state);
  136.         return state;
  137.     }
  138.  
  139.     // moge grać
  140.     for(const auto move: possible_moves){
  141.         State child; make_child_from_state(state, child, move);
  142.         child = min_max(child);
  143.        
  144.         if(state.player == max_player){
  145.             state.val = max(state.val, child.val);
  146.             state.alfa = max(state.alfa, state.val);
  147.  
  148.             if(state.val >= state.beta)
  149.                 break;
  150.         }
  151.         else if(state.player == min_player){
  152.             state.val = min(state.val, child.val);
  153.             state.beta = min(state.beta, state.val);
  154.             if(state.val <= state.alfa)
  155.                 break;
  156.         }
  157.     }
  158.  
  159.     return state;
  160. }
  161.  
  162. State choose_random(const State &state){
  163.     vector<pii> possible_moves = generate_moves(state);
  164.     int idx = rand() % possible_moves.size();
  165.     State child; make_child_from_state(state, child, possible_moves[idx]);
  166.     return child;
  167. }
  168.  
  169. long seed()
  170. {
  171.     auto t=chrono::system_clock::now();
  172.     return std::chrono::duration_cast<std::chrono::milliseconds>(t.time_since_epoch()).count();
  173. }
  174.  
  175. int eval_end_board(State state){
  176.     if(state.black_poss.size() > state.white_poss.size()) return black;
  177.     return white;
  178. }
  179.  
  180. State choose_smart(State state){
  181.     State best_child;
  182.     vector<pii> possible_moves = generate_moves(state);
  183.  
  184.     for(auto move: possible_moves){
  185.         State child; make_child_from_state(state, child, move);
  186.         child = min_max(child);
  187.        
  188.         if(state.player == max_player){
  189.             if(child.val > state.val){
  190.                 state.val = child.val;
  191.                 best_child = child;
  192.             }
  193.  
  194.             state.alfa = max(state.alfa, state.val);
  195.             if(state.val >= state.beta)
  196.                 break;
  197.        
  198.         }
  199.         else if(state.player == min_player){
  200.             if(child.val < state.val){
  201.                 state.val = child.val;
  202.                 best_child = child;
  203.             }
  204.  
  205.             state.beta = min(state.beta, state.val);
  206.             if(state.val <= state.alfa)
  207.                 break;
  208.         }
  209.     }
  210.  
  211.     return best_child;
  212. }
  213.  
  214. // debug
  215. void print_board(const State state);
  216.  
  217. int main(){    
  218.     srand(seed());
  219.     pii score = {0, 0};
  220.     for(int i = 0; i < 1000; i++){
  221.  
  222.         // ustawianie gry
  223.         State state;
  224.         set_initial_state(state, black);
  225.  
  226.         // gra dopuki ktoś nie wygra
  227.         for(int turn = 0; !generate_moves(state).empty(); turn ^= 1){
  228.             if(turn == black)
  229.                 state = choose_smart(state);
  230.             else
  231.                 state = choose_random(state);
  232.             // print_board(state); //debug
  233.         }
  234.  
  235.         if(eval_end_board(state) == black) score.first += 1;
  236.         else score.second += 1;
  237.         cout << "black: " << score.first << " white: " << score.second << endl;
  238.     }
  239. }
  240.  
  241. void print_board(const State state){
  242.     cout << (state.player == black ^ 1 ? "black" : "white") << endl;
  243.     for(int i = 0; i < 8; i++){
  244.         for(int j = 0; j < 8; j++)
  245.             if(state.board[i][j] == black) cout << 'B' << ' ';
  246.             else if(state.board[i][j] == white) cout << 'W' << ' ';
  247.             else cout << '.' << ' ';
  248.         cout << endl;
  249.     }
  250.     cout << endl;
  251. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement