code: package tools;
  
  import java.util.ArrayList;
  
  import core.game.StateObservation;
  import core.player.AbstractPlayer;
  import ontology.Types;
  import ontology.Types.ACTIONS;
  
  public class StepController{
  	
  	/**
  	 * the selected agent to play the game
  	 */
  	private AbstractPlayer agent;
  	/**
  	 * the final state reached after playing
  	 */
  	private StateObservation finalState;
  	/**
  	 * list of all actions taken by the agent after playing the game
  	 */
  	private ArrayList<Types.ACTIONS> solution;
  	/**
  	 * the length of the time step used by the agent
  	 */
  	private long stepTime;
  	
  	/**
  	 * Initialize the Step Agent
  	 * @param agent		agent used to play the game
  	 * @param stepTime	amount of time spend for each step
  	 */
  	public StepController(AbstractPlayer agent, long stepTime){
  		this.stepTime = stepTime;
  		this.agent = agent;
  	}
  	
  	/**
  	 * play the current game for a specific amount of time using the initialized player
  	 * @param stateObs		starting observation object
  	 * @param elapsedTimer	amount of time that can be spent in this function
  	 */
  	public void playGame(StateObservation stateObs, ElapsedCpuTimer elapsedTimer) {
  		solution = new ArrayList<Types.ACTIONS>();
  		finalState = stateObs;
  		
  		while(elapsedTimer.remainingTimeMillis() > stepTime && !finalState.isGameOver()){
  			ElapsedCpuTimer timer = new ElapsedCpuTimer();
  			timer.setMaxTimeMillis(stepTime);
  			Types.ACTIONS action = agent.act(finalState.copy(), timer);
  			finalState.advance(action);
  			solution.add(action);
  		}
  	}
  	
  	/**
  	 * play the current game for a specific amount of time using the initialized player
  	 * @param stateObs		starting observation object
  	 * @param elapsedTimer	amount of time that can be spent in this function
  	 * @param SOs			List of stateobservations to be cached
  	 */
  	public void playGame(StateObservation stateObs, ElapsedCpuTimer elapsedTimer, ArrayList<Vector2d> SOs) {
  		solution = new ArrayList<Types.ACTIONS>();
  		finalState = stateObs;
  		
  		while(elapsedTimer.remainingTimeMillis() > stepTime && !finalState.isGameOver()){
  			ElapsedCpuTimer timer = new ElapsedCpuTimer();
  			timer.setMaxTimeMillis(stepTime);
  			Types.ACTIONS action = agent.act(finalState.copy(), timer);
  			finalState.advance(action);
  			if (finalState != null) {
  				SOs.add(new Vector2d(finalState.getAvatarPosition()));
  			}
  			solution.add(action);
  		}
  	}
  
  	/**
  	 * get list of action used during playing the game
  	 * @return	list of actions used during playing
  	 */
  	public ArrayList<ACTIONS> getSolution() {
  		return solution;
  	}
  
  	/**
  	 * called after playing a game and return the final game state reached
  	 * @return	game state after playing the game
  	 */
  	public StateObservation getFinalState() {
  		return finalState;
  	}
  }
  