/** * Run a game in asynchronous mode: the game waits until a move is returned. In order to slow * thing down in case the controllers return very quickly, a time limit can be used. If fasted * gameplay is required, this delay should be put as 0. * * @param pacManController The Pac-Man controller * @param ghostController The Ghosts controller * @param visual Indicates whether or not to use visuals * @param delay The delay between time-steps */ public void runGame( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, boolean visual, int delay) { try { PrintStream out = new PrintStream("replay.txt"); Game game = new Game(0); GameView gv = null; if (visual) gv = new GameView(game).showGame(); while (!game.gameOver()) { game.advanceGame( pacManController.getMove(game.copy(), -1), ghostController.getMove(game.copy(), System.currentTimeMillis() + Long.MAX_VALUE)); try { Thread.sleep(delay); } catch (Exception e) { } if (visual) gv.repaint(); out.println(game.getGameState()); out.flush(); } out.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/** * Run the game with time limit (asynchronous mode). This is how it will be done in the * competition. Can be played with and without visual display of game states. * * @param pacManController The Pac-Man controller * @param ghostController The Ghosts controller * @param visual Indicates whether or not to use visuals */ public void runGameTimed( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, boolean visual) { Game game = new Game(0); GameView gv = null; if (visual) gv = new GameView(game).showGame(); if (pacManController instanceof HumanController) gv.getFrame().addKeyListener(((HumanController) pacManController).getKeyboardInput()); new Thread(pacManController).start(); new Thread(ghostController).start(); while (!game.gameOver()) { pacManController.update(game.copy(), System.currentTimeMillis() + DELAY); ghostController.update(game.copy(), System.currentTimeMillis() + DELAY); try { Thread.sleep(DELAY); } catch (InterruptedException e) { e.printStackTrace(); } game.advanceGame(pacManController.getMove(), ghostController.getMove()); if (visual) gv.repaint(); } pacManController.terminate(); ghostController.terminate(); }
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; }
/** * Run the game in asynchronous mode but proceed as soon as both controllers replied. The time * limit still applies so so the game will proceed after 40ms regardless of whether the * controllers managed to calculate a turn. * * @param pacManController The Pac-Man controller * @param ghostController The Ghosts controller * @param fixedTime Whether or not to wait until 40ms are up even if both controllers already * responded * @param visual Indicates whether or not to use visuals */ public void runGameTimedSpeedOptimised( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, boolean fixedTime, boolean visual) { Game game = new Game(0); GameView gv = null; if (visual) gv = new GameView(game).showGame(); if (pacManController instanceof HumanController) gv.getFrame().addKeyListener(((HumanController) pacManController).getKeyboardInput()); new Thread(pacManController).start(); new Thread(ghostController).start(); while (!game.gameOver()) { pacManController.update(game.copy(), System.currentTimeMillis() + DELAY); ghostController.update(game.copy(), System.currentTimeMillis() + DELAY); try { int waited = DELAY / INTERVAL_WAIT; for (int j = 0; j < DELAY / INTERVAL_WAIT; j++) { Thread.sleep(INTERVAL_WAIT); if (pacManController.hasComputed() && ghostController.hasComputed()) { waited = j; break; } } if (fixedTime) Thread.sleep(((DELAY / INTERVAL_WAIT) - waited) * INTERVAL_WAIT); game.advanceGame(pacManController.getMove(), ghostController.getMove()); } catch (InterruptedException e) { e.printStackTrace(); } if (visual) gv.repaint(); } pacManController.terminate(); ghostController.terminate(); }
/** * Run a game in asynchronous mode: the game waits until a move is returned. In order to slow * thing down in case the controllers return very quickly, a time limit can be used. If fasted * gameplay is required, this delay should be put as 0. * * @param pacManController The Pac-Man controller * @param ghostController The Ghosts controller * @param visual Indicates whether or not to use visuals * @param delay The delay between time-steps */ public void runGame( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, boolean visual, int delay) { Game game = new Game(0); GameView gv = null; if (visual) gv = new GameView(game).showGame(); while (!game.gameOver()) { game.advanceGame( pacManController.getMove(game.copy(), -1), ghostController.getMove(game.copy(), -1)); try { Thread.sleep(delay); } catch (Exception e) { } if (visual) gv.repaint(); } }
/** * For running multiple games without visuals. This is useful to get a good idea of how well a * controller plays against a chosen opponent: the random nature of the game means that * performance can vary from game to game. Running many games and looking at the average score * (and standard deviation/error) helps to get a better idea of how well the controller is likely * to do in the competition. * * @param pacManController The Pac-Man controller * @param ghostController The Ghosts controller * @param trials The number of trials to be executed */ public void runExperiment( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, int trials) { double avgScore = 0; Random rnd = new Random(0); Game game; for (int i = 0; i < trials; i++) { game = new Game(rnd.nextLong()); while (!game.gameOver()) { long due = System.currentTimeMillis() + DELAY; game.advanceGame( pacManController.getMove(game.copy(), due), ghostController.getMove(game.copy(), due)); } avgScore += game.getScore(); System.out.println(i + "\t" + game.getScore()); } System.out.println(avgScore / trials); }
// Funcion que ejecuta varias veces el juego con los controladores que se le pasan por parametro y // devuelve la media de la puntiacion de todas las partidas public double runGenetico( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, int trials) { double avgScore = 0; Random rnd = new Random(0); Game game; for (int i = 0; i < trials; i++) { game = new Game(rnd.nextLong()); while (!game.gameOver()) { game.advanceGame( pacManController.getMove(game.copy(), System.currentTimeMillis() + DELAY), ghostController.getMove(game.copy(), System.currentTimeMillis() + DELAY)); } avgScore += game.getScore(); } // System.out.println(avgScore/trials); return (avgScore / trials); }
@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; }
@Override public Constants.MOVE getMove(Game game, long timeDue) { // Random random = new Random(); Constants.MOVE[] allMoves = Constants.MOVE.values(); int highSorce = -1; Constants.MOVE highMove = null; // Start State // int[] a = new int[5]; HashMap<MOVE, Integer> map = new HashMap<>(); HashMap<Integer, MOVE> map2 = new HashMap<>(); for (Constants.MOVE m : allMoves) { Game gameCopy = game.copy(); Game gameATM = gameCopy; gameATM.advanceGame(m, ghosts.getMove(gameATM, timeDue)); // Neighbors int tempHightSocre = this.hill_climbing_value(gameATM); map.put(m, tempHightSocre); map2.put(tempHightSocre, m); System.out.println("PacMan Trying Move:" + m + ", Socre:" + tempHightSocre); } int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; // Pick one with the highest score, if higher than cuurent state, move to the child state for (Map.Entry<MOVE, Integer> it : map.entrySet()) { min = Math.min(min, it.getValue()); max = Math.max(max, it.getValue()); } if (min == max) { highMove = MOVE.LEFT; } else { highMove = map2.get(max); } System.out.println("High Score:" + highSorce + ", High Move:" + highMove); return highMove; }
public void runQLearner( Controller<MOVE> pacManController, Controller<EnumMap<GHOST, MOVE>> ghostController, int iteraciones) { System.out.println("Entrenamos nuestro controlador con " + iteraciones + " iteraciones."); long start_time = System.nanoTime(); QLearner learner = new QLearner(); learner.initialize(); Game game; Estado estado; Accion accion; Estado lastEstado; Accion lastAccion; Estado ePrima; MOVE siguienteMovimiento; float recompensa; for (int i = 0; i < iteraciones; i++) { System.out.println("Ejecucion del juego: " + i); game = new Game(0); lastEstado = null; lastAccion = null; while (!game.gameOver()) { recompensa = 0; estado = learner.getState(game); accion = learner.getAccion(estado); siguienteMovimiento = accion.getMovimientoFromAccion(game); recompensa = estado.getRecompensa(); if (lastEstado != null) { learner.update(lastEstado, lastAccion, recompensa, estado); } lastEstado = estado; lastAccion = accion; // Le pasamos el siguiente movimiento al controlador ((QController) ghostController).setSiguienteMovimiento(siguienteMovimiento); game.advanceGame( pacManController.getMove(game.copy(), System.currentTimeMillis() + DELAY), ghostController.getMove(game.copy(), System.currentTimeMillis() + DELAY)); } estado = learner.getState(game); recompensa = estado.getRecompensa(); learner.update(lastEstado, lastAccion, recompensa, estado); } long end_time = System.nanoTime(); double tiempo = (((end_time - start_time) / 1e6) / 1000); System.out.println(learner); System.out.printf("Tiempo de entrenamiento: %.2f segundos%n", tiempo); System.out.printf( "Ejecucion del juego en modo grafico con la QTable generada en el entrenamiento."); game = new Game(0); GameView gv = new GameView(game).showGame(); while (!game.gameOver()) { pacManController.update(game.copy(), System.currentTimeMillis() + DELAY); ghostController.update(game.copy(), System.currentTimeMillis() + DELAY); // Obtenemos la mejor accion segun el estado actual (miramos en la QTabla la accion con mas // puntuacion para ese estado) Accion mejorAccionFromTQtable = learner.getMejorAccion(learner.getState(game)); siguienteMovimiento = mejorAccionFromTQtable.getMovimientoFromAccion(game); // Le pasamos el siguiente movimiento al controlador ((QController) ghostController).setSiguienteMovimiento(siguienteMovimiento); game.advanceGame( pacManController.getMove(game.copy(), System.currentTimeMillis() + DELAY), ghostController.getMove(game.copy(), System.currentTimeMillis() + DELAY)); try { Thread.sleep(DELAY); } catch (InterruptedException e) { e.printStackTrace(); } gv.repaint(); } }
public Constants.MOVE kNN(Game game, int k, long timeDue) { Constants.MOVE bestMove = myMove; int current = game.getPacmanCurrentNodeIndex(); double averageDistance = averageGhostDistance(game); int positionBottom = kNNSearch(0, historicalData.size(), averageDistance); int positionTop = positionBottom + 1; k--; int totalCount = k / 2; while (totalCount > 0 && k > 0) { if (positionBottom > 0) { if (historicalData.get(positionBottom).moveAway) { totalCount--; } positionBottom--; k--; if (k <= 0) break; } if (positionTop < historicalData.size()) { if (historicalData.get(positionTop).moveAway) { totalCount--; } positionTop++; k--; } } Constants.MOVE[] next = game.getPossibleMoves(current); if (totalCount > 0) { double closestAway = Double.POSITIVE_INFINITY; for (int index : game.getActivePillsIndices()) { double distanceAway = game.getShortestPathDistance(game.getPacmanCurrentNodeIndex(), index); if (distanceAway < closestAway) closestAway = distanceAway; } for (Constants.MOVE eachMove : next) { Game newState = game.copy(); newState.advanceGame(eachMove, new AggressiveGhosts().getMove()); // if near to pill good; double nextClosestAway = Double.POSITIVE_INFINITY; for (int index : newState.getActivePillsIndices()) { double distanceAway = newState.getShortestPathDistance(newState.getPacmanCurrentNodeIndex(), index); if (distanceAway < closestAway) nextClosestAway = distanceAway; } if (nextClosestAway <= closestAway) bestMove = eachMove; } } else { for (Constants.MOVE eachMove : next) { Game newState = game.copy(); newState.advanceGame(eachMove, new AggressiveGhosts().getMove()); if (averageGhostDistance(newState) < averageDistance) { bestMove = eachMove; } } } lastMove = bestMove; return bestMove; }