Guest User

Untitled

a guest
Jan 19th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <algorithm>
  4. #include <limits>
  5.  
  6. class Game
  7. {
  8. enum class Player
  9. {
  10. none = '-',
  11. human = 'X',
  12. computer = 'O'
  13. };
  14.  
  15. struct Move
  16. {
  17. unsigned x = 0;
  18. unsigned y = 0;
  19. };
  20.  
  21. static const unsigned DIM = 4;
  22.  
  23. Player board[DIM][DIM];
  24. unsigned remained;
  25.  
  26. public:
  27. Game() : remained(DIM * DIM)
  28. {
  29. for (unsigned i = 0; i < DIM; i++)
  30. {
  31. for (unsigned j = 0; j < DIM; j++)
  32. {
  33. board[i][j] = Player::none;
  34. }
  35. }
  36. }
  37.  
  38. void play()
  39. {
  40. unsigned turn = 0;
  41. bool exit = false;
  42.  
  43. printBoard();
  44. std::cout << "Enter your move in coordinate form[row, col]. ex: 02n";
  45.  
  46. do
  47. {
  48. // human move
  49. if (turn == 0)
  50. {
  51. getHumanMove();
  52.  
  53. if (checkWin(Player::human))
  54. {
  55. std::cout << "Human Winsn";
  56. exit = true;
  57. }
  58. }
  59. else
  60. {
  61. std::cout << "nComputer Move: ";
  62.  
  63. Move aimove = minimax();
  64.  
  65. std::cout << aimove.x << aimove.y << "n";
  66.  
  67. board[aimove.x][aimove.y] = Player::computer;
  68. remained--;
  69.  
  70. if (checkWin(Player::computer))
  71. {
  72. std::cout << "Computer Winsn";
  73. exit = true;
  74. }
  75. }
  76.  
  77. if (isTie())
  78. {
  79. std::cout << "n*** Tie ***n";
  80. exit = true;
  81. }
  82.  
  83. turn ^= 1;
  84. printBoard();
  85.  
  86. } while (!exit);
  87. }
  88.  
  89. private:
  90. void printBoard()
  91. {
  92. for (unsigned i = 0; i < DIM; i++)
  93. {
  94. std::cout << "n|";
  95. for (unsigned j = 0; j < DIM; j++)
  96. {
  97. std::cout << std::setw(3) << static_cast<char>(board[i][j]) << std::setw(3) << " |";
  98. }
  99. }
  100. std::cout << "nn";
  101. }
  102.  
  103. bool isTie()
  104. {
  105. return remained == 0;
  106. }
  107.  
  108. bool checkWin(Player player)
  109. {
  110. // check for row or column wins
  111. for (unsigned i = 0; i < DIM; ++i)
  112. {
  113. bool rowwin = true;
  114. bool colwin = true;
  115. for (unsigned j = 0; j < DIM; ++j)
  116. {
  117. rowwin &= board[i][j] == player;
  118. colwin &= board[j][i] == player;
  119. }
  120. if (colwin || rowwin)
  121. return true;
  122. }
  123.  
  124. // check for diagonal wins
  125. bool diagwin = true;
  126. for (unsigned i = 0; i < DIM; ++i)
  127. diagwin &= board[i][i] == player;
  128.  
  129. if (diagwin)
  130. return true;
  131.  
  132. diagwin = true;
  133. for (unsigned i = 0; i < DIM; ++i)
  134. diagwin &= board[DIM - i - 1][i] == player;
  135.  
  136. return diagwin;
  137. }
  138.  
  139.  
  140. Move minimax()
  141. {
  142. int score = std::numeric_limits<int>::max();
  143. Move move;
  144. int level = 0;
  145.  
  146. for (unsigned i = 0; i < DIM; i++)
  147. {
  148. for (unsigned j = 0; j < DIM; j++)
  149. {
  150. if (board[i][j] == Player::none)
  151. {
  152. board[i][j] = Player::computer;
  153. remained--;
  154.  
  155. int temp = maxSearch(level, std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
  156.  
  157. if (temp < score)
  158. {
  159. score = temp;
  160. move.x = i;
  161. move.y = j;
  162. }
  163.  
  164. board[i][j] = Player::none;
  165. remained++;
  166. }
  167. }
  168. }
  169.  
  170. return move;
  171. }
  172.  
  173. int maxSearch(int level, int alpha, int beta)
  174. {
  175. if (checkWin(Player::human)) { return 10; }
  176. else if (checkWin(Player::computer)) { return -10; }
  177. else if (isTie()) { return 0; }
  178.  
  179. int score = std::numeric_limits<int>::min();
  180.  
  181. for (unsigned i = 0; i < DIM; i++)
  182. {
  183. for (unsigned j = 0; j < DIM; j++)
  184. {
  185. if (board[i][j] == Player::none)
  186. {
  187. board[i][j] = Player::human;
  188. remained--;
  189.  
  190. score = std::max(score, minSearch(level + 1, alpha, beta) - level);
  191. alpha = std::max(alpha, score);
  192.  
  193. board[i][j] = Player::none;
  194. remained++;
  195.  
  196. if (beta <= alpha) return alpha;
  197. }
  198. }
  199. }
  200.  
  201. return score;
  202. }
  203.  
  204. int minSearch(int level, int alpha, int beta)
  205. {
  206. if (checkWin(Player::human)) { return 10; }
  207. else if (checkWin(Player::computer)) { return -10; }
  208. else if (isTie()) { return 0; }
  209.  
  210. int score = std::numeric_limits<int>::max();
  211.  
  212. for (unsigned i = 0; i < DIM; i++)
  213. {
  214. for (unsigned j = 0; j < DIM; j++)
  215. {
  216. if (board[i][j] == Player::none)
  217. {
  218. board[i][j] = Player::computer;
  219. remained--;
  220.  
  221. score = std::min(score, maxSearch(level + 1, alpha, beta) + level);
  222. beta = std::min(beta, score);
  223.  
  224. board[i][j] = Player::none;
  225. remained++;
  226.  
  227. if (beta <= alpha) return beta;
  228. }
  229. }
  230. }
  231.  
  232. return score;
  233. }
  234.  
  235. void getHumanMove()
  236. {
  237. bool fail = true;
  238. unsigned x = -1, y = -1;
  239.  
  240. do
  241. {
  242. std::cout << "Your Move: ";
  243.  
  244. char c;
  245. std::cin >> c;
  246. x = c - '0';
  247. std::cin >> c;
  248. y = c - '0';
  249.  
  250. fail = board[x][y] != Player::none;
  251.  
  252. std::cin.clear();
  253. std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
  254.  
  255. } while (fail);
  256.  
  257. board[x][y] = Player::human;
  258. remained--;
  259. }
  260. };
  261.  
  262. int main()
  263. {
  264. Game tictactoe;
  265. tictactoe.play();
  266. std::cin.ignore();
  267. }
Add Comment
Please, Sign In to add comment