Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Robocode.TrunkInt/HeuristicLab.Problems.Robocode/3.3/Interpreter.cs @ 9926

Last change on this file since 9926 was 9926, checked in by ascheibe, 11 years ago

#2069

  • renamed path parameter to robocode path
  • made number of rounds configurable
File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Diagnostics;
24using System.Globalization;
25using System.IO;
26using System.Linq;
27using System.Reflection;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29
30namespace HeuristicLab.Problems.Robocode {
31  public static class Interpreter {
32    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, string robotName = null, bool showUI = false, int nrOfRounds = 3) {
33      if (robotName == null)
34        robotName = GenerateRobotName();
35
36      string interpretedProgram = InterpretProgramTree(tree.Root, robotName);
37      string battleRunnerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
38      string roboCodeLibPath = Path.Combine(path, "libs");
39      string robocodeJar = Path.Combine(roboCodeLibPath, "robocode.jar");
40      string robocodeCoreJar = GetFileName(roboCodeLibPath, "robocode.core*");
41      string picocontainerJar = GetFileName(roboCodeLibPath, "picocontainer*");
42      string robotsPath = Path.Combine(path, "robots", "Evaluation");
43      string srcRobotPath = Path.Combine(robotsPath, robotName + ".java");
44
45      File.WriteAllText(srcRobotPath, interpretedProgram, System.Text.Encoding.Default);
46
47      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
48      javaCompileInfo.FileName = "cmd.exe";
49      javaCompileInfo.Arguments = "/C javac -cp " + robocodeJar + "; " + srcRobotPath;
50      javaCompileInfo.RedirectStandardOutput = true;
51      javaCompileInfo.RedirectStandardError = true;
52      javaCompileInfo.UseShellExecute = false;
53      javaCompileInfo.CreateNoWindow = true;
54
55      Process javaCompile = new Process();
56      javaCompile.StartInfo = javaCompileInfo;
57      javaCompile.Start();
58
59      string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
60      cmdOutput += javaCompile.StandardError.ReadToEnd();
61
62      javaCompile.WaitForExit();
63      if (javaCompile.ExitCode != 0) {
64        DeleteRobotFiles(path, robotName);
65        throw new Exception("Compile Error: " + cmdOutput);
66      }
67
68      //parallel execution of multiple robocode instances can sometimes lead to a damaged robot.database
69      try { File.Delete(path + @"\robots\robot.database"); }
70      catch { }
71
72      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
73
74      evaluateCodeInfo.FileName = "cmd.exe";
75      evaluateCodeInfo.Arguments = "/C java -cp " + battleRunnerPath + ";" + robocodeCoreJar + ";" + robocodeJar +
76                                  ";" + picocontainerJar + ";" + " BattleRunner Evaluation." + robotName + "* " + path;
77
78      if (showUI) {
79        evaluateCodeInfo.Arguments += " true " + nrOfRounds;
80      } else {
81        evaluateCodeInfo.Arguments += " false " + nrOfRounds;
82      }
83
84      evaluateCodeInfo.RedirectStandardOutput = true;
85      evaluateCodeInfo.RedirectStandardError = true;
86      evaluateCodeInfo.UseShellExecute = false;
87      evaluateCodeInfo.CreateNoWindow = true;
88
89      Process evaluateCode = new Process();
90      evaluateCode.StartInfo = evaluateCodeInfo;
91      evaluateCode.Start();
92      evaluateCode.WaitForExit();
93
94      if (evaluateCode.ExitCode != 0) {
95        DeleteRobotFiles(path, robotName);
96        throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd());
97      }
98
99      string scoreString = "";
100      double evaluation = -1.0;
101      try {
102        scoreString = evaluateCode.StandardOutput.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Last();
103        evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
104      }
105      catch (Exception ex) {
106        throw new Exception("Error parsing score string: " + ex.ToString());
107      }
108      finally {
109        DeleteRobotFiles(path, robotName);
110      }
111
112      return evaluation;
113    }
114
115    private static void DeleteRobotFiles(string path, string outputname) {
116      try {
117        File.Delete(path + @"\robots\Evaluation\" + outputname + ".java");
118        File.Delete(path + @"\robots\Evaluation\" + outputname + ".class");
119      }
120      catch { }
121    }
122
123    private static string GetFileName(string path, string pattern) {
124      string fileName = string.Empty;
125      try {
126        fileName = Directory.GetFiles(path, pattern).First();
127      }
128      catch {
129        throw new Exception("Error finding required RoboCode files.");
130      }
131      return fileName;
132    }
133
134    private static string GenerateRobotName() {
135      // Robocode class names are 32 char max and
136      // Java class names have to start with a letter
137      string outputname = Guid.NewGuid().ToString();
138      outputname = outputname.Remove(8, 1);
139      outputname = outputname.Remove(12, 1);
140      outputname = outputname.Remove(16, 1);
141      outputname = outputname.Remove(20, 1);
142      outputname = outputname.Remove(0, 1);
143      outputname = outputname.Insert(0, "R");
144      return outputname;
145    }
146
147    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) {
148      var tankNode = node;
149      while (!(tankNode.Symbol is Tank))
150        tankNode = tankNode.GetSubtree(0);
151
152      string result = ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);
153      result = result.Replace("class output", "class " + robotName);
154      return result;
155    }
156  }
157}
Note: See TracBrowser for help on using the repository browser.