package cecj.eval;

import ec.EvolutionState;
import ec.Individual;
import ec.util.Parameter;
import games.ec.TDLImprover;

public class TDLImprovingEvaluator extends CoevolutionaryEvaluator {

	private static final String P_INNER_EVALUATOR = "inner-evaluator";
	private static final String P_TDL_IMPROVER = "tdl-improver";

	private CoevolutionaryEvaluator innerEvaluator;
	private TDLImprover temporalDifferenceImprover;
	private boolean firstEvaluation = true;
	
	@Override
	public void setup(EvolutionState state, Parameter base) {
		super.setup(state, base);

		Parameter innerEvaluatorParam = base.push(P_INNER_EVALUATOR);
		innerEvaluator = (CoevolutionaryEvaluator) (state.parameters
			.getInstanceForParameter(innerEvaluatorParam, null, CoevolutionaryEvaluator.class));
		innerEvaluator.setup(state, innerEvaluatorParam);

		Parameter tdlImproverParam = base.push(P_TDL_IMPROVER);
		temporalDifferenceImprover = (TDLImprover) (state.parameters
			.getInstanceForParameter(tdlImproverParam, null, TDLImprover.class));
		temporalDifferenceImprover.setup(state, tdlImproverParam);
	}

	@Override
	public void evaluatePopulation(EvolutionState state) {
		if (firstEvaluation) {
			for (int subpop = 0; subpop < numSubpopulations; subpop++) {
				Individual[] inds = state.population.subpops[subpop].individuals;
				for (Individual ind : inds) {
					temporalDifferenceImprover.prepareForImproving(state, ind);
				}
			}
			firstEvaluation = false;
		}
		
		for (int subpop = 0; subpop < numSubpopulations; subpop++) {
			Individual[] inds = state.population.subpops[subpop].individuals;
			for (Individual ind : inds) {
				temporalDifferenceImprover.improve(state, ind);
			}
		}

		innerEvaluator.evaluatePopulation(state);
	}
}
