Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Robocode/HeuristicLab.Problems.Robocode/Interpreter.cs @ 13003

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

#2069

  • fixed error handling for external program calls
  • added missing StorableClass attribute
File size: 18.8 KB
Line 
1using System;
2using System.Diagnostics;
3using System.IO;
4using System.Linq;
5using System.Text;
6using System.Xml;
7using HeuristicLab.Core;
8using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
9
10namespace HeuristicLab.Problems.Robocode {
11  public class Interpreter {
12
13    private struct TankStats {
14      public int moves, shots;
15      public TankStats(int moves, int shots) {
16        this.moves = moves;
17        this.shots = shots;
18      }
19    }
20    static string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
21
22    public static string BuildTankProgram(ISymbolicExpressionTree tree) {
23      XmlDocument solutionCandidateRoot = new XmlDocument();
24      solutionCandidateRoot.Load("../tank.xml");
25
26      TankStats tankStats = EvaluateTankProgram(tree.Root, solutionCandidateRoot.FirstChild, null);
27      return solutionCandidateRoot.InnerText;
28    }
29
30    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, XmlNode solutionCandidateRoot, string path) {
31      //TankStats tankStats = EvaluateTankProgram(tree.Root, solutionCandidateRoot, null);
32      //Evaluator.tankStatLog += "\r\n" + tankStats.shots + " / " + tankStats.moves;
33      string interpretedProgram = InterpretProgramTree(tree.Root);
34      Random random = new Random();
35      string formattedPath = path.Replace("/", "\\");
36      string outputname = "";
37      string output = "";
38      bool noError = true;
39      do {
40        try {
41          outputname = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
42          output = /*solutionCandidateRoot.InnerText*/interpretedProgram.Replace("class output", "class " + outputname);
43          File.WriteAllText(path + "/robots/Evaluation/" + outputname + ".java", output, System.Text.Encoding.Default);
44          noError = true;
45        }
46        catch (Exception e) { noError = false; }
47      } while (!noError);
48
49      //string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
50      //path.Replace("\\", "\\\\");
51      //path.Replace(" ", "\\ ");
52      #region Compile code file
53
54      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
55      javaCompileInfo.FileName = "cmd.exe";
56      javaCompileInfo.Arguments = "/C javac -cp " + formattedPath + "\\libs\\robocode.jar " + formattedPath + "\\robots\\Evaluation\\" + outputname + ".java";
57      javaCompileInfo.RedirectStandardOutput = true;
58      javaCompileInfo.RedirectStandardError = true;
59      javaCompileInfo.UseShellExecute = false;
60      javaCompileInfo.CreateNoWindow = true;
61
62      Process javaCompile = new Process();
63      javaCompile.StartInfo = javaCompileInfo;
64      javaCompile.Start();
65
66      /*Evaluator.tankStatLog = "=====================================================\r\n";
67      Evaluator.tankStatLog += "Tree Compilation Output: \r\n";
68      Evaluator.tankStatLog += "=====================================================\r\n";*/
69
70      string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
71      cmdOutput += javaCompile.StandardError.ReadToEnd();
72
73      //Evaluator.tankStatLog += cmdOutput;
74      //Console.WriteLine(cmdOutput);
75      //Console.ReadLine();
76
77      /*Evaluator.tankStatLog = "=====================================================\r\n";
78      Evaluator.tankStatLog += "End of Tree Compilation Output: \r\n";
79      Evaluator.tankStatLog += "=====================================================\r\n";*/
80
81      javaCompile.WaitForExit();
82      if (javaCompile.ExitCode != 0) {
83        return -1000.0;
84      }
85      #endregion
86
87
88      try { File.Delete(path + "/robots/robot.database"); }
89      catch (Exception e) { }
90
91      #region evaluate code
92
93      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
94      evaluateCodeInfo.FileName = "cmd.exe";
95      //javaCompileInfo.Arguments = "/C javac -cp C:\\robocode\\libs\\robocode.jar \"" + path + "\\Spaced Up\\output.java\"";
96      evaluateCodeInfo.Arguments = "/C java -classpath " + formattedPath + "\\libs;" + formattedPath + "\\libs\\robocode.core-1.8.1.0.jar;" + formattedPath + "\\libs\\robocode.jar;" + formattedPath + "\\libs\\picocontainer-2.14.2.jar BattleRunner Evaluation." + outputname + "* false";
97      //Console.WriteLine(javaCompileInfo.Arguments);
98      evaluateCodeInfo.RedirectStandardOutput = true;
99      evaluateCodeInfo.RedirectStandardError = true;
100      evaluateCodeInfo.UseShellExecute = false;
101      evaluateCodeInfo.CreateNoWindow = true;
102
103      Process evaluateCode = new Process();
104      evaluateCode.StartInfo = evaluateCodeInfo;
105      evaluateCode.Start();
106
107      StringBuilder q = new StringBuilder();
108      string scoreString = "";
109      evaluateCode.WaitForExit();
110
111      try {
112        scoreString = evaluateCode.StandardOutput.ReadToEnd().Split(
113        new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Last();
114        q.Append("Output: " + scoreString + "\r\n");
115        q.Append("Error: " + evaluateCode.StandardError.ReadToEnd() + "\r\n");
116        cmdOutput += q.ToString();
117      }catch {
118        return -1000.0;
119      }
120
121      #endregion
122
123      double evaluation = -900;
124      try {
125        File.Delete(path + "/robots/Evaluation/" + outputname + ".java");
126        File.Delete(path + "/robots/Evaluation/" + outputname + ".class");
127        evaluation = Double.Parse(scoreString);
128      }
129      catch (Exception e) { evaluation = -900; }
130      Random rand = new Random();
131      evaluation += rand.NextDouble() / 100;
132
133      /*Evaluator.tankStatLog = "=====================================================\r\n";
134      Evaluator.tankStatLog += "START OF TREE - Score: " + evaluation + " (" + tankStats.shots + "/" + tankStats.moves + ")" + "\r\n" + " Compilation Output: " + cmdOutput + "\r\n";
135      Evaluator.tankStatLog += "=====================================================\r\n";
136
137      Evaluator.tankStatLog += solutionCandidateRoot.InnerText + "\r\n";
138
139      Evaluator.tankStatLog += "=====================================================\r\n";
140      Evaluator.tankStatLog += "END OF TREE\r\n";
141      Evaluator.tankStatLog += "=====================================================\r\n";
142
143      File.AppendAllText("../TankLog.txt", Evaluator.tankStatLog);*/
144      return evaluation;
145    }
146
147    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, ScopeList coevolutionIndividuals, XmlNode solutionCandidateRoot, string path) {
148      Random random = new Random();
149      string formattedPath = path.Replace("/", "\\");
150
151      // Interpret and compile main tree
152      //XmlNode mainTreeNode = solutionCandidateRoot.Clone();
153      //EvaluateTankProgram(tree.Root, mainTreeNode, null);
154      string interpretedMainTree = InterpretProgramTree(tree.Root);
155      string mainTreeName = writeTreeToFile(interpretedMainTree, path, random);
156      compileCodefile(/*mainTreeName,*/ mainTreeName, formattedPath);
157
158      // Interpret and compile coevolutionIndividuals
159      String[] coevolutionIndividualsNames = new String[coevolutionIndividuals.Count];
160      for (int i = 0; i < coevolutionIndividuals.Count; i++) {
161        //XmlNode individualTreeNode = solutionCandidateRoot.Clone();
162        //EvaluateTankProgram(((ISymbolicExpressionTree)coevolutionIndividuals[i].Variables.ToArray()[0].Value).Root, individualTreeNode, null);
163        string interpretedIndividual = InterpretProgramTree(((ISymbolicExpressionTree)coevolutionIndividuals[i].Variables.ToArray()[0].Value).Root);
164        coevolutionIndividualsNames[i] = writeTreeToFile(/*individualTreeNode,*/ interpretedIndividual, path, random);
165        compileCodefile(coevolutionIndividualsNames[i], formattedPath);
166      }
167
168      // Force Robocode to update its robot database by deleting the existing one
169      try { File.Delete(path + "/robots/robot.database"); }
170      catch (Exception e) { }
171
172      // Run evaluator
173      double evaluation = runEvaluator(mainTreeName, coevolutionIndividualsNames, formattedPath);
174      try {
175        File.Delete(path + "/robots/Evaluation/" + mainTreeName + ".java");
176        File.Delete(path + "/robots/Evaluation/" + mainTreeName + ".class");
177        foreach (string s in coevolutionIndividualsNames) {
178          File.Delete(path + "/robots/Evaluation/" + s + ".java");
179          File.Delete(path + "/robots/Evaluation/" + s + ".class");
180        }
181      }
182      catch (Exception e) { }
183      Random rand = new Random();
184      evaluation += rand.NextDouble() / 100;
185
186      return evaluation;
187    }
188
189    private static string writeTreeToFile(/*XmlNode node,*/ string interpretedTree, string path, Random random) {
190      string outputName = "";
191      string outputString = "";
192      bool noError = true;
193      do {
194        try {
195          outputName = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
196          outputString = /*node.InnerText*/interpretedTree.Replace("class output", "class " + outputName);
197          File.WriteAllText(path + "/robots/Evaluation/" + outputName + ".java", outputString, System.Text.Encoding.Default);
198          noError = true;
199        }
200        catch (Exception e) { noError = false; }
201      } while (!noError);
202
203      return outputName;
204    }
205
206    private static bool compileCodefile(string filename, string formattedPath) {
207      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
208      javaCompileInfo.FileName = "cmd.exe";
209      javaCompileInfo.Arguments = "/C javac -cp " + formattedPath + "\\libs\\robocode.jar " + formattedPath + "\\robots\\Evaluation\\" + filename + ".java";
210      javaCompileInfo.RedirectStandardOutput = true;
211      javaCompileInfo.RedirectStandardError = true;
212      javaCompileInfo.UseShellExecute = false;
213      javaCompileInfo.CreateNoWindow = true;
214
215      Process javaCompile = new Process();
216      javaCompile.StartInfo = javaCompileInfo;
217      javaCompile.Start();
218
219      string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
220      cmdOutput += javaCompile.StandardError.ReadToEnd();
221
222      javaCompile.WaitForExit();
223
224      if (cmdOutput.Equals(""))
225        return true;
226      return false;
227    }
228
229    private static double runEvaluator(string mainTreeFilename, string[] coevolutionIndividualsNames, string formattedPath) {
230      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
231      evaluateCodeInfo.FileName = "cmd.exe";
232      //javaCompileInfo.Arguments = "/C javac -cp C:\\robocode\\libs\\robocode.jar \"" + path + "\\Spaced Up\\output.java\"";
233      evaluateCodeInfo.Arguments = "/C java -classpath " + formattedPath + "\\libs;" + formattedPath + "\\libs\\robocode.core-1.8.1.0.jar;" + formattedPath + "\\libs\\robocode.jar;" + formattedPath + "\\libs\\picocontainer-2.14.2.jar BattleRunner Evaluation." + mainTreeFilename + "* ";
234      if (coevolutionIndividualsNames != null) {
235        foreach (string s in coevolutionIndividualsNames)
236          evaluateCodeInfo.Arguments += "Evaluation." + s + "* ";
237      } else
238        evaluateCodeInfo.Arguments += "false";
239      //Console.WriteLine(javaCompileInfo.Arguments);
240      evaluateCodeInfo.RedirectStandardOutput = true;
241      evaluateCodeInfo.RedirectStandardError = true;
242      evaluateCodeInfo.UseShellExecute = false;
243      evaluateCodeInfo.CreateNoWindow = true;
244
245      Process evaluateCode = new Process();
246      evaluateCode.StartInfo = evaluateCodeInfo;
247      evaluateCode.Start();
248
249      StringBuilder q = new StringBuilder();
250      string scoreString = "";
251      while (!evaluateCode.HasExited) {
252        scoreString = evaluateCode.StandardOutput.ReadToEnd().Split(
253        new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Last();
254        q.Append("Output: " + scoreString + "\r\n");
255        q.Append("Error: " + evaluateCode.StandardError.ReadToEnd() + "\r\n");
256      }
257      string cmdOutput = q.ToString();
258      try {
259        double evaluation = Double.Parse(scoreString);
260        return evaluation;
261      }
262      catch (Exception e) { }
263
264      return -900;
265    }
266
267    private static TankStats EvaluateTankProgram(ISymbolicExpressionTreeNode node, XmlNode docNode, string method) {
268      TankStats tankStats = new TankStats(0, 0);
269
270      //string log = "Doing node: \r\n";
271      /*if (node.Symbol is ProgramRootSymbol ||
272          node.Symbol is StartSymbol)
273          tankStats = EvaluateTankProgram(node.GetSubtree(0), ref docNode, null);
274      else*/
275      if (node.Symbol is Constant)
276        docNode[method]["code"].InnerText += " " + ((ConstantTreeNode)node).Value + " ";
277      else if (node.Symbol is ShotPower)
278        docNode[method]["code"].InnerText += " " + ((ShotPowerTreeNode)node).Value + " ";
279      else if (node.Symbol is LogicalValue)
280        docNode[method]["code"].InnerText += " " + ((BooleanTreeNode)node).Value.ToString().ToLower() + " ";
281      else if (node.Symbol is Block) {
282        docNode[method]["code"].InnerText += "{\r\n";
283        foreach (ISymbolicExpressionTreeNode n in node.Subtrees)
284          EvaluateTankProgram(n, docNode, method);
285        docNode[method]["code"].InnerText += "}\r\n";
286      } else if (node.Symbol is IfStatement) {
287        docNode[method]["code"].InnerText += "if(";
288        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
289        docNode[method]["code"].InnerText += ")\r\n";
290        EvaluateTankProgram(node.GetSubtree(1), docNode, method);
291        if (node.SubtreeCount == 3)
292          EvaluateTankProgram(node.GetSubtree(2), docNode, method);
293      } else if (node.Symbol is ElseStatement) {
294        docNode[method]["code"].InnerText += "else\r\n";
295        if (node.SubtreeCount == 1)
296          EvaluateTankProgram(node.GetSubtree(0), docNode, method);
297      } else if (node.Symbol is WhileLoop) {
298        docNode[method]["code"].InnerText += "While(";
299        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
300        docNode[method]["code"].InnerText += ")\r\n";
301        EvaluateTankProgram(node.GetSubtree(1), docNode, method);
302      } else if (node.Symbol is Ahead) {
303        docNode[method]["code"].InnerText += "setAhead(";
304        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
305        docNode[method]["code"].InnerText += ");\r\n";
306        tankStats.moves = 1;
307      } else if (node.Symbol is Back) {
308        docNode[method]["code"].InnerText += "setBack(";
309        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
310        docNode[method]["code"].InnerText += ");\r\n";
311        tankStats.moves = 1;
312      } else if (node.Symbol is SetAdjustGunForRobotTurn) {
313        docNode[method]["code"].InnerText += "setAdjustGunForRobotTurn(";
314        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
315        docNode[method]["code"].InnerText += ");\r\n";
316        tankStats.moves = 1;
317      } else if (node.Symbol is SetAdjustRadarForGunTurn) {
318        docNode[method]["code"].InnerText += "setAdjustRadarForGunTurn(";
319        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
320        docNode[method]["code"].InnerText += ");\r\n";
321        tankStats.moves = 1;
322      } else if (node.Symbol is SetAdjustRadarForRobotTurn) {
323        docNode[method]["code"].InnerText += "setAdjustRadarForRobotTurn(";
324        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
325        docNode[method]["code"].InnerText += ");\r\n";
326        tankStats.moves = 1;
327      } else if (node.Symbol is TurnGunLeft) {
328        docNode[method]["code"].InnerText += "setTurnGunLeft(";
329        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
330        docNode[method]["code"].InnerText += ");\r\n";
331        tankStats.moves = 1;
332      } else if (node.Symbol is TurnGunRight) {
333        docNode[method]["code"].InnerText += "setTurnGunRight(";
334        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
335        docNode[method]["code"].InnerText += ");\r\n";
336        tankStats.moves = 1;
337      } else if (node.Symbol is TurnLeft) {
338        docNode[method]["code"].InnerText += "setTurnLeft(";
339        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
340        docNode[method]["code"].InnerText += ");\r\n";
341        tankStats.moves = 1;
342      } else if (node.Symbol is TurnRadarLeft) {
343        docNode[method]["code"].InnerText += "setTurnRadarLeft(";
344        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
345        docNode[method]["code"].InnerText += ");\r\n";
346        tankStats.moves = 1;
347      } else if (node.Symbol is TurnRadarRight) {
348        docNode[method]["code"].InnerText += "setTurnRadarRight(";
349        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
350        docNode[method]["code"].InnerText += ");\r\n";
351        tankStats.moves = 1;
352      } else if (node.Symbol is TurnRight) {
353        docNode[method]["code"].InnerText += "setTurnRight(";
354        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
355        docNode[method]["code"].InnerText += ");\r\n";
356        tankStats.moves = 1;
357      } else if (node.Symbol is Fire) {
358        docNode[method]["code"].InnerText += "setFire(";
359        EvaluateTankProgram(node.GetSubtree(0), docNode, method);
360        docNode[method]["code"].InnerText += ");\r\n";
361        tankStats.shots = 1;
362      } else if (node.Symbol is Run ||
363            node.Symbol is OnBulletHit ||
364            node.Symbol is OnBulletMissed ||
365            node.Symbol is OnHitByBullet ||
366            node.Symbol is OnHitRobot ||
367            node.Symbol is OnHitWall ||
368            node.Symbol is OnScannedRobot) {
369        tankStats = new TankStats();
370        foreach (SymbolicExpressionTreeNode n in node.Subtrees) {
371          string methodName = node.Symbol.GetType().ToString().Split('.').Last();
372          try {
373            var tempStats = EvaluateTankProgram(n, docNode, methodName);
374            tankStats.moves += tempStats.moves;
375            tankStats.shots += tempStats.shots;
376          }
377          catch (Exception e) {
378            //log += "NULL EXCEPTION ON:::::::: -" + methodName + "-\r\n";
379            //foreach (XmlNode f in docNode[methodName])
380            //    log += f.Name + "\r\n";
381          }
382        }
383      } else if (node.Symbol is Tank) {
384        foreach (SymbolicExpressionTreeNode n in node.Subtrees) {
385          try {
386            var tempStats = EvaluateTankProgram(n, docNode, method);
387            tankStats.moves += tempStats.moves;
388            tankStats.shots += tempStats.shots;
389          }
390          catch (Exception e) { }
391        }
392      } else
393        tankStats = EvaluateTankProgram(node.GetSubtree(0), docNode, null);
394
395      //log += tankStats.shots + " / " + tankStats.moves + "\r\n";
396      //File.AppendAllText("../TankLog.txt", log);
397
398      return tankStats;
399    }
400
401    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node) {
402      var tankNode = node;
403      while (!(tankNode.Symbol is Tank))
404        tankNode = tankNode.GetSubtree(0);
405      return ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);
406    }
407  }
408}
Note: See TracBrowser for help on using the repository browser.