Guest User

akulsareen game of amazons code

a guest
Jan 19th, 2016
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.65 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef pair<int,int> pii;
  4. int MAX_DEP;
  5. const int BOARD_SZ = 10;
  6. const int INF = 1000000000;
  7. struct MOVE
  8. {
  9.     pair <int,int> sp,fp,ap;
  10.     int val;
  11. };
  12. bool sorter(const MOVE &x, const MOVE &y)
  13. {
  14.     return x.val > y.val;
  15. }
  16. int P1, tot_iter, pruned, early_break, deepest, heu_break;
  17. int dr[] = {-1,-1,-1,0,0,1,1,1}, dc[] = {-1,0,1,-1,1,-1,0,1};
  18. bool alternate_limits;
  19. double alt_ratio;
  20. bool is_ok(int r, int c, int board[][BOARD_SZ])
  21. {
  22.     if(r < 0 || r >= 10 || c < 0 || c >= 10)
  23.         return false;
  24.     if(board[r][c] != 0)
  25.         return false;
  26.     return true;
  27. }
  28. bool is_almost_ok(int r, int c, int board[][BOARD_SZ])
  29. {
  30.     if(r < 0 || r >= 10 || c < 0 || c >= 10)
  31.         return false;
  32.     if(board[r][c] == -1)
  33.         return false;
  34.     return true;
  35. }
  36. void print_board(int board[][BOARD_SZ])
  37. {
  38.     for (int i = 0; i < 10; ++i)
  39.     {
  40.         for (int j = 0; j < 10; ++j)
  41.         {
  42.             cout<<board[i][j]<<"\t";
  43.         }
  44.         cout<<"\n";
  45.     }
  46.     cout<<"\n\n";
  47. }
  48. inline void apply_MOVE(int board[][BOARD_SZ], const MOVE &mv)
  49. {
  50.     swap(board[mv.sp.first][mv.sp.second],board[mv.fp.first][mv.fp.second]);
  51.     board[mv.ap.first][mv.ap.second] = -1;
  52. }
  53. inline void withdraw_MOVE(int board[][BOARD_SZ], const MOVE &mv)
  54. {
  55.     board[mv.ap.first][mv.ap.second] = 0;
  56.     swap(board[mv.sp.first][mv.sp.second],board[mv.fp.first][mv.fp.second]);
  57. }
  58. int board_eval(int board[][BOARD_SZ])
  59. {
  60.     vector < vector <int> > d1(10,vector <int> (10,INF));
  61.     vector < vector <int> > d2 = d1;
  62.     queue <pii> bfs;
  63.     for (int i = 0; i < 10; ++i)
  64.     {
  65.         for (int j = 0; j < 10; ++j)
  66.         {
  67.             if(board[i][j] == P1)
  68.             {
  69.                 d1[i][j] = 0;
  70.                 bfs.push(pii(i,j));
  71.             }
  72.         }
  73.     }
  74.     while(!bfs.empty())
  75.     {
  76.         pii top = bfs.front();
  77.         bfs.pop();
  78.         for (int i = 0; i < 8; ++i)
  79.         {
  80.             int r = top.first, c = top.second;
  81.             while(is_ok(r+dr[i],c+dc[i],board) && d1[r+dr[i]][c+dc[i]] == INF)
  82.             {
  83.                 r+=dr[i];
  84.                 c+=dc[i];
  85.                 d1[r][c] = d1[top.first][top.second]+1;
  86.                 bfs.push(pii(r,c));
  87.             }
  88.         }
  89.     }
  90.     for (int i = 0; i < 10; ++i)
  91.     {
  92.         for (int j = 0; j < 10; ++j)
  93.         {
  94.             if(board[i][j] == 3-P1)
  95.             {
  96.                 d2[i][j] = 0;
  97.                 bfs.push(pii(i,j));
  98.             }
  99.         }
  100.     }
  101.     while(!bfs.empty())
  102.     {
  103.         pii top = bfs.front();
  104.         bfs.pop();
  105.         for (int i = 0; i < 8; ++i)
  106.         {
  107.             int r = top.first, c = top.second;
  108.             while(is_ok(r+dr[i],c+dc[i],board) && d2[r+dr[i]][c+dc[i]] == INF)
  109.             {
  110.                 r+=dr[i];
  111.                 c+=dc[i];
  112.                 d2[r][c] = d2[top.first][top.second]+1;
  113.                 bfs.push(pii(r,c));
  114.             }
  115.         }
  116.     }
  117.     int ans = 0;
  118.     for (int i = 0; i < 10; ++i)
  119.     {
  120.         for (int j = 0; j < 10; ++j)
  121.         {
  122.             if(d1[i][j] < d2[i][j])
  123.                 ans++;
  124.             if(d1[i][j] > d2[i][j])
  125.                 ans--;
  126.         }
  127.     }
  128.     return ans;
  129. }
  130. bool is_finished(int board[][BOARD_SZ])
  131. {
  132.     vector < vector <int> > d1(10,vector <int> (10,INF));
  133.     vector < vector <int> > d2 = d1;
  134.     queue <pii> bfs;
  135.     for (int i = 0; i < 10; ++i)
  136.     {
  137.         for (int j = 0; j < 10; ++j)
  138.         {
  139.             if(board[i][j] == P1)
  140.             {
  141.                 d1[i][j] = 0;
  142.                 bfs.push(pii(i,j));
  143.             }
  144.         }
  145.     }
  146.     while(!bfs.empty())
  147.     {
  148.         pii top = bfs.front();
  149.         bfs.pop();
  150.         for (int i = 0; i < 8; ++i)
  151.         {
  152.             int r = top.first, c = top.second;
  153.             while(is_almost_ok(r+dr[i],c+dc[i],board) && d1[r+dr[i]][c+dc[i]] == INF)
  154.             {
  155.                 r+=dr[i];
  156.                 c+=dc[i];
  157.                 d1[r][c] = d1[top.first][top.second]+1;
  158.                 bfs.push(pii(r,c));
  159.             }
  160.         }
  161.     }
  162.     for (int i = 0; i < 10; ++i)
  163.     {
  164.         for (int j = 0; j < 10; ++j)
  165.         {
  166.             if(board[i][j] == 3-P1)
  167.             {
  168.                 d2[i][j] = 0;
  169.                 bfs.push(pii(i,j));
  170.             }
  171.         }
  172.     }
  173.     while(!bfs.empty())
  174.     {
  175.         pii top = bfs.front();
  176.         bfs.pop();
  177.         for (int i = 0; i < 8; ++i)
  178.         {
  179.             int r = top.first, c = top.second;
  180.             while(is_almost_ok(r+dr[i],c+dc[i],board) && d2[r+dr[i]][c+dc[i]] == INF)
  181.             {
  182.                 r+=dr[i];
  183.                 c+=dc[i];
  184.                 d2[r][c] = d2[top.first][top.second]+1;
  185.                 bfs.push(pii(r,c));
  186.             }
  187.         }
  188.     }
  189.     for (int i = 0; i < 10; ++i)
  190.     {
  191.         for (int j = 0; j < 10; ++j)
  192.         {
  193.             if(d1[i][j]+d2[i][j] < INF)
  194.                 return false;
  195.         }
  196.     }
  197.     return true;
  198. }
  199. void get_MOVEs(int board[][BOARD_SZ], int pl, vector <MOVE> &all_MOVEs, int BRANCHES = 1000)
  200. {
  201.     int p1,p2;
  202.     if(pl == 1)
  203.     {
  204.         p1 = P1;
  205.         p2 = 3-p1;
  206.     }
  207.     else
  208.     {
  209.         p1 = 3-P1;
  210.         p2 = P1;
  211.     }
  212.     vector < vector <int> > neigh_ctr(10, vector <int> (10,0));
  213.     vector < vector <int> > path_ctr = neigh_ctr;
  214.     //
  215.     for (int i = 0; i < 10; ++i)
  216.     {
  217.         for (int j = 0; j < 10; ++j)
  218.         {
  219.             //
  220.             for (int k = 0; k < 8; ++k)
  221.             {
  222.                 if(!is_ok(i+dr[k],j+dc[k],board))
  223.                     neigh_ctr[i][j]++;
  224.             }
  225.             //
  226.             if(board[i][j] == p2)
  227.             {
  228.                 for (int k = 0; k < 8; ++k)
  229.                 {
  230.                     int r = i, c = j, cd = 1;
  231.                     while(is_ok(r+dr[k],c+dc[k],board))
  232.                     {
  233.                         r+=dr[k];
  234.                         c+=dc[k];
  235.                         cd++;
  236.                         path_ctr[r][c]+=15-cd;
  237.                     }
  238.                 }
  239.             }
  240.         }
  241.     }
  242.     // now check all of your own MOVEs
  243.     MOVE temp;
  244.     for (int i = 0; i < 10; ++i)
  245.     {
  246.         for (int j = 0; j < 10; ++j)
  247.         {
  248.             if(board[i][j] == p1)
  249.             {
  250.                 temp.sp.first = i;
  251.                 temp.sp.second = j;
  252.                 for (int k = 0; k < 8; ++k)
  253.                 {
  254.                     int r = i, c = j;
  255.                     while(is_ok(r+dr[k],c+dc[k],board))
  256.                     {
  257.                         r+=dr[k];
  258.                         c+=dc[k];
  259.                         temp.fp.first = r;
  260.                         temp.fp.second = c;
  261.                         swap(board[i][j],board[r][c]);
  262.                         for (int l = 0; l < 8; ++l)
  263.                         {
  264.                             int tr = r, tc = c;
  265.                             while(is_ok(tr+dr[l],tc+dc[l],board))
  266.                             {
  267.                                 tr+=dr[l];
  268.                                 tc+=dc[l];
  269.                                 temp.ap.first = tr;
  270.                                 temp.ap.second = tc;
  271.                                 temp.val = neigh_ctr[i][j]*neigh_ctr[i][j] - neigh_ctr[r][c] + path_ctr[r][c] + 2*(path_ctr[tr][tc] + neigh_ctr[tr][tc]);
  272.                                 all_MOVEs.push_back(temp);
  273.                             }
  274.                         }
  275.                         swap(board[i][j],board[r][c]);
  276.                     }
  277.                 }
  278.             }
  279.         }
  280.     }
  281.     sort(all_MOVEs.begin(), all_MOVEs.end(), sorter);
  282.     if(all_MOVEs.size() <= BRANCHES)
  283.         return;
  284.     all_MOVEs.resize(min(3*BRANCHES/2,(int)all_MOVEs.size()));
  285.     random_shuffle(all_MOVEs.begin(), all_MOVEs.end());
  286.     all_MOVEs.resize(min(BRANCHES,(int)all_MOVEs.size()));
  287.     sort(all_MOVEs.begin(), all_MOVEs.end(), sorter);
  288. }
  289. MOVE alpha_beta(int board[][BOARD_SZ], int depth, int alpha, int beta)
  290. {
  291.     // int lala;
  292.     // cin>>lala;
  293.     // cout<<"entering: "<<alpha<<" "<<beta<<" "<<" at depth = "<<depth<<"\n";
  294.     MOVE ret;
  295.     tot_iter++;
  296.     if(depth == MAX_DEP || (clock() >= alt_ratio*CLOCKS_PER_SEC && depth >= 3))
  297.     {
  298.         if(depth < 3)
  299.             early_break++;
  300.         if(depth == MAX_DEP)
  301.             deepest++;
  302.         ret.val = board_eval(board);
  303.         // cout<<"early ret = "<<ret.val<<"\n";
  304.         return ret;
  305.     }
  306.     // print_board(board);
  307.     if(depth%2)
  308.         ret.val = -INF;
  309.     else
  310.         ret.val = INF;
  311.     if(clock() >= 0.98*CLOCKS_PER_SEC)
  312.     {
  313.         if(depth < 3)
  314.             early_break++;
  315.         ret.val*=-1;
  316.         return ret;
  317.     }
  318.     // odd depth = P1 = max. node
  319.     // even depth = P2 = min.node
  320.     if(depth >= 2 && is_finished(board))
  321.     {
  322.         ret.val = board_eval(board);
  323.         heu_break++;
  324.         return ret;
  325.     }
  326.     vector <MOVE> all_MOVEs;
  327.     if(depth <= 2)
  328.         get_MOVEs(board,depth%2,all_MOVEs);
  329.     else if(depth <= 4)
  330.         get_MOVEs(board,depth%2,all_MOVEs,500);
  331.     else
  332.         get_MOVEs(board,depth%2,all_MOVEs,100);
  333.     if(all_MOVEs.empty())
  334.     {
  335.         ret.val = board_eval(board);
  336.         return ret;
  337.     }
  338.     for (int i = 0; i < all_MOVEs.size() && alpha < beta; ++i)
  339.     {
  340.         apply_MOVE(board,all_MOVEs[i]);
  341.         MOVE temp = alpha_beta(board,depth+1,alpha,beta);
  342.         withdraw_MOVE(board,all_MOVEs[i]);
  343.         if(depth%2)
  344.         {
  345.             if(temp.val > alpha)
  346.                 alpha = temp.val;
  347.             if(temp.val > ret.val)
  348.             {
  349.                 ret = all_MOVEs[i];
  350.                 ret.val = temp.val;
  351.             }
  352.         }
  353.         else
  354.         {
  355.             if(temp.val < beta)
  356.                 beta = temp.val;
  357.             if(temp.val < ret.val)
  358.             {
  359.                 ret = all_MOVEs[i];
  360.                 ret.val = temp.val;
  361.             }
  362.         }
  363.         if(alpha >= beta)
  364.             pruned++;
  365.     }
  366.     return ret;
  367. }
  368. int main()
  369. {
  370.     // freopen("input.txt", "r", stdin);
  371.     srand(92812038);
  372.     int board[BOARD_SZ][BOARD_SZ];
  373.     //
  374.     for (int i = 0; i < 10; ++i)
  375.     {
  376.         for (int j = 0; j < 10; ++j)
  377.         {
  378.             cin>>board[i][j];
  379.         }
  380.     }
  381.     cin>>P1;
  382.     // for some reason bit doesnt play well when it is player 2
  383.     // making sure it is not some stupid fault somewhere in the code
  384.     // by changing code to always run on player 1
  385.     if(P1 == 2)
  386.     {
  387.         for (int i = 0; i < 10; ++i)
  388.         {
  389.             for (int j = 0; j < 10; ++j)
  390.             {
  391.                 if(board[i][j] == 2)
  392.                     board[i][j] = 1;
  393.                 else if(board[i][j] == 1)
  394.                     board[i][j] = 2;
  395.                 else
  396.                 {
  397.                     //
  398.                 }
  399.             }
  400.         }
  401.         P1 = 1;
  402.     }
  403.     //
  404.     vector <MOVE> lala;
  405.     get_MOVEs(board,1,lala);
  406.     alt_ratio = 0.95;
  407.     MAX_DEP = 45;
  408.     for (int i = 50; i <= 1050; i+=50, alt_ratio-=0.02, MAX_DEP--)
  409.     {
  410.         if(lala.size() <= i)
  411.             break;
  412.     }
  413.     MOVE ans = alpha_beta(board,1,-INF,INF);
  414.     cout<<ans.sp.first<<" "<<ans.sp.second<<"\n";
  415.     cout<<ans.fp.first<<" "<<ans.fp.second<<"\n";
  416.     cout<<ans.ap.first<<" "<<ans.ap.second<<"\n";
  417.     cout<<"stats: "<<ans.val<<" "<<MAX_DEP<<" : ("<<early_break<<","<<deepest<<","<<tot_iter<<") "<<heu_break<<"\n";
  418.     return 0;
  419. }
Add Comment
Please, Sign In to add comment