Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/16/15 10:36:09 (9 years ago)
Author:
gkronber
Message:

#2069 refactored grammar, symbols, and interpreter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/Robocode.TrunkInt/HeuristicLab.Problems.Robocode/3.3/Interpreter.cs

    r13013 r13017  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Diagnostics;
     25using System.Diagnostics.Contracts;
    2426using System.Globalization;
    2527using System.IO;
    2628using System.Linq;
    2729using System.Reflection;
     30using System.Runtime.Remoting.Messaging;
    2831using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2932
    3033namespace HeuristicLab.Problems.GeneticProgramming.Robocode {
    3134  public static class Interpreter {
     35    // TODO performance: it would probably be useful to implement the BattleRunner in such a way that we don't have to restart the java process each time, e.g. using console IO to load & run robots
    3236    public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3) {
    3337      if (robotName == null)
     
    148152    public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) {
    149153      var tankNode = node;
    150       while (!(tankNode.Symbol is Tank))
     154      while (tankNode.Symbol.Name != "Tank")
    151155        tankNode = tankNode.GetSubtree(0);
    152156
    153       string result = ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);
     157      string result = Interpret(tankNode);
    154158      result = result.Replace("class output", "class " + robotName);
    155159      return result;
    156160    }
     161
     162    private static string Interpret(ISymbolicExpressionTreeNode node) {
     163      switch (node.Symbol.Name) {
     164        case "Block": return InterpretBlock(node);
     165        case "Statement": return InterpretStat(node);
     166        case "DoNothing": return string.Empty;
     167        case "EmptyEvent": return string.Empty;
     168
     169        case "GetEnergy": return "getEnergy()";
     170        case "GetHeading": return "getHeading()";
     171        case "GetGunHeading": return "getGunHeading()";
     172        case "GetRadarHeading": return "getRadarHeading()";
     173        case "GetX": return "getX()";
     174        case "GetY": return "getY()";
     175
     176        case "Addition": return InterpretBinaryOperator(" + ", node);
     177        case "Subtraction": return InterpretBinaryOperator(" - ", node);
     178        case "Multiplication": return InterpretBinaryOperator(" * ", node);
     179        case "Division": return InterpretBinaryOperator(" / ", node);
     180        case "Modulus": return InterpretBinaryOperator(" % ", node);
     181
     182        case "Equal": return InterpretComparison(" == ", node);
     183        case "LessThan": return InterpretComparison(" < ", node);
     184        case "LessThanOrEqual": return InterpretComparison(" <= ", node);
     185        case "GreaterThan": return InterpretComparison("  >", node);
     186        case "GreaterThanOrEqual": return InterpretComparison(" >= ", node);
     187        case "ConditionalAnd": return InterpretBinaryOperator(" && ", node);
     188        case "ConditionalOr": return InterpretBinaryOperator(" || ", node);
     189        case "Negation": return InterpretFunc1("!", node);
     190
     191        case "IfThenElseStat": return InterpretIf(node);
     192        case "WhileStat": return InterpretWhile(node);
     193        case "BooleanExpression": return InterpretChild(node);
     194        case "NumericalExpression": return InterpretChild(node);
     195        case "Number": return InterpretNumber(node);
     196        case "BooleanValue": return InterpretBoolValue(node);
     197
     198
     199        case "Ahead": return InterpretFunc1("setAhead", node);
     200        case "Back": return InterpretFunc1("setBack", node);
     201        case "Fire": return InterpretFunc1("setFire", node);
     202        case "TurnLeft": return InterpretFunc1("setTurnLeft", node);
     203        case "TurnRight": return InterpretFunc1("setTurnRight", node);
     204        case "TurnGunLeft": return InterpretFunc1("setTurnGunLeft", node);
     205        case "TurnGunRight": return InterpretFunc1("setTurnGunRight", node);
     206        case "TurnRadarLeft": return InterpretFunc1("setTurnRadarLeft", node);
     207        case "TurnRadarRight": return InterpretFunc1("setTurnRadarRight", node);
     208        case "ShotPower": return InterpetShotPower(node);
     209
     210        case "OnBulletHit": return InterpretOnBulletHit(node);
     211        case "OnBulletMissed": return InterpretOnBulletMissed(node);
     212        case "OnHitByBullet": return InterpretOnHitByBullet(node);
     213        case "OnHitRobot": return InterpretOnHitRobot(node);
     214        case "OnHitWall": return InterpretOnHitWall(node);
     215        case "OnScannedRobot": return InterpretOnScannedRobot(node);
     216
     217        case "Run": return InterpretRun(node);
     218        case "Tank": return InterpretTank(node);
     219        case "CodeSymbol": return InterpretCodeSymbol(node);
     220
     221        default: throw new ArgumentException(string.Format("Found an unknown symbol {0} in a robocode solution", node.Symbol.Name));
     222      }
     223    }
     224
     225    private static string InterpretCodeSymbol(ISymbolicExpressionTreeNode node) {
     226      var sy = node.Symbol as CodeSymbol;
     227      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     228      return string.Format(
     229@"{0}
     230{1}
     231{2}", sy.Prefix, code, sy.Suffix);
     232    }
     233
     234    private static string InterpretBoolValue(ISymbolicExpressionTreeNode node) {
     235      var boolNode = node as BooleanTreeNode;
     236      return string.Format(NumberFormatInfo.InvariantInfo, "{0}", boolNode.Value).ToLower();
     237    }
     238
     239    private static string InterpretNumber(ISymbolicExpressionTreeNode node) {
     240      var numberNode = node as NumberTreeNode;
     241      return string.Format(NumberFormatInfo.InvariantInfo, "{0}", numberNode.Value);
     242    }
     243
     244    private static string InterpetShotPower(ISymbolicExpressionTreeNode node) {
     245      var shotPowerNode = node as ShotPowerTreeNode;
     246      return string.Format(NumberFormatInfo.InvariantInfo, "{0:E}", shotPowerNode.Value);
     247    }
     248
     249
     250    internal static string InterpretBlock(ISymbolicExpressionTreeNode node) {
     251      string result = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     252      return string.Format("{{ {0} }}", result + Environment.NewLine);
     253    }
     254
     255    internal static string InterpretStat(ISymbolicExpressionTreeNode node) {
     256      // must only have one sub-tree
     257      Contract.Assert(node.SubtreeCount == 1);
     258      return Interpret(node.GetSubtree(0)) + " ;" + Environment.NewLine;
     259    }
     260
     261    internal static string InterpretIf(ISymbolicExpressionTreeNode node) {
     262      ISymbolicExpressionTreeNode condition = null, truePart = null, falsePart = null;
     263      string[] parts = new string[3];
     264
     265      if (node.SubtreeCount < 2 || node.SubtreeCount > 3)
     266        throw new Exception("Unexpected number of children. Expected 2 or 3 children.");
     267
     268      condition = node.GetSubtree(0);
     269      truePart = node.GetSubtree(1);
     270      if (node.SubtreeCount == 3)
     271        falsePart = node.GetSubtree(2);
     272
     273      parts[0] = Interpret(condition);
     274      parts[1] = Interpret(truePart);
     275      if (falsePart != null) parts[2] = Interpret(falsePart);
     276
     277      return string.Format("if ({0}) {{ {1} }} else {{ {2} }}", Interpret(condition), Interpret(truePart),
     278        falsePart == null ? string.Empty : Interpret(falsePart));
     279    }
     280
     281    internal static string InterpretWhile(ISymbolicExpressionTreeNode node) {
     282      var cond = Interpret(node.GetSubtree(0));
     283      var body = Interpret(node.GetSubtree(1));
     284      return string.Format("while ({0}) {{ {2} {1} {2} }} {2}", cond, body, Environment.NewLine);
     285    }
     286
     287    public static string InterpretBinaryOperator(string opSy, ISymbolicExpressionTreeNode node) {
     288      if (node.SubtreeCount < 2)
     289        throw new ArgumentException(string.Format("Expected at least two children in {0}.", node.Symbol), "node");
     290
     291      string result = string.Join(opSy, node.Subtrees.Select(Interpret));
     292      return "(" + result + ")";
     293    }
     294
     295    public static string InterpretChild(ISymbolicExpressionTreeNode node) {
     296      if (node.SubtreeCount != 1)
     297        throw new ArgumentException(string.Format("Expected exactly one child in {0}.", node.Symbol), "node");
     298
     299      return Interpret(node.GetSubtree(0));
     300    }
     301
     302    public static string InterpretComparison(string compSy, ISymbolicExpressionTreeNode node) {
     303      ISymbolicExpressionTreeNode lhs = null, rhs = null;
     304      if (node.SubtreeCount != 2)
     305        throw new ArgumentException(string.Format("Expected exactly two children in {0}.", node.Symbol), "node");
     306
     307      lhs = node.GetSubtree(0);
     308      rhs = node.GetSubtree(1);
     309
     310      return Interpret(lhs) + " == " + Interpret(rhs);
     311    }
     312
     313    public static string InterpretFunc1(string functionId, ISymbolicExpressionTreeNode node) {
     314      if (node.SubtreeCount != 1)
     315        throw new ArgumentException(string.Format("Expected 1 child in {0}.", node.Symbol.Name), "node");
     316
     317      return string.Format("{0}({1})", functionId, Interpret(node.GetSubtree(0)));
     318    }
     319
     320    public static string InterpretOnScannedRobot(ISymbolicExpressionTreeNode node) {
     321      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     322      return string.Format(
     323@"public void onScannedRobot(ScannedRobotEvent e) {{
     324  double absoluteBearing = getHeading() + e.getBearing();
     325  double bearingFromGun = normalRelativeAngleDegrees(absoluteBearing - getGunHeading());
     326  setTurnGunRight(bearingFromGun);
     327{0}
     328  execute();
     329}}", code);
     330    }
     331
     332
     333    public static string InterpretOnHitWall(ISymbolicExpressionTreeNode node) {
     334      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     335      return string.Format(
     336@"public void onHitWall(HitWallEvent e) {{
     337{0}
     338execute();
     339}}", code);
     340    }
     341
     342    public static string InterpretOnHitRobot(ISymbolicExpressionTreeNode node) {
     343      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     344      return string.Format(
     345@"public void onHitRobot(HitRobotEvent e) {{
     346{0}
     347execute();
     348}}", code);
     349    }
     350
     351    public static string InterpretOnHitByBullet(ISymbolicExpressionTreeNode node) {
     352      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     353      return string.Format(
     354@"public void onHitByBullet(HitByBulletEvent e) {{
     355{0}
     356execute();
     357}}", code);
     358    }
     359
     360    public static string InterpretOnBulletMissed(ISymbolicExpressionTreeNode node) {
     361      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     362      return string.Format(
     363@"public void onBulletMissed(BulletMissedEvent e) {{
     364{0}
     365execute();
     366}}", code);
     367    }
     368
     369    public static string InterpretOnBulletHit(ISymbolicExpressionTreeNode node) {
     370      var Prefix = "public void onBulletHit(BulletHitEvent e) {";
     371      var Suffix =
     372@"execute();
     373}";
     374      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     375      return Prefix + code + Environment.NewLine + Suffix;
     376    }
     377
     378    public static string InterpretRun(ISymbolicExpressionTreeNode node) {
     379      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     380      return string.Format(
     381@"public void run() {{
     382  setAdjustGunForRobotTurn(true);
     383  turnRadarRightRadians(Double.POSITIVE_INFINITY);
     384{0}
     385  execute();
     386}}", code);
     387    }
     388
     389    public static string InterpretTank(ISymbolicExpressionTreeNode node) {
     390      string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret));
     391      return string.Format(
     392@"package Evaluation;
     393import robocode.*;
     394import robocode.Robot;
     395import robocode.util.*;
     396import static robocode.util.Utils.normalRelativeAngleDegrees;
     397import java.awt.*;
     398
     399public class output extends AdvancedRobot {{
     400{0}
     401}}", code);
     402    }
    157403  }
    158404}
Note: See TracChangeset for help on using the changeset viewer.