public override void Run() { blackBoard.robot = this; FleeBehaviour = new Sequence(blackBoard, new ScanRobot(blackBoard, 360), new CircleMove(blackBoard, 1000), new TurnToEnemy(blackBoard), //new Shoot(blackBoard, 15), new TurnGunTowardsScannedTank(blackBoard), new UpdateColour(blackBoard, Color.Green) ); KamikazeBehaviour = new Sequence(blackBoard, new ScanRobot(blackBoard, 360), new Kamikaze(blackBoard, 1000, 15), new TurnToEnemy(blackBoard), new TurnGunTowardsScannedTank(blackBoard), new UpdateColour(blackBoard, Color.Red) ); RangedBehaviour = new Sequence(blackBoard, new ScanRobot(blackBoard, 360), new MoveAhead(blackBoard, 1000), new TurnToEnemy(blackBoard), new Shoot(blackBoard, 15), new TurnGunTowardsScannedTank(blackBoard), new UpdateColour(blackBoard, Color.Yellow) ); IsAdjustGunForRobotTurn = true; IsAdjustRadarForGunTurn = true; Random rnd = new Random(); blackBoard.crazyMode = rnd.Next(0, 2); while (true) { if (blackBoard.robot.Energy < 30) { FleeBehaviour.Tick(); } else if (blackBoard.robot.Energy > 90) { RangedBehaviour.Tick(); } else { KamikazeBehaviour.Tick(); } } }
/// <summary> /// Hoofdprogramma van de robot. Kiest tussen drie verschillende patronen afhankelijk van resterende energie: /// * Agressief: Kies de dichtstbijzijnde tank en blijf deze achtervolgen. Probeer hem ook te rammen /// * Normaal: kies dichtstbijzijnde tank en blijf deze van een redelijke afstand beschieten /// * Voorzichtig: blijf bij de tanks vandaan. Blijf veel rondrijden en schiet af en toe /// /// Het normale patroon kiest afwisselend tussen de twee patronen: langzaam scannen en gek bewegen /// Dit maakt hem een stuk onvoorspelbaarder /// </summary> public override void Run() { Random rand = new Random(); blackBoard = new BlackBoard(this); maxEnergy = Energy; IsAdjustGunForRobotTurn = true; blackBoard.gunTurnAmt = 10; int behaviour = -1, oldBehaviour; BhvAgressive = new Sequence(blackBoard, new ChangeColor(blackBoard, Color.Green), new TrackRobot(blackBoard) ); BhvCautious = new Sequence(blackBoard, new ChangeColor(blackBoard, Color.Red), new CircleMove(blackBoard) ); BhvNormal = new Sequence(blackBoard, new ChangeColor(blackBoard, Color.Blue), new DrunkMove(blackBoard) ); BhvNormalAlt = new Sequence(blackBoard, new ChangeColor(blackBoard, Color.Yellow), new Stationary(blackBoard) ); BhvReverse = new Sequence(blackBoard, new ChangeColor(blackBoard, Color.Purple), new DriveReverse(blackBoard) ); BhvVictoryDance = new Sequence(blackBoard, new Dance(blackBoard) ); // Robot hoofdloop while (true) { // het oude gedrag oldBehaviour = behaviour; // pas schaalfactor aan voor het bepalen van het gedrag if (Energy > maxEnergy) { maxEnergy = Energy; } else { // Verlaag langzaam de drempelwaarde om ervoor te zorgen dat zijn gedrag verandert als een gevecht lang duurt maxEnergy *= 0.98; if (maxEnergy < 80) { maxEnergy = 80; } } // kies gedrag: aggresief als >66%, normaal als >33% en anders spinbot if (Energy > maxEnergy * thresAgressive) { behaviour = 0; } else if (Energy > maxEnergy * thresNormal) { behaviour = 1; // kiest of hij langzaam gaat zoeken of willekeurig gaat bewegen trackStealthy = rand.NextDouble() >= chanceStealthy; } else { behaviour = 2; } // als we een nieuw gedrag hebben if (oldBehaviour != behaviour) { // stop oude stappen als we die nog in de wachtrij hebben if (oldBehaviour != -1) { // Tweemalig om alles te resetten Stop(true); Stop(true); } } // Voer gedrag uit switch (behaviour) { case 0: BhvAgressive.Tick(); break; case 1: // Gedrag is willekeurig if (trackStealthy) { BhvNormalAlt.Tick(); } else { BhvNormal.Tick(); } break; default: BhvCautious.Tick(); break; } } }
/// <summary> /// Hij botst tegen een muur /// </summary> public override void OnHitWall(HitWallEvent e) { BhvReverse.Tick(); }
/// <summary> /// Doe een overwinningsdans als hij heeft gewonnen /// </summary> /// <param name="e"></param> public override void OnWin(WinEvent e) { BhvVictoryDance.Tick(); }
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(); } }