Advertisement
Guest User

tictacminimax

a guest
Jan 13th, 2014
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.30 KB | None | 0 0
  1. /***************************************************
  2. *
  3. * board.cpp
  4. * Board Class
  5. *
  6. *
  7. ***************************************************/
  8.  
  9. #include "board.h"
  10. #include <iostream>
  11. #include <vector>
  12. #include <climits>
  13.  
  14. using namespace std;
  15.  
  16.  
  17. board::board()
  18. {
  19.     for (int i = 0; i < 3; ++i)
  20.         for (int j = 0; j < 3; ++j)
  21.             gameBoard[i][j] = '*';
  22.  
  23.     computerTurn = false; //humans go first
  24.     firstMoveMade = false;
  25. }
  26.  
  27.  
  28. board::board(const board & other)
  29. {
  30.     for (int i = 0; i < 3; ++i)
  31.         for (int j = 0; j < 3; ++j)
  32.             gameBoard[i][j] = other.gameBoard[i][j];
  33.  
  34.     computerTurn = other.computerTurn;
  35.     firstMoveMade = other.firstMoveMade;   
  36. }
  37.  
  38. board & board::operator=(const board & rhs)
  39. {
  40.     if (this == &rhs) return *this;
  41.     for(int i = 0; i < 10; ++i)
  42.         for (int j = 0; j < 10; ++j)
  43.             gameBoard[i][j] = rhs.gameBoard[i][j];
  44.    
  45.     computerTurn = rhs.computerTurn;
  46.     firstMoveMade = rhs.firstMoveMade; 
  47.  
  48.     return *this;
  49. }
  50.  
  51. char board::getPosition(int x, int y)
  52. {
  53.     if (x < 3 && x >= 0 && y < 3 && y >= 0) // boundary check
  54.         return gameBoard[x][y];
  55.     else return ' ';
  56. }
  57.  
  58. void board::setPosition(int x, int y)
  59. {
  60.     if (x < 3 && x >= 0 && y < 3 && y >= 0) // boundary check
  61.     {  
  62.         if (!computerTurn)
  63.             gameBoard[x][y] = 'X';
  64.         else gameBoard[x][y] = 'O';
  65.     }
  66.    
  67.     if (!firstMoveMade) firstMoveMade = true; // first move has been made
  68.     computerTurn = !computerTurn; // someone just made a move  
  69. }
  70.  
  71. void board::makeComputerMove()
  72. {
  73.     drawboard();
  74.     getBestMove();
  75.     drawboard();   
  76. }
  77.  
  78. void board::getBestMove()
  79. {
  80.     board returnBoard;
  81.     miniMax(INT_MIN + 1, INT_MAX -1, returnBoard);
  82.    
  83.     *this = returnBoard;
  84. }
  85.  
  86. int board::miniMax(int alpha, int beta, board childWithMaximum)
  87. {  
  88.     if (checkDone())
  89.         return boardScore();
  90.  
  91.     vector<board> children = getChildren();
  92.     for (int i = 0; i < 9; ++i)
  93.     {
  94.         if(children.empty()) break;
  95.  
  96.         board curr = children.back();
  97.         if (curr.firstMoveMade) // not an empty board
  98.         {
  99.             board dummyBoard;
  100.             int score = curr.miniMax(alpha, beta, dummyBoard);
  101.            
  102.             if (computerTurn && (beta > score))
  103.             {
  104.                 beta = score;
  105.                 childWithMaximum = *this;  
  106.                 if (alpha >= beta) break;
  107.             }
  108.  
  109.             else if (alpha < score)
  110.             {
  111.                 alpha = score;
  112.                 childWithMaximum = *this;
  113.                 if (alpha >= beta) break;
  114.             }
  115.         }
  116.     }
  117.     return computerTurn? alpha : beta;
  118. }
  119.  
  120. vector<board> board::getChildren()
  121. {
  122.     vector<board> children;
  123.    
  124.     for (int i = 0; i < 3; ++i)
  125.     {   for (int j = 0; j < 3; ++j)
  126.         {
  127.             if (getPosition(i, j) == '*') //move not made here
  128.             {
  129.                 board moveMade(*this);
  130.                 moveMade.setPosition(i, j);            
  131.                 children.push_back(moveMade);
  132.             }
  133.         }
  134.     }
  135.  
  136.     return children;
  137. }
  138.  
  139. int board::boardScore()
  140. {
  141.     return rowScore(gameBoard[0][0], gameBoard[0][1], gameBoard[0][2]) + rowScore(gameBoard[1][0], gameBoard[1][1], gameBoard[1][2])
  142.     + rowScore(gameBoard[2][0], gameBoard[2][1], gameBoard[2][2]) + rowScore(gameBoard[0][0], gameBoard[1][0], gameBoard[2][0])
  143.     + rowScore(gameBoard[0][1], gameBoard[1][1], gameBoard[2][1])+ rowScore(gameBoard[0][2], gameBoard[1][2], gameBoard[2][2])
  144.     + rowScore(gameBoard[0][0], gameBoard[1][1], gameBoard[2][2])+ rowScore(gameBoard[0][2], gameBoard[1][1], gameBoard[2][0]);
  145. }
  146.  
  147. int board::rowScore(char one, char two, char three)
  148. {
  149.     char row[3] = {one, two, three};
  150.     int numX = 0;
  151.     int numO = 0;
  152.    
  153.     for (int i = 0; i < 3; ++i)
  154.     {  
  155.         if (row[i] == 'X') numX++;
  156.         if (row[i] == 'O') numO++;
  157.     }
  158.  
  159.     if (numX == numO) return 0;
  160.     else if (numO == 3) return 100; // three in a row
  161.     else if (numO == 2) return 10;  // two in a row
  162.     else if (numO == 1) return 1;  // one in a row
  163.     else if (numX == 3) return -100;
  164.     else if (numX == 2) return -10;
  165.     else if (numX == 1) return -1;
  166.     else return 0; 
  167. }
  168.  
  169. void board::makeHumanMove()
  170. {
  171.     int x;
  172.     int y;
  173.  
  174.     while(1)
  175.     {
  176.         cout << "Please enter the x - coordinate of the square you wish to mark (0 - 2)" << endl;
  177.         cin >> x;
  178.         cout << "Please enter the y - coordinate of the square you wish to mark (0 - 2)" << endl;
  179.         cin >> y;
  180.        
  181.         if (x < 3 && x >= 0 && y < 3 && y >= 0 && gameBoard[x][y] != 'X' && gameBoard[x][y] != 'O')
  182.         {
  183.             setPosition(x, y);
  184.             drawboard();
  185.             break;
  186.         }
  187.  
  188.         else
  189.         {
  190.             drawboard();
  191.             cout << "Please enter valid coordinates." << endl;
  192.             continue;
  193.         }
  194.        
  195.     }
  196.     return;
  197. }
  198.  
  199.  
  200. int board::checkWin()
  201. {
  202.     if (checkDone() && computerTurn)
  203.     {
  204.         return 1;
  205.         if (!computerTurn) return -1;
  206.         return 0;
  207.     }
  208.  
  209.     return -100; // testing only
  210. }
  211.  
  212.  
  213.  
  214. bool board::checkDone()
  215. {  
  216.     if (!firstMoveMade) return false;
  217.  
  218.     // check for win
  219.     else if  (areEqual(gameBoard[0][0], gameBoard[0][1], gameBoard[0][2])
  220.         || areEqual(gameBoard[1][0], gameBoard[1][1], gameBoard[1][2])
  221.         || areEqual(gameBoard[2][0], gameBoard[2][1], gameBoard[2][2])  
  222.         || areEqual(gameBoard[0][0], gameBoard[1][0], gameBoard[2][0])     
  223.         || areEqual(gameBoard[0][1], gameBoard[1][1], gameBoard[2][1])
  224.         || areEqual(gameBoard[0][2], gameBoard[1][2], gameBoard[2][2])
  225.         || areEqual(gameBoard[0][0], gameBoard[1][1], gameBoard[2][2])
  226.         || areEqual(gameBoard[0][2], gameBoard[1][1], gameBoard[2][0]))
  227.         return true;
  228.  
  229.     for (int i = 0; i < 3; ++i)
  230.         for (int j = 0; j < 3; ++j)
  231.             if (gameBoard[i][j] == '*') return false; // no win statements are true and there is an empty
  232.                                      // square, so game must be in progress
  233.  
  234.     return true; // must be a tie    
  235. }
  236.  
  237.  
  238. bool board::areEqual(char one, char two, char three)
  239. {
  240.     return ((two == one && three == one) && one != '*');
  241. }
  242.  
  243. void board::drawboard()
  244. {
  245.    
  246.     cout << "\033[2J\033[1;1H" << endl; // clears the screen       
  247.    
  248.     cout << "\n\n    TIC-TAC-TOE    ";
  249.     cout << "\n\n     You are X      \n\n";
  250.     if (!computerTurn) cout << "\n\n     YOUR TURN      \n\n";  
  251.     else cout << "\n\n     COMPUTER TURN      \n\n";
  252.     cout << "\n";
  253.  
  254.     cout << "     0     1    2  " << endl; 
  255.    
  256.     cout << "   ________________" << endl;
  257.    
  258.     cout << "  |     |     |    |" << endl;
  259.    
  260.     cout << "0 |  " << gameBoard[0][0] << "  |  " << gameBoard[0][1] << "  |  " << gameBoard[0][2] << " |" << endl;
  261.  
  262.     cout << "  |-----|-----|----|" << endl;
  263.  
  264.     cout << "1 |  " << gameBoard[1][0] << "  |  " << gameBoard[1][1] << "  |  " << gameBoard[1][2] << " |" << endl;
  265.      
  266.     cout << "  |-----|-----|----|" << endl;
  267.  
  268.     cout << "2 |  " << gameBoard[2][0] << "  |  " << gameBoard[2][1] << "  |  " << gameBoard[2][2] << " |" << endl;
  269.  
  270.     cout << "  |_____|_____|____|\n\n";
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement