/* * Implementation of "Ms Pac-Man" for the "Ms Pac-Man versus Ghost Team Competition", brought * to you by Philipp Rohlfshagen, David Robles and Simon Lucas of the University of Essex. * * www.pacman-vs-ghosts.net * * Code written by Philipp Rohlfshagen, based on earlier implementations of the game by * Simon Lucas and David Robles. * * You may use and distribute this code freely for non-commercial purposes. This notice * needs to be included in all distributions. Deviations from the original should be * clearly documented. We welcome any comments and suggestions regarding the code. */ package game.core; import java.util.Random; /* * This interface defines the contract between the game engine and the controllers. It provides all * the methods a controller may use to (a) query the game state, (b) compute game-related attributes * and (c) test moves by using a forward model (i.e., copy() followed by advanceGame()). */ public interface Game { //These constants specify the exact nature of the game public static final int UP=0; //direction going up public static final int RIGHT=1; //direction going right public static final int DOWN=2; //direction going down public static final int LEFT=3; //direction going left public static final int EMPTY=-1; //value of an non-existing neighbour public static final int PILL=10; //points for a pill public static final int POWER_PILL=50; //points for a power pill public static final int GHOST_EAT_SCORE=200; //score for the first ghost eaten (doubles every time for the duration of a single power pill) public static final int EDIBLE_TIME=200; //initial time a ghost is edible for (decreases as level number increases) public static final float EDIBLE_TIME_REDUCTION=0.9f; //reduction factor by which edible time decreases as level number increases public static final int[] LAIR_TIMES={40,60,80,100}; //time spend in the lair by each ghost at the start of a level public static final int COMMON_LAIR_TIME=40; //time spend in lair after being eaten public static final float LAIR_REDUCTION=0.9f; //reduction factor by which lair times decrease as level number increases public static final int LEVEL_LIMIT=3000; //time limit for a level public static final int MAX_LEVELS=16; //maximum number of levels played before the end of the game public static final int EXTRA_LIFE_SCORE=10000; //extra life is awarded when this many points have been collected public static final int EAT_DISTANCE=2; //distance in the connected graph considered close enough for an eating event to take place public static final int NUM_GHOSTS=4; //number of ghosts in the game public static final int NUM_MAZES=4; //number of different mazes in the game public static final int DELAY=40; //delay (in milliseconds) between game advancements public static final int NUM_LIVES=3; //total number of lives Ms Pac-Man has (current + NUM_LIVES-1 spares) public static final int INITIAL_PAC_DIR=3; //initial direction taken by Ms Pac-Man public static final int[] INITIAL_GHOST_DIRS={Game.LEFT, Game.LEFT, Game.LEFT, Game.LEFT}; //initial directions for the ghosts (after leaving the lair) public static final int GHOST_SPEED_REDUCTION=2; //difference in speed when ghosts are edible (every GHOST_SPEED_REDUCTION, a ghost remains stationary) public static final Random rnd=new Random(); public Game copy(); //returns an exact copy of the game (forward model) public int[] advanceGame(int pacManDir,int[] ghostDirs); //advances the game using the actions (directions) supplied; returns all directions played [PacMan, Ghost1, Ghost2, Ghost3, Ghost4] public int getReverse(int direction); //returns the reverse of the direction supplied public boolean gameOver(); //returns true is Ms Pac-Man has lost all her lives or if MAX_LEVELS has been reached public boolean checkPill(int pillIndex); //checks if the pill specified is still available public boolean checkPowerPill(int powerPillIndex); //checks if the power pill specified is still available public int[] getPacManNeighbours(); //returns an array of size 4, indicating neighbouring nodes for the current position of Ms Pac-Man. E.g., [-1,12,-1,44] for neighbours 12 and 44 in direction RIGHT and LEFT public int[] getGhostNeighbours(int whichGhost); //returns an array of size 4, indicating neighbouring nodes for the current position of the ghost specified. Replaces the direction corresponding to the opposite previous direction with -1 public int getCurLevel(); //returns the current level public int getCurMaze(); //returns the current maze public int getCurPacManLoc(); //returns the node index Ms Pac-Man is at public int getCurPacManDir(); //returns the last direction taken by Ms Pac-Man public int getLivesRemaining(); //returns the number of lives remaining for Ms Pac-Man public int getCurGhostLoc(int whichGhost); //returns the node index for the ghost specified public int getCurGhostDir(int whichGhost); //returns the last direction taken by the ghost specified public int getEdibleTime(int whichGhost); //returns the edible time (time left in which the ghost can be eaten) for the ghost specified public boolean isEdible(int whichGhost); //returns true if the ghost is currently edible public int getScore(); //returns the score of the game public int getLevelTime(); //returns the time for which the CURRENT level has been played public int getTotalTime(); //returns the time for which the game has been played (across all levels) public int getNumberPills(); //returns the total number of pills in this maze (at the beginning of the level) public int getNumberPowerPills(); //returns the total number of power pills in this maze (at the beginning of the level) public int getLairTime(int whichGhost); //returns the time remaining the ghost specified spends in the lair public boolean ghostRequiresAction(int whichGhost); //returns true of ghost is at a junction and a direction is needed public String getName(); //returns the name of the maze public int getInitialPacPosition(); //returns the position where Ms Pac-Man starts at the beginning of the level public int getInitialGhostsPosition(); //returns the position where the ghosts starts at the beginning of the level, AFTER leaving the lair public int getNumberOfNodes(); //returns the total number of nodes in the graph (pills, power pills and empty) public int getX(int nodeIndex); //returns the x-coordinate of the node specified public int getY(int nodeIndex); //returns the y-coordinate of the node specified public int getPillIndex(int nodeIndex); //returns the pill index of the node specified (can be used with the bitset for the pills) public int getPowerPillIndex(int nodeIndex); //returns the power pill index of the node specified (can be used with the bitset for the power pills) public int getNeighbour(int nodeIndex,int direction); //returns the neighbour of the node specified for the direction supplied public int[] getPillIndices(); //returns indices to all nodes with pills public int[] getPowerPillIndices(); //returns indices to all nodes with power pills public int[] getJunctionIndices(); //returns indices to all nodes that are junctions public int getNextEdibleGhostScore(); //returns the score awarded for the next ghost to be eaten public int getNumActivePills(); //returns the number of pills still in the maze public int getNumActivePowerPills(); //returns the number of power pills still in the maze public int[] getPillIndicesActive(); //returns the indices of all active pills in the maze public int[] getPowerPillIndicesActive(); //returns the indices of all active power pills in the maze public boolean isJunction(int nodeIndex); //returns true if node is a junction (more than 2 neighbours) public int getNumNeighbours(int nodeIndex); //returns the number of neighbours of the node specified public enum DM{PATH,EUCLID,MANHATTEN}; //simple enumeration for use with the direction methods (below) public int getNextPacManDir(int to,boolean closer,DM measure); //returns the direction Ms Pac-Man should take to approach/retreat from the node specified, using the distance measure specified public int getNextGhostDir(int whichGhost,int to,boolean closer,DM measure); //returns the direction the ghost specified should take to approach/retreat from the node specified, using the distance measure specified public int getPathDistance(int from,int to); //returns the shortest path distance (Dijkstra) from one node to another public double getEuclideanDistance(int from,int to); //returns the Euclidean distance between two nodes public int getManhattenDistance(int from,int to); //returns the Manhatten distance between two nodes public int[] getPossiblePacManDirs(boolean includeReverse); //returns the set of possible directions for Ms Pac-Man, with or without the direction opposite to the last direction taken public int[] getPossibleGhostDirs(int whichGhost); //returns the set of possible directions for the ghost specified (excludes the opposite of the previous direction) public int[] getPath(int from,int to); //returns the path from one node to another (e.g., [1,2,5,7,9] for 1 to 9) public int[] getGhostPath(int whichGhost,int to); //returns the path from one node to another, taking into account that reversals are not possible public int getTarget(int from,int[] targets,boolean nearest,DM measure); //selects a target from 'targets' given current position ('from'), a distance measure and whether it should be the point closest or farthest public int getGhostTarget(int from,int[] targets,boolean nearest); //selects a target for a ghost (accounts for the fact that ghosts may not reverse) public int getGhostPathDistance(int whichGhost,int to); //returns the distance of a path for the ghost specified (accounts for the fact that ghosts may not reverse) }