package org.ggp.base.validator;

import org.ggp.base.util.game.Game;
import org.ggp.base.util.statemachine.MachineState;
import org.ggp.base.util.statemachine.StateMachine;
import org.ggp.base.util.statemachine.exceptions.MoveDefinitionException;
import org.ggp.base.util.statemachine.exceptions.TransitionDefinitionException;
import org.ggp.base.util.statemachine.implementation.prover.ProverStateMachine;

public final class SimulationValidator implements Validator
{
	private final int maxDepth;
	private final int numSimulations;

	public SimulationValidator(int maxDepth, int numSimulations)
	{
		this.maxDepth = maxDepth;
		this.numSimulations = numSimulations;
	}

	@Override
	public void checkValidity(Game theGame) throws ValidatorException {
		for (int i = 0; i < numSimulations; i++)
		{
			StateMachine stateMachine = new ProverStateMachine();
			stateMachine.initialize(theGame.getRules());

			MachineState state = stateMachine.getInitialState();
			for (int depth = 0; !stateMachine.isTerminal(state); depth++)
			{
				if (depth == maxDepth) {
					throw new ValidatorException("Hit max depth while simulating: " + maxDepth);
				}

				try {
					state = stateMachine.getRandomNextState(state);
				} catch (MoveDefinitionException mde) {
					throw new ValidatorException("Could not find legal moves while simulating: " + mde);
				} catch (TransitionDefinitionException tde) {
					throw new ValidatorException("Could not find transition definition while simulating: " + tde);
				}
			}

		}
	}
}

package org.ggp.base.validator;

import org.ggp.base.util.game.Game;
import org.ggp.base.util.statemachine.MachineState;
import org.ggp.base.util.statemachine.StateMachine;
import org.ggp.base.util.statemachine.exceptions.GoalDefinitionException;
import org.ggp.base.util.statemachine.exceptions.MoveDefinitionException;
import org.ggp.base.util.statemachine.exceptions.TransitionDefinitionException;
import org.ggp.base.util.statemachine.implementation.prover.ProverStateMachine;

public final class SimulationValidator implements Validator
{
	private final int maxDepth;
	private final int numSimulations;

	public SimulationValidator(int maxDepth, int numSimulations)
	{
		this.maxDepth = maxDepth;
		this.numSimulations = numSimulations;
	}

	@Override
	public void checkValidity(Game theGame) throws ValidatorException {
		for (int i = 0; i < numSimulations; i++) {
			StateMachine stateMachine = new ProverStateMachine();
			stateMachine.initialize(theGame.getRules());

			MachineState state = stateMachine.getInitialState();
			for (int depth = 0; !stateMachine.isTerminal(state); depth++) {
				if (depth == maxDepth) {
					throw new ValidatorException("Hit max depth while simulating: " + maxDepth);
				}
				try {
					state = stateMachine.getRandomNextState(state);
				} catch (MoveDefinitionException mde) {
					throw new ValidatorException("Could not find legal moves while simulating: " + mde);
				} catch (TransitionDefinitionException tde) {
					throw new ValidatorException("Could not find transition definition while simulating: " + tde);
				}
			}

			try {
				stateMachine.getGoals(state);
			} catch (GoalDefinitionException gde) {
				throw new ValidatorException("Could not find goals while simulating: " + gde);
			}
		}
	}
}

Check for goal values in terminal states when doing simulation-based validation.