/** * Method which simulates the game from a given node/state * * @param n * @return */ private int defaultPolicy(Node n) { Game currentState = n.getState().copy(); int d = 0; while (!isStateTerminal(currentState) && d != depth) { MOVE localCurrentDirection = null; if (d == 0 || currentState.isJunction( currentState.getPacmanCurrentNodeIndex())) { // is in a junction MOVE[] moves = currentState.getPossibleMoves(currentState.getPacmanCurrentNodeIndex()); int i = rng.nextInt(moves.length); localCurrentDirection = moves[i]; while (moves[i] == localCurrentDirection.opposite()) { i = rng.nextInt(moves.length); } localCurrentDirection = moves[i]; } currentState.advanceGame( localCurrentDirection, controller.Controller.getGhostController().getMove(currentState, 0)); d++; } if (isStateTerminal(currentState)) { return -1; } return currentState.getScore(); }
public DataTuple(String data) { String[] dataSplit = data.split(";"); this.DirectionChosen = MOVE.valueOf(dataSplit[0]); this.mazeIndex = Integer.parseInt(dataSplit[1]); this.currentLevel = Integer.parseInt(dataSplit[2]); this.pacmanPosition = Integer.parseInt(dataSplit[3]); this.pacmanLivesLeft = Integer.parseInt(dataSplit[4]); this.currentScore = Integer.parseInt(dataSplit[5]); this.totalGameTime = Integer.parseInt(dataSplit[6]); this.currentLevelTime = Integer.parseInt(dataSplit[7]); this.numOfPillsLeft = Integer.parseInt(dataSplit[8]); this.numOfPowerPillsLeft = Integer.parseInt(dataSplit[9]); this.isBlinkyEdible = Boolean.parseBoolean(dataSplit[10]); this.isInkyEdible = Boolean.parseBoolean(dataSplit[11]); this.isPinkyEdible = Boolean.parseBoolean(dataSplit[12]); this.isSueEdible = Boolean.parseBoolean(dataSplit[13]); this.blinkyDist = Integer.parseInt(dataSplit[14]); this.inkyDist = Integer.parseInt(dataSplit[15]); this.pinkyDist = Integer.parseInt(dataSplit[16]); this.sueDist = Integer.parseInt(dataSplit[17]); this.blinkyDir = MOVE.valueOf(dataSplit[18]); this.inkyDir = MOVE.valueOf(dataSplit[19]); this.pinkyDir = MOVE.valueOf(dataSplit[20]); this.sueDir = MOVE.valueOf(dataSplit[21]); this.numberOfNodesInLevel = Integer.parseInt(dataSplit[22]); this.numberOfTotalPillsInLevel = Integer.parseInt(dataSplit[23]); this.numberOfTotalPowerPillsInLevel = Integer.parseInt(dataSplit[24]); }
/** * Sets the game state from a string: the inverse of getGameState(). It reconstructs all the * game's variables from the string. * * @param gameState The game state represented as a string */ public void setGameState(String gameState) { String[] values = gameState.split(","); int index = 0; indiceDeLaberinto = Integer.parseInt(values[index++]); tiempoTotal = Integer.parseInt(values[index++]); score = Integer.parseInt(values[index++]); tiempoLvlActual = Integer.parseInt(values[index++]); cuentaElLvl = Integer.parseInt(values[index++]); pacman = new PacMan( Integer.parseInt(values[index++]), MOVE.valueOf(values[index++]), Integer.parseInt(values[index++]), Boolean.parseBoolean(values[index++])); fantasmas = new EnumMap<GHOST, Ghost>(GHOST.class); for (GHOST ghostType : GHOST.values()) fantasmas.put( ghostType, new Ghost( ghostType, Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), Integer.parseInt(values[index++]), MOVE.valueOf(values[index++]))); _setPills(laberintoActua = laberintos[indiceDeLaberinto]); for (int i = 0; i < values[index].length(); i++) if (values[index].charAt(i) == '1') pills.set(i); else pills.clear(i); index++; for (int i = 0; i < values[index].length(); i++) if (values[index].charAt(i) == '1') powerPills.set(i); else powerPills.clear(i); timeOfLastGlobalReversal = Integer.parseInt(values[++index]); pacmanFueComido = Boolean.parseBoolean(values[++index]); fantasmaComido = new EnumMap<GHOST, Boolean>(GHOST.class); for (GHOST ghost : GHOST.values()) fantasmaComido.put(ghost, Boolean.parseBoolean(values[++index])); pastillaFueComida = Boolean.parseBoolean(values[++index]); pildoraPoderFueComida = Boolean.parseBoolean(values[++index]); }
@Override public MOVE getMove(Game g, long t) { if (g.gameOver()) { currentDirection = null; } else if (!moved) { moved = true; return currentDirection; } else if (!g.isJunction(g.getPacmanCurrentNodeIndex()) && currentDirection != null) { ArrayList<MOVE> moves = new ArrayList<MOVE>(Arrays.asList(g.getPossibleMoves(g.getPacmanCurrentNodeIndex()))); // MOVE[]g.getPossibleMoves(pacmanNode) if (moves.contains(currentDirection)) { return currentDirection; } else { moves.remove(currentDirection.opposite()); currentDirection = moves.get(0); return moves.get(0); } } if (0 < t) { return run(g, t); } else { // TESTING MOVE m = run(g); return m; // // return run(g); } }
private int Asearch(Game game) { Comparator<PacManNode> comparator = new PacComparator(); PriorityQueue<PacManNode> open = new PriorityQueue<PacManNode>(1, comparator); // because we are conducting tree-search, so 'closed' may not be used, but I'll still leave it // here HashSet<PacManNode> closed = new HashSet<PacManNode>(); open.add(new PacManNode(game.copy(), 0)); int score = game.getScore(); while (!open.isEmpty()) { PacManNode node = open.poll(); closed.add(node); if (node.depth == DEPTH) { // System.out. score = node.currentState.getScore(); return score; } MOVE[] moves = MOVE.values(); for (MOVE move : moves) { Game gameCopy = node.currentState.copy(); gameCopy.advanceGame(move, ghosts.getMove(gameCopy, 0)); open.add(new PacManNode(gameCopy, node.depth + 1)); } } return score; }
public int[] getPathToJunction(MOVE lastMoveMade) { if (isJunction) return new int[] {}; for (int i = 0; i < closestJunctions.size(); i++) if (!closestJunctions.get(i).firstMove.equals(lastMoveMade.opposite())) return closestJunctions.get(i).path; return null; }
public JunctionData getNearestJunction(MOVE lastMoveMade) { if (isJunction) return closestJunctions.get(0); for (int i = 0; i < closestJunctions.size(); i++) if (!closestJunctions.get(i).firstMove.equals(lastMoveMade.opposite())) return closestJunctions.get(i); return null; }
/** * Method that returns the direction to take given a node index and an index of a neighbouring * node. Returns null if the neighbour is invalid. * * @param currentNodeIndex The current node index. * @param neighbourNodeIndex The direct neighbour (node index) of the current node. * @return the move to make to reach direct neighbour */ public MOVE getMoveToMakeToReachDirectNeighbour(int currentNodeIndex, int neighbourNodeIndex) { for (MOVE move : MOVE.values()) { if (laberintoActua.graph[currentNodeIndex].neighbourhood.containsKey(move) && laberintoActua.graph[currentNodeIndex].neighbourhood.get(move) == neighbourNodeIndex) { return move; } } return null; }
@Override public MOVE getMove(Game game, long timeDue) { int score = -1; MOVE ret = MOVE.NEUTRAL; MOVE[] moves = MOVE.values(); for (MOVE move : moves) { Game gameCopy = game.copy(); gameCopy.advanceGame(move, ghosts.getMove(gameCopy, timeDue)); int cur = Asearch(gameCopy); System.out.println(move.toString() + "\t score: " + cur); if (cur >= score) { score = cur; ret = move; } } System.out.println("Move to: " + ret.toString()); System.out.println("\t--------"); return ret; }
/* * The Class Legacy. */ public class Legacy extends Controller<EnumMap<GHOST, MOVE>> { Random rnd = new Random(); EnumMap<GHOST, MOVE> myMoves = new EnumMap<GHOST, MOVE>(GHOST.class); MOVE[] moves = MOVE.values(); /* (non-Javadoc) * @see pacman.controllers.Controller#getMove(pacman.game.Game, long) */ public EnumMap<GHOST, MOVE> getMove(Game game, long timeDue) { myMoves.clear(); int targetNode = game.getPacmanCurrentNodeIndex(); if (game.doesGhostRequireAction(GHOST.BLINKY)) myMoves.put( GHOST.BLINKY, game.getApproximateNextMoveTowardsTarget( game.getGhostCurrentNodeIndex(GHOST.BLINKY), targetNode, game.getGhostLastMoveMade(GHOST.BLINKY), DM.PATH)); if (game.doesGhostRequireAction(GHOST.INKY)) myMoves.put( GHOST.INKY, game.getApproximateNextMoveTowardsTarget( game.getGhostCurrentNodeIndex(GHOST.INKY), targetNode, game.getGhostLastMoveMade(GHOST.INKY), DM.MANHATTAN)); if (game.doesGhostRequireAction(GHOST.PINKY)) myMoves.put( GHOST.PINKY, game.getApproximateNextMoveTowardsTarget( game.getGhostCurrentNodeIndex(GHOST.PINKY), targetNode, game.getGhostLastMoveMade(GHOST.PINKY), DM.EUCLID)); if (game.doesGhostRequireAction(GHOST.SUE)) myMoves.put(GHOST.SUE, moves[rnd.nextInt(moves.length)]); return myMoves; } }
public JunctionData getNearestJunction(MOVE lastMoveMade) { if (isJunction) return closestJunctions.get(0); int minDist = Integer.MAX_VALUE; int bestIndex = -1; for (int i = 0; i < closestJunctions.size(); i++) if (!closestJunctions.get(i).firstMove.equals(lastMoveMade.opposite())) { int newDist = closestJunctions.get(i).path.length; if (newDist < minDist) { minDist = newDist; bestIndex = i; } } if (bestIndex != -1) return closestJunctions.get(bestIndex); else return null; }
public void computeShortestPaths() { MOVE[] moves = MOVE.values(); for (int i = 0; i < paths.length; i++) { if (i == jctId) paths[i].put(MOVE.NEUTRAL, new int[] {}); else { int distance = Integer.MAX_VALUE; int[] path = null; for (int j = 0; j < moves.length; j++) { if (paths[i].containsKey(moves[j])) { int[] tmp = paths[i].get(moves[j]); if (tmp.length < distance) { distance = tmp.length; path = tmp; } } } paths[i].put(MOVE.NEUTRAL, path); } } }
public String toString() { return nodeID + "\t" + firstMove.toString() + "\t" + Arrays.toString(path); }
public int[] getPathFromA2B(int a, int b, MOVE lastMoveMade) { // not going anywhere if (a == b) return new int[] {}; // first, go to closest junction (there is only one since we can't reverse) JunctionData fromJunction = nodes[a].getNearestJunction(lastMoveMade); // if target is on the way to junction, then we are done for (int i = 0; i < fromJunction.path.length; i++) if (fromJunction.path[i] == b) return Arrays.copyOf(fromJunction.path, i + 1); // we have reached a junction, fromJunction, which we entered with moveEnteredJunction int junctionFrom = fromJunction.nodeID; int junctionFromId = junctionIndexConverter.get(junctionFrom); MOVE moveEnteredJunction = fromJunction.lastMove.equals(MOVE.NEUTRAL) ? lastMoveMade : fromJunction.lastMove; // if we are at a junction, consider last move instead // now we need to get the 1 or 2 target junctions that enclose the target point ArrayList<JunctionData> junctionsTo = nodes[b].closestJunctions; int minDist = Integer.MAX_VALUE; int[] shortestPath = null; int closestJunction = -1; boolean onTheWay = false; for (int q = 0; q < junctionsTo.size(); q++) { int junctionToId = junctionIndexConverter.get(junctionsTo.get(q).nodeID); if (junctionFromId == junctionToId) { if (!game.getMoveToMakeToReachDirectNeighbour( junctionFrom, junctionsTo.get(q).reversePath[0]) .equals(moveEnteredJunction.opposite())) { int[] reversepath = junctionsTo.get(q).reversePath; int cutoff = -1; for (int w = 0; w < reversepath.length; w++) if (reversepath[w] == b) cutoff = w; shortestPath = Arrays.copyOf(reversepath, cutoff + 1); minDist = shortestPath.length; closestJunction = q; onTheWay = true; } } else { EnumMap<MOVE, int[]> paths = junctions[junctionFromId].paths[junctionToId]; Set<MOVE> set = paths.keySet(); for (MOVE move : set) { if (!move.opposite().equals(moveEnteredJunction) && !move.equals(MOVE.NEUTRAL)) { int[] path = paths.get(move); if (path.length + junctionsTo.get(q).path.length < minDist) // need to take distance from toJunction to target into account { minDist = path.length + junctionsTo.get(q).path.length; shortestPath = path; closestJunction = q; onTheWay = false; } } } } } if (!onTheWay) return concat(fromJunction.path, shortestPath, junctionsTo.get(closestJunction).reversePath); else return concat(fromJunction.path, shortestPath); // return concat(fromJunction.path, junctionsTo.get(closestJunction).reversePath); }
public int getPathDistanceFromA2B(int a, int b, MOVE lastMoveMade) { // not going anywhere if (a == b) return 0; // find nearest junction (there is only one since we can't reverse) // first, go to closest junction JunctionData fromJunction = nodes[a].getNearestJunction(lastMoveMade); // if target is on the way to junction, then we are done for (int i = 0; i < fromJunction.path.length; i++) if (fromJunction.path[i] == b) return i + 1; // we have reached a junction, fromJunction, which we entered with moveEnteredJunction int junctionFrom = fromJunction.nodeID; MOVE moveEnteredJunction = fromJunction.lastMove.equals(MOVE.NEUTRAL) ? lastMoveMade : fromJunction.lastMove; // if we are at a junction, consider last move instead // now we need to get the 1 or 2 target junctions that enclose the target point ArrayList<JunctionData> junctionsTo = nodes[b].closestJunctions; int minDist = Integer.MAX_VALUE; int closestJunction = -1; int junctionFromId = junctionIndexConverter.get(junctionFrom); for (int q = 0; q < junctionsTo.size(); q++) { int junctionToId = junctionIndexConverter.get(junctionsTo.get(q).nodeID); // we are already on the right junction. If the target is in position so that no reversal is // required, we are done if (junctionFrom == junctionsTo.get(q).nodeID) { if (!game.getMoveToMakeToReachDirectNeighbour( junctionFrom, junctionsTo.get(q).reversePath[0]) .equals(moveEnteredJunction.opposite())) { closestJunction = q; minDist = junctionsTo.get(closestJunction).path.length; break; } } EnumMap<MOVE, int[]> paths = junctions[junctionFromId].paths[junctionToId]; Set<MOVE> set = paths.keySet(); for (MOVE move : set) { if (!move.opposite().equals(moveEnteredJunction) && !move.equals(MOVE.NEUTRAL)) { int[] path = paths.get(move); if (path.length + junctionsTo.get(q).path.length < minDist) // need to take distance from toJunction to target into account { minDist = path.length + junctionsTo.get(q).path.length; closestJunction = q; } } } } return fromJunction.path.length + minDist; }