/** * 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(); }
/** * 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(); } }
// Loads all the nodes from files and initialises all maze-specific information. private void loadNodes(String fileName) { try { BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream( pathMazes + System.getProperty("file.separator") + fileName + ".txt"))); String input = br.readLine(); // preamble String[] pr = input.split("\t"); this.name = pr[0]; this.initialPacManNodeIndex = Integer.parseInt(pr[1]); this.lairNodeIndex = Integer.parseInt(pr[2]); this.initialGhostNodeIndex = Integer.parseInt(pr[3]); this.graph = new Node[Integer.parseInt(pr[4])]; this.pillIndices = new int[Integer.parseInt(pr[5])]; this.powerPillIndices = new int[Integer.parseInt(pr[6])]; this.junctionIndices = new int[Integer.parseInt(pr[7])]; int nodeIndex = 0; int pillIndex = 0; int powerPillIndex = 0; int junctionIndex = 0; input = br.readLine(); while (input != null) { String[] nd = input.split("\t"); Node node = new Node( Integer.parseInt(nd[0]), Integer.parseInt(nd[1]), Integer.parseInt(nd[2]), Integer.parseInt(nd[7]), Integer.parseInt(nd[8]), new int[] { Integer.parseInt(nd[3]), Integer.parseInt(nd[4]), Integer.parseInt(nd[5]), Integer.parseInt(nd[6]) }); graph[nodeIndex++] = node; if (node.pillIndex >= 0) pillIndices[pillIndex++] = node.nodeIndex; else if (node.powerPillIndex >= 0) powerPillIndices[powerPillIndex++] = node.nodeIndex; if (node.numNeighbouringNodes > 2) junctionIndices[junctionIndex++] = node.nodeIndex; input = br.readLine(); } br.close(); } catch (IOException ioe) { ioe.printStackTrace(); } }
/** * 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(); }
// 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); }
/* * Loads the shortest path distances which have been pre-computed. The data contains the shortest distance from * any node in the maze to any other node. Since the graph is symmetric, the symmetries have been removed to preserve * memory and all distances are stored in a 1D array; they are looked-up using getDistance(-). */ private void loadDistances(String fileName) { this.shortestPathDistances = new int[((graph.length * (graph.length - 1)) / 2) + graph.length]; try { BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream( pathDistances + System.getProperty("file.separator") + fileName))); String input = br.readLine(); int index = 0; while (input != null) { shortestPathDistances[index++] = Integer.parseInt(input); input = br.readLine(); } br.close(); } catch (IOException ioe) { ioe.printStackTrace(); } }
/** * 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); }
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(); } }