A java PacMan game application for A.U.TH (data structures class)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
10 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.MinMaxTree;
  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. {
  36. amPrey = isPrey;
  37. }
  38. /**
  39. * @brief
  40. * Create node for each one of the possible moves (0, 1, 2, 3) and
  41. * evaluate these moves.
  42. */
  43. public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition)
  44. {
  45. Node89978445 cur = new Node89978445 (Maze, currPosition);
  46. MinMaxTree mmTree = new MinMaxTree (cur); /*<
  47. * Plant a tree with dummy root
  48. * Null parent and no evaluation
  49. */
  50. createSubTreePacman (0, cur, Maze, currPosition); //make the tree
  51. // min-max
  52. return 0;
  53. }
  54. void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition)
  55. {
  56. if (++depth > Globals.MINMAXTREE_MAX_DEPTH)
  57. return;
  58. else {
  59. Node89978445 newNode;
  60. Room[][] newMaze;
  61. int[] nextPosition = {-1, -1};
  62. // scan possible valid moves
  63. for (int move=0 ; move<4 ; ++move) {
  64. if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.FALSE_POS) {
  65. // Make a copy of the maze in order to simulate next move and move Pacman
  66. newMaze = PacmanUtilities.copy (Maze);
  67. PacmanUtilities.movePacman (newMaze, parent.getCurentPacmanPos(), nextPosition);
  68. // Create a node for the move in the new stated game maze
  69. newNode = new Node89978445 (newMaze, nextPosition);
  70. newNode.getEvaluation();
  71. MinMaxTree.insert (newNode, parent); // add node to the min-max tree
  72. // call the recursive ranch creator
  73. createSubTreeGhosts (depth, newNode, newMaze, newNode.getCurrentGhostPos());
  74. }
  75. }
  76. }
  77. }
  78. void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition)
  79. {
  80. if (++depth > Globals.MINMAXTREE_MAX_DEPTH)
  81. return;
  82. else {
  83. Node89978445 newNode;
  84. Room[][] newMaze;
  85. ArrayList<int[][]> ghostMoves;
  86. // Get all possible ghost moves
  87. ghostMoves = PacmanUtilities.allGhostMoves(Maze, currGhostsPosition);
  88. // loop all ghost moves
  89. int s = ghostMoves.size();
  90. for (int i=0 ; i<s ; ++i) {
  91. // Make a copy of the maze in order to simulate next move and move ghosts
  92. newMaze = PacmanUtilities.copy (Maze);
  93. PacmanUtilities.moveGhosts(newMaze, currGhostsPosition, ghostMoves.get(i));
  94. // Create a node for the move in the new stated game maze
  95. newNode = new Node89978445 (newMaze, parent.getCurentPacmanPos());
  96. newNode.getEvaluation();
  97. MinMaxTree.insert (newNode, parent); // add node to the min-max tree
  98. //recursive call for the rest of the tree
  99. //createSubTreePacman (depth, newNode, newMaze, parent.getCurentPacmanPos());
  100. }
  101. }
  102. }
  103. public int[] getPacPos (Room[][] Maze)
  104. {
  105. int[] pacmanPos = new int[2];
  106. for (int i = 0; i < PacmanUtilities.numberOfRows; i++) {
  107. for (int j = 0; j < PacmanUtilities.numberOfColumns; j++) {
  108. if (Maze[i][j].isPacman()) {
  109. pacmanPos[0] = i;
  110. pacmanPos[1] = j;
  111. return pacmanPos;
  112. }
  113. }
  114. }
  115. return pacmanPos;
  116. }
  117. public boolean[] comAvPos (Room[][] Maze, int[][] currentPos, int[] moves, int currentGhost)
  118. {
  119. boolean[] availablePositions = { true, true, true, true };
  120. int[][] newPos = new int[4][2];
  121. for (int i = 0; i < 4; i++) {
  122. if (Maze[currentPos[currentGhost][0]][currentPos[currentGhost][1]].walls[i] == 0) {
  123. availablePositions[i] = false;
  124. continue;
  125. }
  126. if (PacmanUtilities.flagColision(Maze, currentPos[currentGhost], i)) {
  127. availablePositions[i] = false;
  128. }
  129. else if (currentGhost == 0)
  130. continue;
  131. else {
  132. switch (i) {
  133. case Room.WEST:
  134. newPos[currentGhost][0] = currentPos[currentGhost][0];
  135. newPos[currentGhost][1] = currentPos[currentGhost][1] - 1;
  136. break;
  137. case Room.SOUTH:
  138. newPos[currentGhost][0] = currentPos[currentGhost][0] + 1;
  139. newPos[currentGhost][1] = currentPos[currentGhost][1];
  140. break;
  141. case Room.EAST:
  142. newPos[currentGhost][0] = currentPos[currentGhost][0];
  143. newPos[currentGhost][1] = currentPos[currentGhost][1] + 1;
  144. break;
  145. case Room.NORTH:
  146. newPos[currentGhost][0] = currentPos[currentGhost][0] - 1;
  147. newPos[currentGhost][1] = currentPos[currentGhost][1];
  148. }
  149. for (int j = (currentGhost - 1); j > -1; j--) {
  150. switch (moves[j]) {
  151. case Room.WEST:
  152. newPos[j][0] = currentPos[j][0];
  153. newPos[j][1] = currentPos[j][1] - 1;
  154. break;
  155. case Room.SOUTH:
  156. newPos[j][0] = currentPos[j][0] + 1;
  157. newPos[j][1] = currentPos[j][1];
  158. break;
  159. case Room.EAST:
  160. newPos[j][0] = currentPos[j][0];
  161. newPos[j][1] = currentPos[j][1] + 1;
  162. break;
  163. case Room.NORTH:
  164. newPos[j][0] = currentPos[j][0] - 1;
  165. newPos[j][1] = currentPos[j][1];
  166. // break;
  167. }
  168. if ((newPos[currentGhost][0] == newPos[j][0]) && (newPos[currentGhost][1] == newPos[j][1])) {
  169. availablePositions[i] = false;
  170. continue;
  171. }
  172. if ((newPos[currentGhost][0] == currentPos[j][0]) && (newPos[currentGhost][1] == currentPos[j][1]) && (newPos[j][0] == currentPos[currentGhost][0])
  173. && (newPos[j][1] == currentPos[currentGhost][1])) {
  174. availablePositions[i] = false;
  175. }
  176. }
  177. }
  178. }
  179. return availablePositions;
  180. }
  181. public int comBestPos (boolean[] availablePositions, int[] pacmanPosition, int[] currentPos)
  182. {
  183. int[] newVerticalDifference = new int[2];
  184. for (int i = 0; i < 2; i++)
  185. newVerticalDifference[i] = currentPos[i] - pacmanPosition[i];
  186. int[] distanceSquared = new int[4];
  187. for (int i = 0; i < 4; i++) {
  188. if (availablePositions[i] == true) {
  189. switch (i) {
  190. case Room.WEST:
  191. newVerticalDifference[1]--;
  192. break;
  193. case Room.SOUTH:
  194. newVerticalDifference[0]++;
  195. break;
  196. case Room.EAST:
  197. newVerticalDifference[1]++;
  198. break;
  199. case Room.NORTH:
  200. newVerticalDifference[0]--;
  201. break;
  202. }
  203. distanceSquared[i] = newVerticalDifference[0] * newVerticalDifference[0] + newVerticalDifference[1] * newVerticalDifference[1];
  204. } else
  205. distanceSquared[i] = PacmanUtilities.numberOfRows * PacmanUtilities.numberOfRows + PacmanUtilities.numberOfColumns * PacmanUtilities.numberOfColumns + 1;
  206. }
  207. int minDistance = distanceSquared[0];
  208. int minPosition = 0;
  209. for (int i = 1; i < 4; i++) {
  210. if (minDistance > distanceSquared[i]) {
  211. minDistance = distanceSquared[i];
  212. minPosition = i;
  213. }
  214. }
  215. return minPosition;
  216. }
  217. public int[] calculateNextGhostPosition (Room[][] Maze, int[][] currentPos)
  218. {
  219. int[] moves = new int[PacmanUtilities.numberOfGhosts];
  220. int[] pacmanPosition = new int[2];
  221. pacmanPosition = getPacPos(Maze);
  222. for (int i = 0; i < PacmanUtilities.numberOfGhosts; i++) {
  223. moves[i] = comBestPos(comAvPos(Maze, currentPos, moves, i), pacmanPosition, currentPos[i]);
  224. }
  225. return moves;
  226. }
  227. public boolean[] checkCollision (int[] moves, int[][] currentPos)
  228. {
  229. boolean[] collision = new boolean[PacmanUtilities.numberOfGhosts];
  230. int[][] newPos = new int[4][2];
  231. for (int i = 0; i < moves.length; i++) {
  232. if (moves[i] == 0) {
  233. if (currentPos[i][1] > 0) {
  234. newPos[i][0] = currentPos[i][0];
  235. newPos[i][1] = currentPos[i][1] - 1;
  236. } else {
  237. newPos[i][0] = currentPos[i][0];
  238. newPos[i][1] = PacmanUtilities.numberOfColumns - 1;
  239. }
  240. } else if (moves[i] == 1) {
  241. if (currentPos[i][0] < PacmanUtilities.numberOfRows - 1) {
  242. newPos[i][0] = currentPos[i][0] + 1;
  243. newPos[i][1] = currentPos[i][1];
  244. } else {
  245. newPos[i][0] = 0;
  246. newPos[i][1] = currentPos[i][1];
  247. }
  248. } else if (moves[i] == 2) {
  249. if (currentPos[i][1] < PacmanUtilities.numberOfColumns - 1) {
  250. newPos[i][0] = currentPos[i][0];
  251. newPos[i][1] = currentPos[i][1] + 1;
  252. } else {
  253. newPos[i][0] = currentPos[i][0];
  254. newPos[i][1] = 0;
  255. }
  256. } else {
  257. if (currentPos[i][0] > 0) {
  258. newPos[i][0] = currentPos[i][0] - 1;
  259. newPos[i][1] = currentPos[i][1];
  260. } else {
  261. newPos[i][0] = PacmanUtilities.numberOfRows - 1;
  262. newPos[i][1] = currentPos[i][1];
  263. }
  264. }
  265. collision[i] = false;
  266. }
  267. for (int k = 0; k < moves.length; k++) {
  268. }
  269. for (int i = 0; i < moves.length; i++) {
  270. for (int j = i + 1; j < moves.length; j++) {
  271. if (newPos[i][0] == newPos[j][0] && newPos[i][1] == newPos[j][1]) {
  272. collision[j] = true;
  273. }
  274. 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]) {
  275. collision[j] = true;
  276. }
  277. }
  278. }
  279. return collision;
  280. }
  281. }