Advertisement
pdpd123

Untitled

May 30th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.26 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define INF 9223372036854775807
  4. #define TIE 9223372036854775806
  5. #define REPLR(i) for(long long i=LEFT;i<RIGHT;i++)
  6. using namespace std;
  7.  
  8. const int LIMIT = 10;
  9. const int DEPTH = 3;
  10.  
  11. const int COMPUTER = 1;
  12. const int PLAYER = 2;
  13. const int EMPTY = 0;
  14. const int BOARDER = 3;
  15.  
  16. const int SIZE = 15;
  17. const int BOARDSIZE = SIZE + 15;
  18. const int LEFT = 10, RIGHT = LEFT + SIZE;
  19. const int CENTER = LEFT + RIGHT >> 1;
  20.  
  21. int board[BOARDSIZE][BOARDSIZE];
  22.  
  23. void initialize(){
  24.     for(int i=0;i<BOARDSIZE;i++)
  25.         for(int j=0;j<BOARDSIZE;j++)
  26.             board[i][j]=BOARDER;
  27.     REPLR(i) REPLR(j) board[i][j]=EMPTY;
  28. }
  29.  
  30. void showBoard(){
  31.     cout << "   ";
  32.     REPLR(i) cout << setw(2) << char(i-LEFT+'A');
  33.     cout << endl;
  34.     REPLR(j){
  35.         cout << setw(3) << j-LEFT+1 << ' ';
  36.         REPLR(i){
  37.             if(board[i][j] == EMPTY)
  38.                 cout << "- ";
  39.             if(board[i][j] == COMPUTER)
  40.                 cout << "O ";
  41.             if(board[i][j] == PLAYER)
  42.                 cout << "X ";
  43.         }
  44.         cout << endl;
  45.     }
  46.     cout << endl;
  47. }
  48.  
  49. vector<int> countPattern(int x,int y,int dx,int dy){
  50.     vector<int> cnt = {0,0,0,0};
  51.     for(int i=0;i<5;i++){
  52.         cnt[board[x+i*dx][y+i*dy]]++;
  53.     }
  54.     int maxlen = 0, len = 0;
  55.     for(int i=0;i<5;i++){
  56.         if(board[x+i*dx][y+i*dy] == COMPUTER)
  57.             maxlen = max(maxlen, ++len);
  58.         else len = 0;
  59.     }
  60.     cnt[COMPUTER] = maxlen;
  61.     for(int i=0;i<5;i++){
  62.         if(board[x+i*dx][y+i*dy] == PLAYER)
  63.             maxlen = max(maxlen, ++len);
  64.         else len = 0;
  65.     }
  66.     cnt[PLAYER] = maxlen;
  67.     return cnt;
  68. }
  69.  
  70. int evaluate(){
  71.     vector<pair<int,int>> patterns = {{0,1},{1,0},{1,1},{1,-1}};
  72.     int score = 0;
  73.     int TIMES = 0;
  74.     REPLR(i)
  75.         REPLR(j)
  76.             for(auto pattern: patterns){
  77.                 vector<int> cnt = countPattern(i,j,pattern.first,pattern.second);
  78.                 if(cnt[BOARDER] || cnt[EMPTY] == 5 || (cnt[PLAYER] && cnt[COMPUTER]))
  79.                     continue;
  80.                 else TIMES++;
  81.                 if(!cnt[PLAYER]){
  82.                     score += pow(50, 2*cnt[COMPUTER]-1);
  83.                     if(cnt[COMPUTER] == 5) return INF;
  84.                 }
  85.                 else if(!cnt[COMPUTER]){
  86.                     score -= pow(50, 2*cnt[PLAYER]);
  87.                     if(cnt[PLAYER] == 5) return -INF;
  88.                 }
  89.             }
  90.     if(!TIMES) return TIE;
  91.     return score + rand()%2500;
  92. }
  93.  
  94. int playersTurn(){
  95.     showBoard();
  96.     char row;
  97.     int col;
  98.     do{
  99.         cout << "INSERT THE LOCATION: ";
  100.         cin >> row >> col;
  101.         row = toupper(row);
  102.         --col;
  103.     }while( !('A' <= row && row < 'A'+SIZE && 0 <= col && col < SIZE
  104.               && board[row-'A'+LEFT][col+LEFT] == EMPTY ) );
  105.     board[row-'A'+LEFT][col+LEFT] = PLAYER;
  106.     int result = evaluate();
  107.     if(result == -INF) return PLAYER;
  108.     else if(result == TIE) return BOARDER;
  109.     return EMPTY;
  110. }
  111.  
  112. pair<int,pair<int,int>> minimax(int depth,int alpha,int beta,bool ismaximizing){
  113.     pair<int,int> moves = {0,0};
  114.     int staticEval = evaluate();
  115.     if(!depth || staticEval == INF || staticEval == -INF) return {staticEval,moves};
  116.     if(staticEval == TIE) return {0,moves};
  117.  
  118.     if(ismaximizing){
  119.         vector<pair<int,pair<int,int>>> scores;
  120.         REPLR(i) REPLR(j) if(board[i][j] == EMPTY){
  121.             board[i][j] = COMPUTER;
  122.             int result = evaluate();
  123.             scores.push_back({result,{i,j}});
  124.             board[i][j] = EMPTY;
  125.         }
  126.         sort(scores.begin(),scores.end(),greater<pair<int,pair<int,int>>>());
  127.         int maxEval = -INF;
  128.         bool purn = false;
  129.         int counter = 0;
  130.         for(auto position: scores){
  131.         if(++counter >= LIMIT) break;
  132.         int i = position.second.first;
  133.         int j = position.second.second;
  134.             if(!purn && board[i][j] == EMPTY){
  135.                 board[i][j] = COMPUTER;
  136.                 int eval = minimax(depth-1, alpha, beta, false).first;
  137.                 if(eval > maxEval){
  138.                     maxEval = max(maxEval, eval);
  139.                     moves = {i,j};
  140.                 }
  141.                 alpha = max(alpha, eval);
  142.                 if(beta <= alpha) purn = true;
  143.                 board[i][j] = EMPTY;
  144.             }
  145.         }
  146.         return {maxEval,moves};
  147.     }
  148.     else{
  149.         vector<pair<int,pair<int,int>>> scores;
  150.         REPLR(i) REPLR(j) if(board[i][j] == EMPTY){
  151.             board[i][j] = PLAYER;
  152.             int result = evaluate();
  153.             scores.push_back({result,{i,j}});
  154.             board[i][j] = EMPTY;
  155.         }
  156.         sort(scores.begin(),scores.end());
  157.         int minEval = INF;
  158.         bool purn = false;
  159.         int counter = 0;
  160.         for(auto position: scores){
  161.         if(++counter >= LIMIT) break;
  162.         int i = position.second.first;
  163.         int j = position.second.second;
  164.             if(!purn && board[i][j] == EMPTY){
  165.                 board[i][j] = PLAYER;
  166.                 int eval = minimax(depth-1, alpha, beta, false).first;
  167.                 if(eval < minEval){
  168.                     minEval = min(minEval, eval);
  169.                     moves = {i,j};
  170.                 }
  171.                 alpha = min(alpha, eval);
  172.                 if(beta <= alpha) purn = true;
  173.                 board[i][j] = EMPTY;
  174.             }
  175.         }
  176.         return {minEval,moves};
  177.     }
  178. }
  179.  
  180. int computersTurn(){
  181.     auto res = minimax(DEPTH, -INF, INF, false);
  182.     int nextx = res.second.first;
  183.     int nexty = res.second.second;
  184.     board[nextx][nexty] = COMPUTER;
  185.     system("cls");
  186.     cout << "     COMPUTER: " << char(nextx-LEFT+'A') << nexty-LEFT+1 << endl << endl;
  187.     int result = evaluate();
  188.     if(result == INF) return COMPUTER;
  189.     else if(result == TIE) return BOARDER;
  190.     return EMPTY;
  191. }
  192.  
  193. signed main(){
  194.     srand(time(0));
  195.     initialize();
  196.     int winner = EMPTY;
  197.     board[CENTER][CENTER] = COMPUTER;
  198.     while(winner == EMPTY){
  199.         winner = playersTurn();
  200.         if(winner != EMPTY) break;
  201.         winner = computersTurn();
  202.     }
  203.     system("cls");
  204.     showBoard();
  205.     cout << "WINNER: ";
  206.     if(winner == PLAYER) cout << "PLAYER\n";
  207.     if(winner == COMPUTER) cout << "COMPUTER\n";
  208.     if(winner == BOARDER) cout << "TIE!\n";
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement