Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.19 KB | None | 0 0
  1. //Copyright © 2017 Manoj M J
  2. //All Rights Reserved
  3.  
  4. // About APPLE NIM
  5. // A small number of apples are placed on a basket.
  6. // Players can remove 1, 2, 3 or 4 apples in turns.
  7. // Whoever picks the last apple loses the game.
  8. //
  9. // This program demonstrates how minimax algorithm can be used for finding best move in this game.
  10. // Note that finding best move in this game is attainable with a better arithmetic method.
  11. // So don't use minimax algorithm for this game in a production code.
  12.  
  13. #include <iostream>
  14. using namespace std;
  15. //#define APPLE_NIM_DEBUG
  16. #define APPLE_NIM_INFINITY 32000
  17. #define BESTSCORE 1000
  18. enum { NONE = -1, COMPUTER = 0, HUMAN = 1 };
  19.  
  20. class AppleNim
  21. {
  22. private:
  23. int m_numTotalApples;
  24. int m_turn;
  25. int m_useMiniMaxAI;
  26. #ifdef APPLE_NIM_DEBUG
  27. int m_maxDepth;
  28. int m_nodesSearched;
  29. #endif
  30. public:
  31. AppleNim(void);
  32. void Init(int numApples, int turn, bool useMiniMaxAI = false);
  33. void GameLoop();
  34. private:
  35. int FindBestMoveWithModuloOperator(int numTotalApples);//best method, use this function in production code
  36. int FindBestMoveWithSearchTree(int numTotalApples);//just for minimax algorithm demonstration, don't use this function in production code
  37. int MiniMax(int numTotalApples, bool maximizingPlayer, int depth);
  38. };
  39.  
  40. AppleNim::AppleNim(void)
  41. {
  42. m_numTotalApples = 21;
  43. m_turn = HUMAN;
  44. m_useMiniMaxAI = false;
  45. }
  46.  
  47. void AppleNim::Init(int numApples, int turn, bool useMiniMaxAI)
  48. {
  49. m_numTotalApples = numApples;
  50. m_turn = turn;
  51. m_useMiniMaxAI = useMiniMaxAI;
  52. }
  53.  
  54. void AppleNim::GameLoop()
  55. {
  56. int pick;
  57. bool invalidInput = false;
  58. cout << "***ABOUT APPLE NIM***" << endl;
  59. cout << "A small number of apples are placed on a basket." << endl;
  60. cout << "Players can remove 1, 2, 3 or 4 apples in turns." << endl;
  61. cout << "Whoever picks the last apple loses the game." << endl;
  62. cout << "***START***" << endl;
  63. while (m_numTotalApples > 0)
  64. {
  65. if (m_turn == HUMAN) {
  66. cout << "Number of apples left: [[ " << m_numTotalApples << " ]]" << endl;
  67. cout << "***YOUR TURN***" << endl;
  68. do {
  69. cout << "Enter your pick: ";
  70. cin >> pick;
  71. if (invalidInput = (pick < 0 || pick > 4 || (m_numTotalApples - pick) < 0)){
  72. cout << "Invalid input" << endl;
  73. }
  74. } while (invalidInput);
  75. m_numTotalApples -= pick;
  76. m_turn = (m_turn + 1) % 2;
  77. }
  78. else if (m_turn == COMPUTER) {
  79. cout << "Number of apples left: [ " << m_numTotalApples << " ]" << endl;
  80. cout << "***COMPUTER'S TURN***" << endl;
  81. if (!m_useMiniMaxAI)
  82. pick = FindBestMoveWithModuloOperator(m_numTotalApples);
  83. else
  84. pick = FindBestMoveWithSearchTree(m_numTotalApples);
  85. m_numTotalApples -= pick;
  86. m_turn = (m_turn + 1) % 2;
  87. cout << "Computer picks ( ";
  88. if (pick != 1)
  89. cout << pick << " ) apples." << endl;
  90. else
  91. cout << pick << " ) apple." << endl;
  92. }
  93. if (m_numTotalApples == 0) {
  94. cout << "Empty basket! " << endl;
  95. if (m_turn == COMPUTER)
  96. cout << "You lose." << endl;
  97. else
  98. cout << "You win." << endl;
  99. }
  100. }
  101.  
  102. cout << "***Game Over***" << endl;
  103. }
  104.  
  105. int AppleNim::FindBestMoveWithModuloOperator(int numTotalApples)
  106. {
  107. for (int pick = 4; pick > 0; --pick)
  108. if ((numTotalApples - pick) % 5 == 1)
  109. return pick;
  110. return 1;
  111. }
  112.  
  113.  
  114. int AppleNim::FindBestMoveWithSearchTree(int numTotalApples)
  115. {
  116. #ifdef APPLE_NIM_DEBUG
  117. m_maxDepth = 0;
  118. m_nodesSearched = 0;
  119. #endif
  120. int best = -APPLE_NIM_INFINITY;
  121. int bestPick = 0;
  122. for (int pick = 4; pick > 0; --pick) {
  123. numTotalApples = numTotalApples - pick;
  124. if (numTotalApples >= 0) {
  125. #ifdef APPLE_NIM_DEBUG
  126. ++m_nodesSearched;
  127. #endif
  128. int value = MiniMax(numTotalApples, false, 1);
  129. if (value > best) {
  130. best = value;
  131. bestPick = pick;
  132. }
  133. }
  134. numTotalApples = numTotalApples + pick;
  135. }
  136. #ifdef APPLE_NIM_DEBUG
  137. cout << endl << "Searched " << m_nodesSearched << " nodes at a maximum depth of " << m_maxDepth << endl;
  138. #endif
  139. return bestPick;
  140. }
  141.  
  142. int AppleNim::MiniMax(int totalApples, bool maximizingPlayer, int depth)
  143. {
  144. #ifdef APPLE_NIM_DEBUG
  145. if (depth > m_maxDepth)
  146. m_maxDepth = depth;
  147. #endif
  148. if (totalApples == 0) {
  149. if (maximizingPlayer)
  150. return (BESTSCORE-depth); // computer is presented with empty basket
  151. else
  152. return -(BESTSCORE-depth);//human is presented with empty basket
  153. }
  154. else if (totalApples == 1) {
  155. if (maximizingPlayer)
  156. return -(BESTSCORE-depth);//computer is presented with one apple
  157. else
  158. return BESTSCORE-depth;//human is presented with one apple
  159. }
  160. else if (maximizingPlayer) {
  161. int best = -APPLE_NIM_INFINITY;
  162. for (int pick = 4; pick > 0; --pick) {
  163. totalApples = totalApples - pick;
  164. if (totalApples >= 0) {
  165. #ifdef APPLE_NIM_DEBUG
  166. ++m_nodesSearched;
  167. #endif
  168. int value = MiniMax(totalApples, false, depth + 1);
  169. if (value > best) {
  170. best = value;
  171. }
  172. }
  173. totalApples = totalApples + pick;
  174. }
  175. return best;
  176. }
  177. else
  178. {
  179. int best = APPLE_NIM_INFINITY;
  180. for (int pick = 4; pick > 0; --pick) {
  181. totalApples = totalApples - pick;
  182. if (totalApples >= 0) {
  183. #ifdef APPLE_NIM_DEBUG
  184. ++m_nodesSearched;
  185. #endif
  186. int value = MiniMax(totalApples, true, depth + 1);
  187. if (value < best) {
  188. best = value;
  189. }
  190. }
  191. totalApples = totalApples + pick;
  192. }
  193. return best;
  194. }
  195. }
  196.  
  197. int main()
  198. {
  199. AppleNim n;
  200. n.Init(26, HUMAN, true);
  201. //n.Init(26, HUMAN, false);
  202. n.GameLoop();
  203. return 0;
  204. }
  205.  
  206. //Losing baskets 1, 6, 11, 16, 21, 26, 31
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement