/** * 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(); } }
/** * 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(); }
/** * 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); }