### Question:
GameController implements Runnable, GameListener { @Override public void run() { RobotMap map=ColorSensor.generate(COLS,COLS,DOT_SPACING); synchronized(controlPairs) { for(int i=0; i<controlPairs.size(); i++){ RobotProxy proxy=controlPairs.get(i).getRobotProxy(); if(proxy instanceof robowars.test.TestRobotProxy) continue; proxy.sendCommand(RobotCommand.setPosition(map.getStartPoint(i))); } } log.info("Robot Map and starting points sent"); log.info("Game execution starting."); lobby.broadcastMessage("<Server> Game launched."); long gameStartTime = System.currentTimeMillis(); long lastUpdateTime = gameStartTime; long timeElapsed = 0; model.startGame(); while(!terminateFlag) { timeElapsed = System.currentTimeMillis() - lastUpdateTime; lastUpdateTime = System.currentTimeMillis(); try { model.updateGameState(timeElapsed); } catch (NullPointerException e) { log.error("Error in model physics, terminating game."); terminateFlag = true; break; } synchronized(controlPairs) { for(ControlPair pair : controlPairs) { RobotCommand command = model.getCurrentRobotCommand(pair.getRobotProxy().getIdentifier()); if(command != null) { pair.getRobotProxy().sendCommand(command); } } } if(!terminateFlag) { terminateFlag = model.checkGameOver(); } Thread.yield(); } lobby.broadcastMessage("<Server> Game terminating."); terminateGame(); } GameController(ServerLobby lobby, GameType gameType); void addPlayer(UserProxy player, RobotProxy robot); void addSpectator(UserProxy player); boolean isPlayer(UserProxy player); boolean isSpectator(UserProxy spectator); boolean isActiveRobot(RobotProxy robot); synchronized RobotProxy getPairedRobot(UserProxy player); @Override /** * Main loop of GameController (performs real-time physics updates on GameModel) */ void run(); void triggerTermination(); synchronized boolean isTerminating(); void processInput(UserProxy player, Vector<Float> orientation, String buttons); RobotCommand generateCommand(Vector<Float> orientation, String buttons, 
			ControlType controlType); void updateRobotPosition(RobotProxy robot, Posture newPosture); GameModel getGameModel(); void gameStateChanged(GameEvent event); static final float PITCH_SCALING_FACTOR; static final float ROLL_SCALING_FACTOR; static final float DOT_SPACING; static final int COLS; static final float STOP_THRESHOLD; }### Answer:
@Test public void testRun() { testController.addPlayer(user1, robot1); testController.addSpectator(user2); robot1.sendCommand(RobotCommand.setPosition(new Pose(2000, 2000, 0))); new Thread(testController).start(); robot1.sendCommand(RobotCommand.moveContinuous(5)); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } assertEquals(true, user1.getLastEvent() instanceof GameEvent); robot1.sendCommand(RobotCommand.stop()); user1.processGameplayCommand((float)0, (float)0, (float)0, "w"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } assertEquals(CommandType.MOVE_CONTINUOUS, robot1.getRobot().getLastCommand().getType()); robot1.sendCommand(RobotCommand.stop()); testController.triggerTermination(); assertEquals(true, testController.isTerminating()); try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } assertEquals(null, testController.getGameModel()); }