- Timestamp:
- 10/16/15 10:36:09 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/Robocode.TrunkInt/HeuristicLab.Problems.Robocode/3.3/Interpreter.cs
r13013 r13017 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Diagnostics; 25 using System.Diagnostics.Contracts; 24 26 using System.Globalization; 25 27 using System.IO; 26 28 using System.Linq; 27 29 using System.Reflection; 30 using System.Runtime.Remoting.Messaging; 28 31 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 32 30 33 namespace HeuristicLab.Problems.GeneticProgramming.Robocode { 31 34 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 32 36 public static double EvaluateTankProgram(ISymbolicExpressionTree tree, string path, EnemyCollection enemies, string robotName = null, bool showUI = false, int nrOfRounds = 3) { 33 37 if (robotName == null) … … 148 152 public static string InterpretProgramTree(ISymbolicExpressionTreeNode node, string robotName) { 149 153 var tankNode = node; 150 while ( !(tankNode.Symbol is Tank))154 while (tankNode.Symbol.Name != "Tank") 151 155 tankNode = tankNode.GetSubtree(0); 152 156 153 string result = ((CodeNode)tankNode.Symbol).Interpret(tankNode, tankNode.Subtrees);157 string result = Interpret(tankNode); 154 158 result = result.Replace("class output", "class " + robotName); 155 159 return result; 156 160 } 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} 338 execute(); 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} 347 execute(); 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} 356 execute(); 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} 365 execute(); 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; 393 import robocode.*; 394 import robocode.Robot; 395 import robocode.util.*; 396 import static robocode.util.Utils.normalRelativeAngleDegrees; 397 import java.awt.*; 398 399 public class output extends AdvancedRobot {{ 400 {0} 401 }}", code); 402 } 157 403 } 158 404 }
Note: See TracChangeset
for help on using the changeset viewer.