/RussianCheckers/RussianCheckers/AlphaBeta - Copy (6).cs

https://bitbucket.org/KuroKaze/russian-checkers · C# · 220 lines · 161 code · 34 blank · 25 comment · 47 complexity · 12e5db00cd5543148c3c9f238d20473a MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Graphics;
  6. using Microsoft.Xna.Framework.Input;
  7. namespace RussianCheckers
  8. {
  9. class AlphaBeta
  10. {
  11. long maxDepth = 0;
  12. long node = 1;
  13. long maxPrun = 0;
  14. long minPrun = 0;
  15. DateTime start;
  16. public AlphaBeta()
  17. {
  18. }
  19. public AlphaBeta(Environment env)
  20. {
  21. start = DateTime.Now;
  22. Tuple<int, int, int> value;
  23. if (!env.gameOver())
  24. {
  25. value = max(env, -100000, 100000, 1);
  26. env.doJump(value.Item2, value.Item3);
  27. env.possibleMoves[value.Item2].piece.newPosition(env.possibleMoves[value.Item2].markers[value.Item3].position);
  28. env.reset();
  29. Console.WriteLine("maxDepth = " + maxDepth + "\n" +
  30. "node = " + node + "\n" +
  31. "maxPruned = " + maxPrun + "\n" +
  32. "minPruned = " + minPrun + "\n" +
  33. "Value = " + value.Item1 + "\n" );
  34. }
  35. else
  36. env.winner = true;
  37. }
  38. Tuple<int, int, int> max(Environment env, int alpha, int beta, long depth)
  39. {
  40. if (depth > maxDepth)
  41. maxDepth = depth;
  42. node++;
  43. if (node % 100000 == 0)
  44. Console.WriteLine("depth = " + depth + "\n" +
  45. "node = " + node + "\n" +
  46. "maxPruned = " + maxPrun + "\n" +
  47. "minPruned = " + minPrun + "\n" +
  48. "Alpha beta= " + alpha + ", " + beta + "\n");
  49. List<Vector2> player = new List<Vector2>();
  50. List<Vector2> ai = new List<Vector2>();
  51. for (int i = 0; i < env.player.Count; i++)
  52. {
  53. player.Add(new Vector2(env.player[i].position.X, env.player[i].position.Y));
  54. ai.Add(new Vector2(env.ai[i].position.X, env.ai[i].position.Y));
  55. }
  56. bool playerTurn = env.playerTurn;
  57. if (env.playerTurn)
  58. Console.WriteLine("BADDDDDDD");
  59. long elapsedTicks = DateTime.Now.Ticks - start.Ticks;
  60. TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
  61. if (env.gameOver() || depth == 17 /*18 + Math.Pow(2.0, (double)env.turn)*/)
  62. return new Tuple<int, int, int>(env.utility(), 0, 0);
  63. //else if (elapsedSpan.TotalMinutes > 1)
  64. // return new Tuple<int, int, int>(-1000, 0, 0);
  65. Tuple<int, int, int> value = new Tuple<int, int, int>(-100000, 0, 0);
  66. for (int i = 0; i < env.possibleMoves.Count; i++)
  67. {
  68. for (int j = 0; j < env.possibleMoves[i].markers.Count && env.possibleMoves[i].markers[j].position != Vector2.Zero; j++)
  69. {
  70. if (env.possibleMoves[i].jumpSet[j].Count == 4)
  71. return new Tuple<int, int, int>(100000, i, j);
  72. else if (env.possibleMoves.Count == 1 && depth == 1)
  73. return new Tuple<int, int, int>(0, i, j);
  74. //else if (env.possibleMoves.Count == 1)
  75. // value = new Tuple<int, int, int>(env.utility(), i, 0);
  76. env.doJump(i, j);
  77. env.possibleMoves[i].piece.newPosition(env.possibleMoves[i].markers[j].position);
  78. env.reset();
  79. env.generateCanJump();
  80. env.generateJump();
  81. Tuple<int, int, int> minimum = min(env, alpha, beta, depth + 1);
  82. int score = Math.Max(value.Item1, minimum.Item1);
  83. if(value.Item1 != score)
  84. value = new Tuple<int, int, int>(score, i, j);
  85. for (int k = 0; k < player.Count; k++)
  86. {
  87. env.player[k].newPosition(player[k]);
  88. env.ai[k].newPosition(ai[k]);
  89. }
  90. env.reset();
  91. env.generateCanJump();
  92. env.generateJump();
  93. if (value.Item1 >= beta)
  94. {
  95. maxPrun++;
  96. return value;
  97. }
  98. alpha = Math.Max(alpha, value.Item1);
  99. }
  100. }
  101. return value;
  102. }
  103. Tuple<int, int, int> min(Environment env, int alpha, int beta, long depth)
  104. {
  105. if (depth > maxDepth)
  106. maxDepth = depth;
  107. node++;
  108. if (node % 100000 == 0)
  109. Console.WriteLine("depth = " + depth + "\n" +
  110. "node = " + node + "\n" +
  111. "maxPruned = " + maxPrun + "\n" +
  112. "minPruned = " + minPrun + "\n" +
  113. "Alpha beta= " + alpha + ", " + beta + "\n");
  114. List<Vector2> player = new List<Vector2>();
  115. List<Vector2> ai = new List<Vector2>();
  116. for (int i = 0; i < env.player.Count; i++)
  117. {
  118. player.Add(new Vector2(env.player[i].position.X, env.player[i].position.Y));
  119. ai.Add(new Vector2(env.ai[i].position.X, env.ai[i].position.Y));
  120. }
  121. bool playerTurn = env.playerTurn;
  122. if (!env.playerTurn)
  123. Console.WriteLine("BADDDDDDD");
  124. long elapsedTicks = DateTime.Now.Ticks - start.Ticks;
  125. TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
  126. if (env.gameOver() || depth == 17 /*18 + Math.Pow(2.0, (double)env.turn)*/)
  127. return new Tuple<int, int, int>(env.utility(), 0, 0);
  128. //else if (elapsedSpan.TotalMinutes > 1)
  129. // return new Tuple<int, int, int>(1000, 0, 0);
  130. Tuple<int, int, int> value = new Tuple<int, int, int>(100000, 0, 0);
  131. for (int i = 0; i < env.possibleMoves.Count; i++)
  132. {
  133. for (int j = 0; j < env.possibleMoves[i].markers.Count && env.possibleMoves[i].markers[j].position != Vector2.Zero; j++)
  134. {
  135. if (env.possibleMoves[i].jumpSet[j].Count == 4)
  136. return new Tuple<int, int, int>(-100000, i, j);
  137. else if (env.possibleMoves.Count == 1 && depth == 1)
  138. return new Tuple<int, int, int>(0, i, j);
  139. //else if (env.possibleMoves.Count == 1)
  140. // value = new Tuple<int, int, int>(env.utility(), i, 0);
  141. env.doJump(i, j);
  142. env.possibleMoves[i].piece.newPosition(env.possibleMoves[i].markers[j].position);
  143. env.reset();
  144. env.generateCanJump();
  145. env.generateJump();
  146. Tuple<int, int, int> maximum = max(env, alpha, beta, depth + 1);
  147. int score = Math.Min(value.Item1, maximum.Item1);
  148. if(value.Item1 != score)
  149. value = new Tuple<int, int, int>(score, i, j);
  150. for (int k = 0; k < player.Count; k++)
  151. {
  152. env.player[k].newPosition(player[k]);
  153. env.ai[k].newPosition(ai[k]);
  154. }
  155. env.reset();
  156. env.generateCanJump();
  157. env.generateJump();
  158. if (value.Item1 <= alpha)
  159. {
  160. minPrun++;
  161. return value;
  162. }
  163. beta = Math.Min(beta, value.Item1);
  164. }
  165. }
  166. return value;
  167. }
  168. // void alphabeta(node, depth, α, β, Player)
  169. // if depth = 0 or node is a terminal node
  170. // return the heuristic value of node
  171. // if Player = MaxPlayer
  172. // for each child of node
  173. // α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))
  174. // if β ≤ α
  175. // break (* Beta cut-off *)
  176. // return α
  177. // else
  178. // for each child of node
  179. // β := min(β, alphabeta(child, depth-1, α, β, not(Player) ))
  180. // if β ≤ α
  181. // break (* Alpha cut-off *)
  182. // return β
  183. //(* Initial call *)
  184. //alphabeta(origin, depth, -infinity, +infinity, MaxPlayer)
  185. }
  186. }