Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2069 added automatic discovery of robocode jars

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 class Interpreter {
32    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, string robotName = null, bool showUI = false) {
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      try {
46        File.WriteAllText(srcRobotPath, interpretedProgram, System.Text.Encoding.Default);
47      }
48      catch (Exception ex) {
49        throw;
50      }
51
52      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
53      javaCompileInfo.FileName = "cmd.exe";
54      javaCompileInfo.Arguments = "/C javac -cp " + robocodeJar + "; " + srcRobotPath;
55      javaCompileInfo.RedirectStandardOutput = true;
56      javaCompileInfo.RedirectStandardError = true;
57      javaCompileInfo.UseShellExecute = false;
58      javaCompileInfo.CreateNoWindow = true;
59
60      Process javaCompile = new Process();
61      javaCompile.StartInfo = javaCompileInfo;
62      javaCompile.Start();
63
64      string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
65      cmdOutput += javaCompile.StandardError.ReadToEnd();
66
67      javaCompile.WaitForExit();
68      if (javaCompile.ExitCode != 0) {
69        DeleteRobotFiles(path, robotName);
70        throw new Exception("Compile Error: " + cmdOutput);
71      }
72
73      //parallel execution of multiple robocode instances can sometimes lead to a damaged robot.database
74      try { File.Delete(path + @"\robots\robot.database"); }
75      catch { }
76
77      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
78
79      evaluateCodeInfo.FileName = "cmd.exe";
80      evaluateCodeInfo.Arguments = "/C java -cp " + battleRunnerPath + ";" + robocodeCoreJar + ";" + robocodeJar +
81                                  ";" + picocontainerJar + ";" + " BattleRunner Evaluation." + robotName + "* " + path;
82
83      if (showUI)
84        evaluateCodeInfo.Arguments += " true";
85
86      evaluateCodeInfo.RedirectStandardOutput = true;
87      evaluateCodeInfo.RedirectStandardError = true;
88      evaluateCodeInfo.UseShellExecute = false;
89      evaluateCodeInfo.CreateNoWindow = true;
90
91      Process evaluateCode = new Process();
92      evaluateCode.StartInfo = evaluateCodeInfo;
93      evaluateCode.Start();
94      evaluateCode.WaitForExit();
95
96      if (evaluateCode.ExitCode != 0) {
97        DeleteRobotFiles(path, robotName);
98        throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd());
99      }
100
101      string scoreString = "";
102      double evaluation = -1.0;
103      try {
104        scoreString = evaluateCode.StandardOutput.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Last();
105        evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
106      }
107      catch (Exception ex) {
108        throw new Exception("Error parsing score string: " + ex.ToString());
109      }
110      finally {
111        DeleteRobotFiles(path, robotName);
112      }
113
114      return evaluation;
115    }
116
117    private static void DeleteRobotFiles(string path, string outputname) {
118      try {
119        File.Delete(path + @"\robots\Evaluation\" + outputname + ".java");
120        File.Delete(path + @"\robots\Evaluation\" + outputname + ".class");
121      }
122      catch { }
123    }
124
125    private static string GetFileName(string path, string pattern) {
126      string fileName = string.Empty;
127      try {
128        fileName = Directory.GetFiles(path, pattern).First();
129      }
130      catch {
131        throw new Exception("Error finding required RoboCode files.");
132      }
133      return fileName;
134    }
135
136    private static string GenerateRobotName() {
137      // Robocode class names are 32 char max and
138      // Java class names have to start with a letter
139      string outputname = Guid.NewGuid().ToString();
140      outputname = outputname.Remove(8, 1);
141      outputname = outputname.Remove(12, 1);
142      outputname = outputname.Remove(16, 1);
143      outputname = outputname.Remove(20, 1);
144      outputname = outputname.Remove(0, 1);
145      outputname = outputname.Insert(0, "R");
146      return outputname;
147    }
148
149    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) {
150      var tankNode = node;
151      while (!(tankNode.Symbol is Tank))
152        tankNode = tankNode.GetSubtree(0);
153
154      string result = ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);
155      result = result.Replace("class output", "class " + robotName);
156      return result;
157    }
158  }
159}
Note: See TracBrowser for help on using the repository browser.