A java PacMan game application for A.U.TH (data structures class)
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

366 lignes
11 KiB

  1. package gr.auth.ee.dsproject.pacman;
  2. import java.util.ArrayList;
  3. import gr.auth.ee.dsproject.node.Globals;
  4. import gr.auth.ee.dsproject.node.Tree;
  5. import gr.auth.ee.dsproject.node.Node89978445;
  6. /**
  7. * <p>
  8. * Title: DataStructures2011
  9. * </p>
  10. *
  11. * <p>
  12. * Description: Data Structures project: year 2011-2012
  13. * </p>
  14. *
  15. * <p>
  16. * Copyright: Copyright (c) 2011
  17. * </p>
  18. *
  19. * <p>
  20. * Company: A.U.Th.
  21. * </p>
  22. *
  23. * @author Michael T. Tsapanos
  24. * @version 1.0
  25. */
  26. public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
  27. {
  28. public String getName ()
  29. {
  30. return "Mine";
  31. }
  32. private int step = 1;
  33. private boolean amPrey;
  34. public Creature (boolean isPrey) {
  35. amPrey = isPrey;
  36. }
  37. /**
  38. *
  39. */
  40. public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition)
  41. {
  42. int [] bestPos = {-1, -1}; // Best position in maze to play
  43. Node89978445 bestNode; // The node with the best evaluation
  44. Node89978445 cur = new Node89978445 (Maze, currPosition); // The node with the current position
  45. //make the tree
  46. createSubTreePacman (cur.getDepth (), cur, Maze, currPosition);
  47. // min-max to find best node and consequently the best position
  48. bestNode = Tree.minmaxAB (cur, Globals.MINMAXTREE_MAX_DEPTH-1, Globals.EVAL_MIN - 1, Globals.EVAL_MAX + 1, true);
  49. bestPos = bestNode.getCurrentPacmanPos();
  50. // convert back to move encoding
  51. return Node89978445.moveConv (bestPos, currPosition);
  52. }
  53. /**
  54. *
  55. */
  56. void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition)
  57. {
  58. if (depth >= Globals.MINMAXTREE_MAX_DEPTH-1)
  59. /*<
  60. * As the depth starts from 0 and MINMAXTREE_MAX_DEPTH
  61. * is strictly even, with this comparison we accept that there
  62. * is no need for a max-depth layer of ghosts-evaluation based nodes.
  63. * As soon as we accept the depth-1 layers max evaluated node.
  64. */
  65. return;
  66. else {
  67. Node89978445 newNode;
  68. Room[][] newMaze;
  69. int[] nextPosition = {-1, -1};
  70. // scan possible valid moves
  71. for (int move=0 ; move<4 ; ++move) {
  72. if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.FALSE_POS) {
  73. // Make a copy of the maze in order to simulate next move and move Pacman
  74. newMaze = PacmanUtilities.copy (Maze);
  75. PacmanUtilities.movePacman (newMaze, parent.getCurrentPacmanPos(), nextPosition);
  76. // Create a node for the move in the new stated game maze
  77. newNode = new Node89978445 (newMaze, nextPosition);
  78. Tree.grow (newNode, parent); // add node to the min-max tree
  79. // call the recursive ranch creator
  80. createSubTreeGhosts (newNode.getDepth (), newNode, newMaze, newNode.getCurrentGhostPos());
  81. }
  82. }
  83. }
  84. }
  85. /**
  86. *
  87. */
  88. void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition)
  89. {
  90. if (depth >= Globals.MINMAXTREE_MAX_DEPTH-1)
  91. /*<
  92. * As the depth starts from 0 and MINMAXTREE_MAX_DEPTH
  93. * is strictly even, with this comparison we accept that there
  94. * is no need for a max-depth layer of ghosts-evaluation based nodes.
  95. * As soon as we accept the depth-1 layers max evaluated node.
  96. */
  97. return;
  98. else {
  99. Node89978445 newNode;
  100. Room[][] newMaze;
  101. ArrayList<int[][]> ghostMoves;
  102. // Get all possible ghost moves
  103. ghostMoves = PacmanUtilities.allGhostMoves(Maze, currGhostsPosition);
  104. // loop all ghost moves
  105. for (int i=0 ; i<ghostMoves.size() ; ++i) {
  106. // Make a copy of the maze in order to simulate next move and move ghosts
  107. newMaze = PacmanUtilities.copy (Maze);
  108. PacmanUtilities.moveGhosts(newMaze, currGhostsPosition, ghostMoves.get(i));
  109. // Create a node for the move in the new stated game maze
  110. newNode = new Node89978445 (newMaze, parent.getCurrentPacmanPos());
  111. Tree.grow (newNode, parent); // add node to the min-max tree
  112. //recursive call for the rest of the tree
  113. createSubTreePacman (newNode.getDepth (), newNode, newMaze, parent.getCurrentPacmanPos());
  114. }
  115. }
  116. }
  117. public int[] getPacPos (Room[][] Maze)
  118. {
  119. int[] pacmanPos = new int[2];
  120. for (int i = 0; i < PacmanUtilities.numberOfRows; i++) {
  121. for (int j = 0; j < PacmanUtilities.numberOfColumns; j++) {
  122. if (Maze[i][j].isPacman()) {
  123. pacmanPos[0] = i;
  124. pacmanPos[1] = j;
  125. return pacmanPos;
  126. }
  127. }
  128. }
  129. return pacmanPos;
  130. }
  131. public boolean[] comAvPos (Room[][] Maze, int[][] currentPos, int[] moves, int currentGhost)
  132. {
  133. boolean[] availablePositions = { true, true, true, true };
  134. int[][] newPos = new int[4][2];
  135. for (int i = 0; i < 4; i++) {
  136. if (Maze[currentPos[currentGhost][0]][currentPos[currentGhost][1]].walls[i] == 0) {
  137. availablePositions[i] = false;
  138. continue;
  139. }
  140. if (PacmanUtilities.flagColision(Maze, currentPos[currentGhost], i)) {
  141. availablePositions[i] = false;
  142. }
  143. else if (currentGhost == 0)
  144. continue;
  145. else {
  146. switch (i) {
  147. case Room.WEST:
  148. newPos[currentGhost][0] = currentPos[currentGhost][0];
  149. newPos[currentGhost][1] = currentPos[currentGhost][1] - 1;
  150. break;
  151. case Room.SOUTH:
  152. newPos[currentGhost][0] = currentPos[currentGhost][0] + 1;
  153. newPos[currentGhost][1] = currentPos[currentGhost][1];
  154. break;
  155. case Room.EAST:
  156. newPos[currentGhost][0] = currentPos[currentGhost][0];
  157. newPos[currentGhost][1] = currentPos[currentGhost][1] + 1;
  158. break;
  159. case Room.NORTH:
  160. newPos[currentGhost][0] = currentPos[currentGhost][0] - 1;
  161. newPos[currentGhost][1] = currentPos[currentGhost][1];
  162. }
  163. for (int j = (currentGhost - 1); j > -1; j--) {
  164. switch (moves[j]) {
  165. case Room.WEST:
  166. newPos[j][0] = currentPos[j][0];
  167. newPos[j][1] = currentPos[j][1] - 1;
  168. break;
  169. case Room.SOUTH:
  170. newPos[j][0] = currentPos[j][0] + 1;
  171. newPos[j][1] = currentPos[j][1];
  172. break;
  173. case Room.EAST:
  174. newPos[j][0] = currentPos[j][0];
  175. newPos[j][1] = currentPos[j][1] + 1;
  176. break;
  177. case Room.NORTH:
  178. newPos[j][0] = currentPos[j][0] - 1;
  179. newPos[j][1] = currentPos[j][1];
  180. // break;
  181. }
  182. if ((newPos[currentGhost][0] == newPos[j][0]) && (newPos[currentGhost][1] == newPos[j][1])) {
  183. availablePositions[i] = false;
  184. continue;
  185. }
  186. if ((newPos[currentGhost][0] == currentPos[j][0]) && (newPos[currentGhost][1] == currentPos[j][1]) && (newPos[j][0] == currentPos[currentGhost][0])
  187. && (newPos[j][1] == currentPos[currentGhost][1])) {
  188. availablePositions[i] = false;
  189. }
  190. }
  191. }
  192. }
  193. return availablePositions;
  194. }
  195. public int comBestPos (boolean[] availablePositions, int[] pacmanPosition, int[] currentPos)
  196. {
  197. int[] newVerticalDifference = new int[2];
  198. for (int i = 0; i < 2; i++)
  199. newVerticalDifference[i] = currentPos[i] - pacmanPosition[i];
  200. int[] distanceSquared = new int[4];
  201. for (int i = 0; i < 4; i++) {
  202. if (availablePositions[i] == true) {
  203. switch (i) {
  204. case Room.WEST:
  205. newVerticalDifference[1]--;
  206. break;
  207. case Room.SOUTH:
  208. newVerticalDifference[0]++;
  209. break;
  210. case Room.EAST:
  211. newVerticalDifference[1]++;
  212. break;
  213. case Room.NORTH:
  214. newVerticalDifference[0]--;
  215. break;
  216. }
  217. distanceSquared[i] = newVerticalDifference[0] * newVerticalDifference[0] + newVerticalDifference[1] * newVerticalDifference[1];
  218. } else
  219. distanceSquared[i] = PacmanUtilities.numberOfRows * PacmanUtilities.numberOfRows + PacmanUtilities.numberOfColumns * PacmanUtilities.numberOfColumns + 1;
  220. }
  221. int minDistance = distanceSquared[0];
  222. int minPosition = 0;
  223. for (int i = 1; i < 4; i++) {
  224. if (minDistance > distanceSquared[i]) {
  225. minDistance = distanceSquared[i];
  226. minPosition = i;
  227. }
  228. }
  229. return minPosition;
  230. }
  231. public int[] calculateNextGhostPosition (Room[][] Maze, int[][] currentPos)
  232. {
  233. int[] moves = new int[PacmanUtilities.numberOfGhosts];
  234. int[] pacmanPosition = new int[2];
  235. pacmanPosition = getPacPos(Maze);
  236. for (int i = 0; i < PacmanUtilities.numberOfGhosts; i++) {
  237. moves[i] = comBestPos(comAvPos(Maze, currentPos, moves, i), pacmanPosition, currentPos[i]);
  238. }
  239. return moves;
  240. }
  241. public boolean[] checkCollision (int[] moves, int[][] currentPos)
  242. {
  243. boolean[] collision = new boolean[PacmanUtilities.numberOfGhosts];
  244. int[][] newPos = new int[4][2];
  245. for (int i = 0; i < moves.length; i++) {
  246. if (moves[i] == 0) {
  247. if (currentPos[i][1] > 0) {
  248. newPos[i][0] = currentPos[i][0];
  249. newPos[i][1] = currentPos[i][1] - 1;
  250. } else {
  251. newPos[i][0] = currentPos[i][0];
  252. newPos[i][1] = PacmanUtilities.numberOfColumns - 1;
  253. }
  254. } else if (moves[i] == 1) {
  255. if (currentPos[i][0] < PacmanUtilities.numberOfRows - 1) {
  256. newPos[i][0] = currentPos[i][0] + 1;
  257. newPos[i][1] = currentPos[i][1];
  258. } else {
  259. newPos[i][0] = 0;
  260. newPos[i][1] = currentPos[i][1];
  261. }
  262. } else if (moves[i] == 2) {
  263. if (currentPos[i][1] < PacmanUtilities.numberOfColumns - 1) {
  264. newPos[i][0] = currentPos[i][0];
  265. newPos[i][1] = currentPos[i][1] + 1;
  266. } else {
  267. newPos[i][0] = currentPos[i][0];
  268. newPos[i][1] = 0;
  269. }
  270. } else {
  271. if (currentPos[i][0] > 0) {
  272. newPos[i][0] = currentPos[i][0] - 1;
  273. newPos[i][1] = currentPos[i][1];
  274. } else {
  275. newPos[i][0] = PacmanUtilities.numberOfRows - 1;
  276. newPos[i][1] = currentPos[i][1];
  277. }
  278. }
  279. collision[i] = false;
  280. }
  281. for (int k = 0; k < moves.length; k++) {
  282. }
  283. for (int i = 0; i < moves.length; i++) {
  284. for (int j = i + 1; j < moves.length; j++) {
  285. if (newPos[i][0] == newPos[j][0] && newPos[i][1] == newPos[j][1]) {
  286. collision[j] = true;
  287. }
  288. if (newPos[i][0] == currentPos[j][0] && newPos[i][1] == currentPos[j][1] && newPos[j][0] == currentPos[i][0] && newPos[j][1] == currentPos[i][1]) {
  289. collision[j] = true;
  290. }
  291. }
  292. }
  293. return collision;
  294. }
  295. }