Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2069 removed unused symbols and cleaned up code

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