public override void Run() { blackBoard = new BlackBoard(); blackBoard.robot = this; AttackBehaviour = new Sequence(blackBoard, new GenericSimpleTask(blackBoard, () => { blackBoard.attackInfo.consecutiveMisses = 0; IsAdjustGunForRobotTurn = false; IsAdjustRadarForGunTurn = true; blackBoard.behaviour = Behaviour.attack; return(true); }), new TurnGun(blackBoard, false, Orientation.forth), new ChangeColor(blackBoard, Color.Red), new MoveAhead(blackBoard, 200, true), new TurnScan(blackBoard, 360, Orientation.none, true), new TurnHeading(blackBoard, true, Orientation.none), new Selector(blackBoard, new InShotRange(blackBoard, 400, 10), new Shoot(blackBoard, 2) ), new CheckNode(blackBoard, () => { return(blackBoard.hitsRobot); }, new Shoot(blackBoard, 5), new MoveAhead(blackBoard, -50, false, true) ), new CheckNode(blackBoard, () => { return(blackBoard.attackInfo.consecutiveMisses < 20); }) ); CornerBehaviour = new Sequence(blackBoard, new TurnHeading(blackBoard, false, Orientation.left), new TurnGun(blackBoard, false, Orientation.right), new GenericSimpleTask(blackBoard, () => { blackBoard.attackInfo.consecutiveMisses = 0; IsAdjustGunForRobotTurn = false; IsAdjustRadarForGunTurn = true; blackBoard.behaviour = Behaviour.corner; return(true); }), new ChangeColor(blackBoard, Color.Blue), new TurnScan(blackBoard, 45, Orientation.none), new TurnScan(blackBoard, -45, Orientation.none), new TurnScan(blackBoard, 0, Orientation.right), //if at wall new Selector(blackBoard, new IsAtWall(blackBoard, 150), //set turn 90 degreees new TurnHeading(blackBoard, false, Orientation.none) ), //if at shot range then fire new Selector(blackBoard, new InShotRange(blackBoard, 10000), new Shoot(blackBoard, 5) ), //do a set(async) move new MoveAhead(blackBoard, 100, true) ); AimBehaviour = new Sequence(blackBoard, //only for the first time new TurnHeading(blackBoard, false, Orientation.bottom), new TurnGun(blackBoard, true, Orientation.none), new GenericSimpleTask(blackBoard, () => { blackBoard.aimInfo.consecutiveMisses = 0; IsAdjustGunForRobotTurn = true; IsAdjustRadarForGunTurn = false; blackBoard.behaviour = Behaviour.aim; return(true); }), new ChangeColor(blackBoard, Color.Yellow), //if not at wall new CheckNode(blackBoard, () => { return(blackBoard.headingOrientation != Orientation.forth); }, //do a set(async) move new MoveAhead(blackBoard, 50, true), //if at wall new Selector(blackBoard, new IsAtWall(blackBoard, 150), //set turn 90 degreees new TurnHeading(blackBoard, false, Orientation.none) ) ), new CheckNode(blackBoard, () => { return(blackBoard.headingOrientation == Orientation.forth); }, //aim at enemy new TurnScan(blackBoard, 360, Orientation.none, true), new TurnGun(blackBoard, true, Orientation.none), //if at shot range then fire new Selector(blackBoard, new InShotRange(blackBoard, 10000, 5), new Shoot(blackBoard, 5, true) ) )); WinBehaviour = new Sequence(blackBoard, new CheckNode(blackBoard, () => { return(blackBoard.behaviour != Behaviour.win); }, new MoveAhead(blackBoard, 0, true), new TurnGun(blackBoard, false, Orientation.forth), new GenericSimpleTask(blackBoard, () => { blackBoard.behaviour = Behaviour.win; return(true); }) ), new ChangeColor(blackBoard, Color.Green, false), new TurnScan(blackBoard, 90, Orientation.none) ); BeahaviorTree = new Sequence(blackBoard, //otherwise it would crash/disabled new TurnScan(blackBoard, 0), //do dance if won new CheckNode(blackBoard, () => { return(blackBoard.wonRound == true); }, WinBehaviour), //if won in previousround, start off with that behaviour. (attack or aim) new CheckNode(blackBoard, () => { return(Global.WonBehaviour == Behaviour.aim); }, new CheckNode(blackBoard, () => { return(AimViable()); }, AimBehaviour )), new CheckNode(blackBoard, () => { return(Global.WonBehaviour == Behaviour.attack); }, new CheckNode(blackBoard, () => { return(AttackViable()); }, AttackBehaviour )), //do the three strategies. if the first one doesn't succeed, than do the second and so forth. new CheckNode(blackBoard, () => { return(CornerViable() && !WinningBehaviourViable(Behaviour.corner)); }, CornerBehaviour ), new CheckNode(blackBoard, () => { return(!CornerViable() && AimViable()); }, AimBehaviour ), new CheckNode(blackBoard, () => { return(!CornerViable() && !AimViable() && AttackViable()); }, AttackBehaviour ), new CheckNode(blackBoard, () => { return(!AttackViable()); }, new GenericSimpleTask(blackBoard, () => { // I give up, try other tactics again blackBoard.cornerInfo = new BehaviourInfo(); blackBoard.aimInfo = new BehaviourInfo(); blackBoard.attackInfo = new BehaviourInfo(); return(true); }) ) ); new TurnScan(blackBoard, 360).Tick(); while (true) { BeahaviorTree.Tick(); } }