Advertisement
Kaidul

16 pawn with Minimax

Dec 29th, 2013
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.40 KB | None | 0 0
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <string>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <utility>
  9.  
  10. using namespace std;
  11.  
  12. #define Max 5
  13. #define computer '*'
  14. #define human 'o'
  15. #define blank '-'
  16. #define infinity (1 << 30)
  17.  
  18. char board[Max + 1][Max + 1];
  19.  
  20. int dirX[] = {0, -1, 0, 1};
  21. int dirY[] = {-1, 0, 1, 0};
  22. int diagDirX[] = {0, -1, -1, -1, 0, 1, 1, 1};
  23. int diagDirY[] = {-1, -1, 0, 1, 1, 1, 0, -1};
  24. pair <int, int> dummy = make_pair(-1, -1);
  25.  
  26. void printGameState() {
  27.     for(int i = 0; i < Max; ++i) {
  28.         for(int j = 0; j < Max; ++j) {
  29.             if(j == 0) printf("%c", board[i][j]);
  30.             else printf("%5c", board[i][j]);
  31.         }
  32.         printf("\n\n");
  33.     }
  34. }
  35.  
  36. void initializeGame() {
  37.     memset(board, blank, sizeof board);
  38. //    for(int i = 1; i < 2; ++i) {
  39. //        for(int j = 0; j < Max; ++j) {
  40. //            board[i][j] = human;
  41. //        }
  42. //    }
  43. //    for(int i = Max - 1 - 1; i > 2; --i) {
  44. //        for(int j = 0; j < Max; ++j) {
  45. //            board[i][j] = computer;
  46. //        }
  47. //    }
  48. //    board[3][2] = blank;
  49. //    board[2][2] = computer;
  50. //    board[3][0] = blank;
  51.  
  52.     board[1][0] = human;
  53.     board[2][0] = computer;
  54.     board[3][1] = computer;
  55.     board[3][4] = computer;
  56.  
  57.     printGameState();
  58. }
  59.  
  60. bool isEngaged(int x, int y) {
  61.     return board[x][y] == human or board[x][y] == computer;
  62. }
  63.  
  64. bool isValid(int x, int y) {
  65.     return (x >= 0 and x < Max) and (y >= 0 and y < Max);
  66. }
  67.  
  68. vector < pair<int ,int> > AvailableMove(int x, int y) {
  69. //    printf("%d %d\n", x, y);
  70.     vector < pair<int ,int> > cells;
  71.  
  72.     if( (x & 1 and y & 1) or (x & 1 == 0 and y & 1 == 0) ) { // i.e. (1, 1) or (2, 4)
  73.  
  74.         for(int i = 0, n = sizeof(diagDirX) / sizeof(diagDirX[0]); i < n; ++i) {
  75.             int posX = x + diagDirX[i], posY = y + diagDirY[i];
  76.  
  77.             if(isValid(posX, posY)) {
  78.                 if(!isEngaged(posX, posY))
  79.                     cells.push_back( make_pair(posX, posY) );
  80.             }
  81.  
  82.             // one step ahead
  83.             int prevX = posX, prevY = posY;
  84.             posX += diagDirX[i], posY += diagDirY[i];
  85.             if(isValid(posX, posY)) {
  86.                 if(isEngaged(prevX, prevY) and !isEngaged(posX, posY))
  87.                     cells.push_back( make_pair(posX, posY) );
  88.             }
  89.         }
  90.     } else {
  91.         for(int i = 0, n = sizeof(dirX) / sizeof(dirX[0]); i < n; ++i) {
  92.             int posX = x + dirX[i], posY = y + dirY[i];
  93.  
  94.             if(isValid(posX, posY)) {
  95.                 if(!isEngaged(posX, posY))
  96.                     cells.push_back( make_pair(posX, posY) );
  97.             }
  98.  
  99.             // one step ahead
  100.             int prevX = posX, prevY = posY;
  101.             posX += dirX[i], posY += dirY[i];
  102.             if(isValid(posX, posY)) {
  103.                 if( isEngaged(prevX, prevY) and !isEngaged(posX, posY) )
  104.                     cells.push_back( make_pair(posX, posY) );
  105.             }
  106.         }
  107.     }
  108.     return cells;
  109. }
  110.  
  111. void printPossibleMoves(vector <pair <int, int> > result) {
  112.     printf("All possible Moves:\n");
  113.     for(vector <pair <int ,int> >:: iterator it = result.begin(); it != result.end(); ++it) {
  114.         printf("(%d, %d)\n", (*it).first, (*it).second);
  115.     }
  116. }
  117.  
  118. bool isHumanWin() {
  119.     for(int i = 0; i < Max; ++i)
  120.         if(find(board[i], board[i] + Max, computer) != board[i] + Max)
  121.             return false;
  122.     return true;
  123. }
  124.  
  125. bool isComputerWin() {
  126.     for(int i = 0; i < Max; ++i)
  127.         if(find(board[i], board[i] + Max, human) != board[i] + Max)
  128.             return false;
  129.     return true;
  130. }
  131.  
  132. bool isTerminateState() {
  133.     if(isHumanWin() or isComputerWin())
  134.         return true;
  135.     return false;
  136. }
  137.  
  138. bool isAhead(int fromX, int fromY, int toX, int toY) {
  139.     return abs(toX - fromX) > 1 or abs(toY - fromY) > 1;
  140. }
  141.  
  142. pair <int, int> terminate(int fromX, int fromY, int toX, int toY, char who) {
  143.     int disMissX, disMissY;
  144.     disMissX = abs(toX - fromX) > 1 ? (toX + fromX) / 2 : toX;
  145.     disMissY = abs(toY - fromY) > 1 ? (toY + fromY) / 2 : toY;
  146.     char opposite = (who == human) ? computer : human;
  147.     if(board[disMissX][disMissY] == opposite) {
  148.         return make_pair(disMissX, disMissY);
  149.     } else {
  150.         return dummy;
  151.     }
  152. }
  153.  
  154. bool takeAction(int fromX, int fromY, int toX, int toY, char who) {
  155.     board[toX][toY] = who;
  156.     board[fromX][fromY] = blank;
  157.     if( isAhead(fromX, fromY, toX, toY) ) {
  158.         pair <int, int> point = terminate(fromX, fromY, toX, toY, who);
  159.         if(point != dummy) {
  160.             board[point.first][point.second] = blank;
  161.             printf("state: \n");
  162.             printGameState();
  163.             return true;
  164.         }
  165.     }
  166.     printf("state: \n");
  167.     printGameState();
  168.     return false;
  169. }
  170.  
  171. void undoAction(int fromX, int fromY, int toX, int toY, char who, bool removed) {
  172.     board[toX][toY] = blank;
  173.     board[fromX][fromY] = who;
  174.     char player = (who == computer) ? human : computer;
  175.     if(removed) {
  176.         int x = abs(toX - fromX) > 1 ? (toX + fromX) / 2 : toX;
  177.         int y = abs(toY - fromY) > 1 ? (toY + fromY) / 2 : toY;
  178.         board[x][y] = player;
  179.     }
  180. //    printf("state: \n");
  181. //    printGameState();
  182. }
  183.  
  184. vector < pair <int, int> > availablePawn(char who) {
  185.     vector < pair <int, int> > ret;
  186.     for(int i = 0; i < Max; ++i) {
  187.         for(int j = 0; j < Max; ++j) {
  188.             if(board[i][j] == who)
  189.                 ret.push_back( make_pair(i, j) );
  190.         }
  191.     }
  192.     return ret;
  193. }
  194.  
  195. int utilityValue() {
  196.     if(isComputerWin()) {
  197.         return +1;
  198.     } else if (isHumanWin()) {
  199.         return -1;
  200.     }
  201.     return 0;
  202. }
  203.  
  204. int minValue();
  205.  
  206. int maxValue() {
  207.     if(isTerminateState())
  208.         return utilityValue();
  209.     int best = -infinity, localBest;
  210.     bool isRemoved;
  211.     vector < pair <int, int> > availPawns = availablePawn(computer);
  212.     for(vector < pair <int, int> >:: iterator it = availPawns.begin(); it != availPawns.end(); ++it) {
  213.         int fromX = (*it).first, fromY = (*it).second;
  214.         vector < pair <int, int> > allPossibleMoves = AvailableMove(fromX, fromY);
  215.         for(vector < pair <int, int> >:: iterator i = allPossibleMoves.begin(); i != allPossibleMoves.end(); ++i) {
  216.             int toX = (*i).first, toY = (*i).second;
  217.             printf("Max\n");
  218.             isRemoved = takeAction(fromX, fromY, toX, toY, computer);
  219.             localBest = minValue();
  220.             undoAction(fromX, fromY, toX, toY, computer, isRemoved);
  221.             best = max(best, localBest);
  222.         }
  223.     }
  224.     return best;
  225. }
  226.  
  227.  
  228. int minValue() {
  229. //    printGameState();
  230.     if(isTerminateState())
  231.         return utilityValue();
  232.     int best = +infinity, localBest;
  233.     bool isRemoved;
  234.     vector < pair <int, int> > availPawns = availablePawn(human);
  235.     for(vector < pair <int, int> >:: iterator it = availPawns.begin(); it != availPawns.end(); ++it) {
  236.         int fromX = (*it).first, fromY = (*it).second;
  237.         vector < pair <int, int> > allPossibleMoves = AvailableMove(fromX, fromY);
  238.         for(vector < pair <int, int> >:: iterator i = allPossibleMoves.begin(); i != allPossibleMoves.end(); ++i) {
  239.             int toX = (*i).first, toY = (*i).second;
  240.             printf("Min\n");
  241.             isRemoved = takeAction(fromX, fromY, toX, toY, human);
  242.             localBest = maxValue();
  243.             undoAction(fromX, fromY, toX, toY, human, isRemoved);
  244.             best = min(best, localBest);
  245.         }
  246.     }
  247.     return best;
  248. }
  249.  
  250. void miniMax() {
  251.     int best = -infinity, localBest;
  252.     int a, b, x, y;
  253.     bool isRemoved;
  254.     // pick up available computer pawns currently in board
  255.     vector < pair <int, int> > availPawns = availablePawn(computer);
  256.     // for each pawn
  257.     for(vector < pair <int, int> >:: iterator it = availPawns.begin(); it != availPawns.end(); ++it) {
  258.         int fromX = (*it).first, fromY = (*it).second;
  259.         // available move for certain move
  260.         vector < pair <int, int> > allPossibleMoves = AvailableMove(fromX, fromY);
  261.         // trying each available move of certain pawn
  262.         for(vector < pair <int, int> >:: iterator i = allPossibleMoves.begin(); i != allPossibleMoves.end(); ++i) {
  263.             int toX = (*i).first, toY = (*i).second;
  264.             isRemoved = takeAction(fromX, fromY, toX, toY, computer);
  265.             localBest = minValue();
  266.             undoAction(fromX, fromY, toX, toY, computer, isRemoved);
  267.             if(localBest > best) {
  268.                 best = localBest;
  269.                 a = fromX, b = fromY, x = toX, y = toY;
  270.             }
  271.         }
  272.     }
  273.     takeAction(a, b, x, y, computer);
  274. }
  275.  
  276. int main(void) {
  277.     freopen("input.txt", "r", stdin);
  278.     freopen("output.txt", "w", stdout);
  279.     initializeGame();
  280. //    startGame();
  281.     int fromX, fromY, toX, toY;
  282.     while(true) {
  283.         // first, human's turn
  284.         printf("Human's turn: x y\n");
  285.         scanf("%d %d", &fromX, &fromY);
  286.         bool end = false;
  287.         while(!end) {
  288.             vector < pair<int, int> > moves = AvailableMove(fromX, fromY);
  289.             printPossibleMoves(moves);
  290.             printf("Choose your move: x y\n");
  291.             scanf("%d %d", &toX, &toY);
  292.             //stop giving input anymore
  293.             if(toX == -1 and toY == -1)
  294.                 break;
  295.             //check whether taken move is valid, otherwise ask for a valid one
  296.             while(find(moves.begin(), moves.end(), make_pair(toX, toY)) == moves.end()) {
  297.                 printf("Invalid Move!\nChoose your move: x y\n");
  298.                 scanf("%d %d", &toX, &toY);
  299.             }
  300.             board[toX][toY] = human;
  301.             board[fromX][fromY] = blank;
  302.             // one step ahead move
  303.             if( isAhead(fromX, fromY, toX, toY) ) {
  304.                 pair <int, int> point = terminate(fromX, fromY, toX, toY, human);
  305.                 if(point != dummy) {
  306.                     board[point.first][point.second] = blank;
  307.                 } else {
  308.                     end = true;
  309.                 }
  310.             } else {
  311.                 end = true;
  312.             }
  313.             printGameState();
  314.             fromX = toX, fromY = toY;
  315.         }
  316.         if(isHumanWin()) {
  317.             printf("Human win!\n");
  318.             break;
  319.         }
  320.         // computer's turn
  321.         printf("Computer's turn:\n");
  322.         miniMax();
  323.         printGameState();
  324.         if(isComputerWin()) {
  325.             printf("Computer win!\n");
  326.             break;
  327.         }
  328.     }
  329.     return 0;
  330. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement