Esempio n. 1
0
        public Problem()
            : base()
        {
            DirectoryValue robocodeDir = new DirectoryValue {
                Value = @"robocode"
            };

            var robotList = EnemyCollection.ReloadEnemies(robocodeDir.Value);

            robotList.RobocodePath = robocodeDir.Value;


            Parameters.Add(new FixedValueParameter <DirectoryValue>(RobocodePathParamaterName, "Path of the Robocode installation.", robocodeDir));
            Parameters.Add(new FixedValueParameter <IntValue>(NrOfRoundsParameterName, "Number of rounds a robot has to fight against each opponent.", new IntValue(3)));
            Parameters.Add(new ValueParameter <EnemyCollection>(EnemiesParameterName, "The enemies that should be battled.", robotList));

            Encoding = new SymbolicExpressionTreeEncoding(new Grammar(), 1000, 10);
            Encoding.FunctionArguments   = 0;
            Encoding.FunctionDefinitions = 0;

            RegisterEventHandlers();
        }
Esempio n. 2
0
        public static EnemyCollection ReloadEnemies(string robocodeDir)
        {
            EnemyCollection robotList = new EnemyCollection();

            try {
                var robotsDir  = new DirectoryInfo(Path.Combine(robocodeDir, "robots"));
                var robotFiles = robotsDir.GetFiles("*", SearchOption.AllDirectories)
                                 .Where(x => x.Extension == ".class" || x.Extension == ".jar");
                var robotSet = new Dictionary <string, StringValue>();
                foreach (var robot in robotFiles)
                {
                    string robotName = Path.Combine(robot.DirectoryName, Path.GetFileNameWithoutExtension(robot.FullName));
                    robotName = robotName.Remove(0, robotsDir.FullName.Length);
                    string[] nameParts = robotName.Split(new[] { Path.DirectorySeparatorChar },
                                                         StringSplitOptions.RemoveEmptyEntries);
                    robotName = string.Join(".", nameParts);
                    robotSet[robot.FullName] = new StringValue(robotName);
                }
                robotList.AddRange(robotSet.Values);

                foreach (var robot in robotList)
                {
                    robotList.SetItemCheckedState(robot, false);
                }
            }
            catch { }

            //select one robot so that if a user tries out the Robocode problem it works with the default settings
            if (robotList.Exists(x => x.Value == sampleRobotToSelect))
            {
                StringValue sampleRobot = robotList.Single(x => x.Value == sampleRobotToSelect);
                robotList.SetItemCheckedState(sampleRobot, true);
            }

            return(robotList);
        }
Esempio n. 3
0
 protected EnemyCollection(EnemyCollection original, Cloner cloner)
     : base(original, cloner)
 {
     RobocodePath = original.RobocodePath;
 }
Esempio n. 4
0
        // TODO performance: it would probably be useful to implement the BattleRunner in such a way that we don't have to restart the java process each time, e.g. using console IO to load & run robots
        public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3)
        {
            if (robotName == null)
            {
                robotName = GenerateRobotName();
            }

            string interpretedProgram = InterpretProgramTree(tree.Root, robotName);
            string battleRunnerPath   = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "robocode");
            string roboCodeLibPath    = Path.Combine(path, "libs");
            string robocodeJar        = Path.Combine(roboCodeLibPath, "robocode.jar");
            string robocodeCoreJar    = GetFileName(roboCodeLibPath, "robocode.core*");
            string picocontainerJar   = GetFileName(roboCodeLibPath, "picocontainer*");
            string robotsPath         = Path.Combine(path, "robots", "Evaluation");
            string srcRobotPath       = Path.Combine(robotsPath, robotName + ".java");

            File.WriteAllText(srcRobotPath, interpretedProgram, System.Text.Encoding.Default);

            // compile java source to class file
            ProcessStartInfo javaCompileInfo = new ProcessStartInfo();

            javaCompileInfo.FileName  = "cmd.exe";
            javaCompileInfo.Arguments = "/C javac -cp " + robocodeJar + "; " + srcRobotPath;
            javaCompileInfo.RedirectStandardOutput = true;
            javaCompileInfo.RedirectStandardError  = true;
            javaCompileInfo.UseShellExecute        = false;
            javaCompileInfo.CreateNoWindow         = true;

            // it's ok to compile multiple robocode programs concurrently
            using (Process javaCompile = new Process()) {
                javaCompile.StartInfo = javaCompileInfo;
                javaCompile.Start();

                string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
                cmdOutput += javaCompile.StandardError.ReadToEnd();

                javaCompile.WaitForExit();
                if (javaCompile.ExitCode != 0)
                {
                    DeleteRobotFiles(path, robotName);
                    throw new Exception("Compile Error: " + cmdOutput);
                }
            }

            ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();

            // execute a battle with numberOfRounds against a number of enemies
            // TODO: seems there is a bug when selecting multiple enemies
            evaluateCodeInfo.FileName = "cmd.exe";
            var classpath       = string.Join(";", new[] { battleRunnerPath, robocodeCoreJar, robocodeJar, picocontainerJar });
            var enemyRobotNames = string.Join(" ", enemies.CheckedItems.Select(i => i.Value));

            evaluateCodeInfo.Arguments = string.Format("/C java -cp {0} BattleRunner Evaluation.{1} {2} {3} {4} {5}", classpath, robotName, path, showUI, nrOfRounds, enemyRobotNames);

            evaluateCodeInfo.RedirectStandardOutput = true;
            evaluateCodeInfo.RedirectStandardError  = true;
            evaluateCodeInfo.UseShellExecute        = false;
            evaluateCodeInfo.CreateNoWindow         = true;

            // the robocode framework writes state to a file therefore parallel evaluation of multiple robocode programs is not possible yet.
            double evaluation;

            lock (syncRoot) {
                using (Process evaluateCode = new Process()) {
                    evaluateCode.StartInfo = evaluateCodeInfo;
                    evaluateCode.Start();
                    evaluateCode.WaitForExit();

                    if (evaluateCode.ExitCode != 0)
                    {
                        DeleteRobotFiles(path, robotName);
                        throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd() +
                                            Environment.NewLine +
                                            evaluateCode.StandardOutput.ReadToEnd());
                    }

                    try {
                        string scoreString =
                            evaluateCode.StandardOutput.ReadToEnd()
                            .Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                            .Last();
                        evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
                    }
                    catch (Exception ex) {
                        throw new Exception("Error parsing score string: " + ex);
                    }
                    finally {
                        DeleteRobotFiles(path, robotName);
                    }
                }
            }

            return(evaluation);
        }