#region License Information /* HeuristicLab * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.Robocode { [StorableClass] [Item("Robocode Grammar", "The grammar for the Robocode GP problem.")] public class Grammar : SymbolicExpressionGrammar { private const string EventsName = "Events"; private const string ExpressionsName = "Expressions"; private const string ControlStatementsName = "Control Statements"; private const string RobocodeFunctionsName = "Robocode Functions"; private const string RelationalOperatorsName = "Relational Operators"; private const string LogicalOperators = "Logical Operators"; private const string NumericalOperatorsName = "Numerical Operators"; [StorableConstructor] protected Grammar(bool deserializing) : base(deserializing) { } protected Grammar(Grammar original, Cloner cloner) : base(original, cloner) { } public Grammar() : base("Robocode Grammar", "The grammar for the Robocode GP problem.") { Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new Grammar(this, cloner); } // initialize set of allowed symbols and define // the allowed combinations of symbols private void Initialize() { #region Symbols var block = new Block(); var stat = new Stat(); var ifThenElseStat = new IfThenElseStat(); var whileStat = new WhileStat(); var logicalExpr = new LogicalExpression(); var numericalExpr = new NumericalExpression(); var equal = new Equal(); var lessThan = new LessThan(); var lessThanOrEqual = new LessThanOrEqual(); var greaterThan = new GreaterThan(); var greaterThanOrEqual = new GreaterThanOrEqual(); var conjunction = new Conjunction(); var disjunction = new Disjunction(); var negation = new Negation(); var addition = new Addition(); var subtraction = new Subtraction(); var multiplication = new Multiplication(); var division = new Division(); var modulus = new Modulus(); var number = new Number(); var logicalVal = new LogicalValue(); var ahead = new Ahead(); var back = new Back(); var fire = new Fire(); var shotPower = new ShotPower(); var getEnergy = new GetEnergy(); var getGunHeading = new GetGunHeading(); var getHeading = new GetHeading(); var getRadarHeading = new GetRadarHeading(); var getX = new GetX(); var getY = new GetY(); //var setAdjustGunForRobotTurn = new SetAdjustGunForRobotTurn(); //var setAdjustRadarForGunTurn = new SetAdjustRadarForGunTurn(); //var setAdjustRadarForRobotTurn = new SetAdjustRadarForRobotTurn(); //var independent = new Independent(); var turnLeft = new TurnLeft(); var turnRight = new TurnRight(); var turnGunLeft = new TurnGunLeft(); var turnGunRight = new TurnGunRight(); var turnRadarLeft = new TurnRadarLeft(); var turnRadarRight = new TurnRadarRight(); var onBulletHit = new OnBulletHit(); var onBulletMissed = new OnBulletMissed(); var onHitByBullet = new OnHitByBullet(); var onHitRobot = new OnHitRobot(); var onHitWall = new OnHitWall(); var onScannedRobot = new OnScannedRobot(); var run = new Run(); var tank = new Tank(); var doNothing = new DoNothing(); var emptyEvent = new EmptyEvent(); #endregion #region Symbol Collections var controlSymbols = new ISymbol[] { ifThenElseStat, whileStat }; var actionSymbols = new ISymbol[] { ahead, back, fire, turnGunLeft, turnGunRight, turnLeft, turnRadarLeft, turnRadarRight, turnRight //setAdjustGunForRobotTurn, setAdjustRadarForGunTurn, setAdjustRadarForRobotTurn, }; var functionSymbols = new ISymbol[] { getEnergy, getGunHeading, getHeading, getRadarHeading, getX, getY }; var events = new GroupSymbol(EventsName, new ISymbol[] { onScannedRobot, onBulletHit, onBulletMissed, onHitByBullet, onHitRobot, onHitWall }); var controlStatements = new GroupSymbol(ControlStatementsName, controlSymbols); var expressions = new GroupSymbol(ExpressionsName, new ISymbol[] { logicalExpr, numericalExpr }); var robocodeFunctions = new GroupSymbol(RobocodeFunctionsName, actionSymbols.Concat(functionSymbols)); var relationalOperators = new GroupSymbol(RelationalOperatorsName, new ISymbol[] { equal, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual }); var logicalOperators = new GroupSymbol(LogicalOperators, new ISymbol[] { conjunction, disjunction, negation }); var numericalOperators = new GroupSymbol(NumericalOperatorsName, new ISymbol[] { addition, subtraction, multiplication, division, modulus }); #endregion #region Adding Symbols AddSymbol(tank); AddSymbol(run); AddSymbol(stat); AddSymbol(block); AddSymbol(shotPower); AddSymbol(number); AddSymbol(logicalVal); AddSymbol(events); AddSymbol(expressions); AddSymbol(controlStatements); AddSymbol(robocodeFunctions); AddSymbol(relationalOperators); AddSymbol(logicalOperators); AddSymbol(numericalOperators); AddSymbol(emptyEvent); AddSymbol(doNothing); #endregion #region Grammar Definition // StartSymbol AddAllowedChildSymbol(StartSymbol, tank); // Tank AddAllowedChildSymbol(tank, run, 0); AddAllowedChildSymbol(tank, onScannedRobot, 1); AddAllowedChildSymbol(tank, onBulletHit, 2); AddAllowedChildSymbol(tank, onBulletMissed, 3); AddAllowedChildSymbol(tank, onHitByBullet, 4); AddAllowedChildSymbol(tank, onHitRobot, 5); AddAllowedChildSymbol(tank, onHitWall, 6); // Run AddAllowedChildSymbol(run, stat); // Event foreach (var s in events.Symbols) AddAllowedChildSymbol(s, stat); // Block AddAllowedChildSymbol(block, stat); // Stat AddAllowedChildSymbol(stat, stat); AddAllowedChildSymbol(stat, block); foreach (var s in controlSymbols) AddAllowedChildSymbol(stat, s); foreach (var s in robocodeFunctions.Symbols) AddAllowedChildSymbol(stat, s); AddAllowedChildSymbol(stat, emptyEvent); AddAllowedChildSymbol(stat, doNothing); // IfStat AddAllowedChildSymbol(ifThenElseStat, logicalExpr, 0); AddAllowedChildSymbol(ifThenElseStat, stat, 1); AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 1); AddAllowedChildSymbol(ifThenElseStat, doNothing, 1); AddAllowedChildSymbol(ifThenElseStat, stat, 2); AddAllowedChildSymbol(ifThenElseStat, emptyEvent, 2); AddAllowedChildSymbol(ifThenElseStat, doNothing, 2); // WhileStat AddAllowedChildSymbol(whileStat, logicalExpr, 0); AddAllowedChildSymbol(whileStat, stat, 1); AddAllowedChildSymbol(whileStat, emptyEvent, 1); AddAllowedChildSymbol(whileStat, doNothing, 1); // Numerical Expressions foreach (var s in functionSymbols.Concat(new[] { number })) AddAllowedChildSymbol(numericalExpr, s); foreach (var s in numericalOperators.Symbols) { AddAllowedChildSymbol(numericalExpr, s); foreach (var ne in functionSymbols.Concat(new[] { number })) AddAllowedChildSymbol(s, ne); foreach (var no in numericalOperators.Symbols) { AddAllowedChildSymbol(s, no); } } // Logical Expressions AddAllowedChildSymbol(logicalExpr, logicalVal); foreach (var s in logicalOperators.Symbols) { AddAllowedChildSymbol(logicalExpr, s); AddAllowedChildSymbol(s, logicalVal); foreach (var lo in logicalOperators.Symbols) AddAllowedChildSymbol(s, lo); foreach (var ro in relationalOperators.Symbols) AddAllowedChildSymbol(s, ro); } foreach (var s in relationalOperators.Symbols) AddAllowedChildSymbol(s, numericalExpr); // Functions foreach (var f in robocodeFunctions.Symbols) { if (f is Fire) AddAllowedChildSymbol(f, shotPower); else AddAllowedChildSymbol(f, numericalExpr); } #endregion } } }