Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2069 added a view for displaying/reloading enemies

File size: 6.3 KB
RevLine 
[9790]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;
[9601]23using System.Diagnostics;
[9888]24using System.Globalization;
[9601]25using System.IO;
[9565]26using System.Linq;
[9891]27using System.Reflection;
[9947]28using HeuristicLab.Core;
29using HeuristicLab.Data;
[9601]30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
[9565]31
[9601]32namespace HeuristicLab.Problems.Robocode {
[9926]33  public static class Interpreter {
[9971]34    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3) {
[9889]35      if (robotName == null)
36        robotName = GenerateRobotName();
37
38      string interpretedProgram = InterpretProgramTree(tree.Root, robotName);
[9891]39      string battleRunnerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
[9898]40      string roboCodeLibPath = Path.Combine(path, "libs");
41      string robocodeJar = Path.Combine(roboCodeLibPath, "robocode.jar");
42      string robocodeCoreJar = GetFileName(roboCodeLibPath, "robocode.core*");
43      string picocontainerJar = GetFileName(roboCodeLibPath, "picocontainer*");
44      string robotsPath = Path.Combine(path, "robots", "Evaluation");
45      string srcRobotPath = Path.Combine(robotsPath, robotName + ".java");
[9565]46
[9926]47      File.WriteAllText(srcRobotPath, interpretedProgram, System.Text.Encoding.Default);
[9565]48
[9601]49      ProcessStartInfo javaCompileInfo = new ProcessStartInfo();
50      javaCompileInfo.FileName = "cmd.exe";
[9898]51      javaCompileInfo.Arguments = "/C javac -cp " + robocodeJar + "; " + srcRobotPath;
[9601]52      javaCompileInfo.RedirectStandardOutput = true;
53      javaCompileInfo.RedirectStandardError = true;
54      javaCompileInfo.UseShellExecute = false;
55      javaCompileInfo.CreateNoWindow = true;
[9565]56
[9601]57      Process javaCompile = new Process();
58      javaCompile.StartInfo = javaCompileInfo;
59      javaCompile.Start();
[9565]60
[9601]61      string cmdOutput = javaCompile.StandardOutput.ReadToEnd();
62      cmdOutput += javaCompile.StandardError.ReadToEnd();
[9612]63
[9601]64      javaCompile.WaitForExit();
[9612]65      if (javaCompile.ExitCode != 0) {
[9889]66        DeleteRobotFiles(path, robotName);
[9881]67        throw new Exception("Compile Error: " + cmdOutput);
[9612]68      }
[9565]69
[9881]70      //parallel execution of multiple robocode instances can sometimes lead to a damaged robot.database
[9898]71      try { File.Delete(path + @"\robots\robot.database"); }
[9881]72      catch { }
[9565]73
[9601]74      ProcessStartInfo evaluateCodeInfo = new ProcessStartInfo();
[9891]75
[9601]76      evaluateCodeInfo.FileName = "cmd.exe";
[9898]77      evaluateCodeInfo.Arguments = "/C java -cp " + battleRunnerPath + ";" + robocodeCoreJar + ";" + robocodeJar +
[9966]78                                  ";" + picocontainerJar + ";" + " BattleRunner Evaluation." + robotName + " " + path;
[9898]79
[9926]80      if (showUI) {
[9962]81        evaluateCodeInfo.Arguments += " true " + nrOfRounds + " ";
[9926]82      } else {
[9962]83        evaluateCodeInfo.Arguments += " false " + nrOfRounds + " ";
[9926]84      }
[9889]85
[9962]86      foreach (var enemy in enemies.CheckedItems)
[9966]87        evaluateCodeInfo.Arguments += enemy.Value + " ";
[9947]88
[9601]89      evaluateCodeInfo.RedirectStandardOutput = true;
90      evaluateCodeInfo.RedirectStandardError = true;
91      evaluateCodeInfo.UseShellExecute = false;
92      evaluateCodeInfo.CreateNoWindow = true;
[9565]93
[9601]94      Process evaluateCode = new Process();
95      evaluateCode.StartInfo = evaluateCodeInfo;
96      evaluateCode.Start();
[9881]97      evaluateCode.WaitForExit();
[9889]98
[9881]99      if (evaluateCode.ExitCode != 0) {
[9889]100        DeleteRobotFiles(path, robotName);
[9881]101        throw new Exception("Error running Robocode: " + evaluateCode.StandardError.ReadToEnd());
102      }
[9565]103
[9601]104      string scoreString = "";
[9884]105      double evaluation = -1.0;
[9612]106      try {
[9898]107        scoreString = evaluateCode.StandardOutput.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Last();
[9888]108        evaluation = Double.Parse(scoreString, CultureInfo.InvariantCulture);
[9790]109      }
[9881]110      catch (Exception ex) {
111        throw new Exception("Error parsing score string: " + ex.ToString());
[9601]112      }
[9881]113      finally {
[9889]114        DeleteRobotFiles(path, robotName);
[9881]115      }
[9565]116
[9881]117      return evaluation;
118    }
[9565]119
[9881]120    private static void DeleteRobotFiles(string path, string outputname) {
[9601]121      try {
[9898]122        File.Delete(path + @"\robots\Evaluation\" + outputname + ".java");
123        File.Delete(path + @"\robots\Evaluation\" + outputname + ".class");
[9601]124      }
[9881]125      catch { }
[9601]126    }
[9565]127
[9898]128    private static string GetFileName(string path, string pattern) {
129      string fileName = string.Empty;
130      try {
131        fileName = Directory.GetFiles(path, pattern).First();
132      }
133      catch {
134        throw new Exception("Error finding required RoboCode files.");
135      }
136      return fileName;
137    }
138
[9889]139    private static string GenerateRobotName() {
140      // Robocode class names are 32 char max and
141      // Java class names have to start with a letter
142      string outputname = Guid.NewGuid().ToString();
143      outputname = outputname.Remove(8, 1);
144      outputname = outputname.Remove(12, 1);
145      outputname = outputname.Remove(16, 1);
146      outputname = outputname.Remove(20, 1);
147      outputname = outputname.Remove(0, 1);
148      outputname = outputname.Insert(0, "R");
149      return outputname;
150    }
151
152    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) {
[9601]153      var tankNode = node;
154      while (!(tankNode.Symbol is Tank))
155        tankNode = tankNode.GetSubtree(0);
[9889]156
157      string result = ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);
158      result = result.Replace("class output", "class " + robotName);
159      return result;
[9601]160    }
161  }
[9565]162}
Note: See TracBrowser for help on using the repository browser.