using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; using System; using System.IO; using System.Threading; using System.Xml; namespace HeuristicLab.Problems.Robocode { [StorableClass] [Item("Robocode Evaluator", "Evaluator for the Robocode GP problem.")] public class Evaluator : SingleSuccessorOperator, ISingleObjectiveEvaluator { #region parameter names private const string QualityParameterName = "Quality"; private const string TankProgramParameterName = "TankProgram"; private const string RobocodePathParamaterName = "Path"; private const string CoevolutionParameterName = "Coevolution"; private static string solutionTemplatePath = ""; public static string SolutionTemplate { get { return solutionTemplatePath; } set { solutionTemplatePath = value; } } public static SemaphoreSlim semaphore = new SemaphoreSlim(10); #endregion #region parameters public ILookupParameter QualityParameter { get { return (ILookupParameter) Parameters[QualityParameterName]; } } public ILookupParameter TankProgramParameter { get { return (ILookupParameter) Parameters[TankProgramParameterName]; } } public ILookupParameter RobocodePathParameter { get { return (ILookupParameter) Parameters[RobocodePathParamaterName]; } } public ILookupParameter CoevolutionParameter { get { return (ILookupParameter) Parameters[CoevolutionParameterName]; } } #endregion [StorableConstructor] protected Evaluator(bool deserializing) : base(deserializing) { } protected Evaluator(Evaluator original, Cloner cloner) : base(original, cloner) { } // default constructor for the evaluator public Evaluator() { Parameters.Add( new LookupParameter( QualityParameterName, "The solution quality of the Robocode tank program.")); Parameters.Add( new LookupParameter( TankProgramParameterName, "The Robocode tank program to evaluate represented as a " + "symbolic expression tree.")); Parameters.Add( new LookupParameter( RobocodePathParamaterName, "Path of the Robocode installation.")); Parameters.Add( new LookupParameter( CoevolutionParameterName, "Use Coevolution")); SolutionTemplate = "../tank.xml"; } // override the apply method to change the behaviour of the operator // here we take trees as inputs and calculate qualities // (fitness evaluation) public override IOperation Apply() { semaphore.Wait(); ISymbolicExpressionTree tree = TankProgramParameter.ActualValue; //XmlDocument doc = new XmlDocument(); //doc.Load("../tank.xml"); XmlNode node = null; string path = RobocodePathParameter.ActualValue.Value; if (CoevolutionParameter.ActualValue.Value) { var trees = ExecutionContext.Parent.Scope.SubScopes;//SymbolicExpressionTreeParameter.ActualValue; if (trees.Count == 2) { trees = trees[0].SubScopes; //treeCount = trees[0].SubScopes.Count; //int selTreeCount = trees[1].SubScopes.Count; } Random random = new Random(); ScopeList chosenScopes = new ScopeList(5); for (int i = 0; i < 5; i++) { var newScope = trees.ToArray()[random.Next(0, trees.Count - 1)]; chosenScopes.Add(newScope); } //if (evaluations % 99 == 0) // evaluations = evaluations; QualityParameter.ActualValue = new DoubleValue(Interpreter.EvaluateTankProgram(tree, chosenScopes, node, path)); } else QualityParameter.ActualValue = new DoubleValue(Interpreter.EvaluateTankProgram(tree, node, path)); semaphore.Release(); // important: return base.Apply() to make sure that the // next operator is queued for execution return base.Apply(); } public override IDeepCloneable Clone(Cloner cloner) { return new Evaluator(this, cloner); } public bool EnabledByDefault { get { return true; } } } }