///<summary> ///constructor ///</summary> ///<param name="graph"></param> ///<param name="source"></param> ///<param name="target"></param> ///<param name="bot">The bot requesting the search</param> public GraphSearchDijkstrasTimeSliced(SparseGraph graph, int source, int target, BotEntity bot) : base(SearchTypes.Dijkstra, bot) { _graph = graph; _shortestPathTree = new List<NavGraphEdge>(graph.NumNodes); _searchFrontier = new List<NavGraphEdge>(graph.NumNodes); _costToThisNode = new List<float>(graph.NumNodes); for (int i = 0; i < graph.NumNodes; i++) { ShortestPathTree.Add(null); SearchFrontier.Add(null); CostToThisNode.Add(0); } _source = source; Target = target; //create the PQ PQ = new IndexedPriorityQueueLow(CostToThisNode, Graph.NumNodes); //put the source node on the queue PQ.Insert(source); }
//returns a value between 0 and 1 based on the total amount of ammo the //bot is carrying each of the weapons. Each of the three weapons a bot can //pick up can contribute a third to the score. In other words, if a bot //is carrying a RL and a RG and has max ammo for the RG but only half max //for the RL the rating will be 1/3 + 1/6 + 0 = 0.5 public static float TotalWeaponStrength(BotEntity bot) { float maxRoundsForShotgun = GetMaxRoundsBotCanCarryForWeapon( WeaponTypes.Shotgun); float maxRoundsForRailgun = GetMaxRoundsBotCanCarryForWeapon( WeaponTypes.Railgun); float maxRoundsForRocketLauncher = GetMaxRoundsBotCanCarryForWeapon( WeaponTypes.RocketLauncher); float totalRoundsCarryable = maxRoundsForShotgun + maxRoundsForRailgun + maxRoundsForRocketLauncher; float numSlugs = bot.WeaponSystem.GetAmmoRemaining( WeaponTypes.Railgun); float numCartridges = bot.WeaponSystem.GetAmmoRemaining( WeaponTypes.Shotgun); float numRockets = bot.WeaponSystem.GetAmmoRemaining( WeaponTypes.RocketLauncher); //the value of the tweaker (must be in the range 0-1) indicates how much //desirability value is returned even if a bot has not picked up any weapons. //(it basically adds in an amount for a bot's persistent weapon -- the blaster) const float tweaker = 0.05f; return tweaker + (1 - tweaker)*(numSlugs + numCartridges + numRockets)/ totalRoundsCarryable; }
//returns a score between 0 and 1 representing the desirability of the //strategy the concrete subclass represents public override float CalculateDesirability(BotEntity bot) { float desirability = 0.0f; //there is no point in trying to capture their flag when we don't even know where //to return it to if (bot.FoundTriggers.NumberOfFlags > 0 && bot.FoundTriggers.IsOurFlagDiscovered) { //if we are carrying a flag, we should really try to return it to our base if (bot.IsCarryingFlag) desirability = 2; else { //if we have decent health, good ammo, and we are a high ranking officer //we want to get their flag, otherwise we will tend to guard desirability = bot.HealthPercentage * bot.WeaponSystem.CurrentWeapon.PercentageRoundsLeft* 3/(2-(int)bot.Rank); desirability = MathHelper.Clamp(desirability, 0, 1); //bias the value according to the personality of the bot desirability *= _characterBias; } } return desirability; }
/// <summary> /// This checks to see if we need to explore to find weapons or health /// Once we know where at least one health pack is, /// and one weapon, we really have reason to explore anymore /// </summary> /// <param name="bot">bot to evaluate for</param> /// <returns></returns> public override float CalculateDesirability(BotEntity bot) { //figure out desirability of exploring for health //if we are unhealthy and we don't know where any health is float howBadIWantToExploreForHealth = (1 - bot.HealthPercentage)*(bot.FoundTriggers.NumberOfHealthItems > 1 ? 1 : 0); //figure out desirability of exploring for the weapon we are holding //if we are unloaded and we don't know where any of the weapon is //by default the bots walk around carrying their blaster... float howBadIWantToExploreForAWeapon; if(bot.WeaponSystem.CurrentWeapon.WeaponType == WeaponTypes.Blaster) { howBadIWantToExploreForAWeapon = GameManager.GameManager.Instance.Parameters.PropensityToSearchForAWeapon; } else { howBadIWantToExploreForAWeapon = (1 - bot.WeaponSystem.CurrentWeapon.PercentageRoundsLeft) * (bot.FoundTriggers.NumberOfWeaponsByType(bot.WeaponSystem.CurrentWeapon.WeaponType) < 1 ? 1 : 0); } //get the maximum desire to explore for something float desirability = MathHelper.Max(howBadIWantToExploreForHealth, howBadIWantToExploreForAWeapon); //ensure the value is in the range 0 to 1 desirability = MathHelper.Clamp(desirability, 0.0f, 1.0f); return desirability; }
///<summary> ///constructor for the NavigationalMemoryRecord class ///</summary> public NavigationalMemoryRecord( BotEntity owner, NavigationalMemory.NavigationalMemoryKey key) { Mode = key.Mode; SourceNodeIndex = key.SourceNodeIndex; DestinationNodeIndex = key.DestinationNodeIndex; Vector2 position = owner.PathPlanner.GetNodePosition(key.DestinationNodeIndex); RunningAverageTimeTaken = Vector2.Distance(owner.Position, position)/ owner.MaxSpeed*3.0f; //200% margin //TODO: make parameter //switch (key.Mode) //{ // case NavigationalMemory.TravelModes.FollowPath: // break; // case NavigationalMemory.TravelModes.SeekToPosition: // break; // case NavigationalMemory.TravelModes.TraverseEdge: // break; //} }
///<summary> ///constructor ///</summary> ///<param name="graph"></param> ///<param name="source"></param> ///<param name="target"></param> ///<param name="bot">Bot Requesting the path</param> public GraphSearchAStarTimeSliced( SparseGraph graph, int source, int target, BotEntity bot) : base(SearchTypes.AStar, bot) { _graph = graph; _shortestPathTree = new List<NavGraphEdge>(graph.NumNodes); _searchFrontier = new List<NavGraphEdge>(graph.NumNodes); _gCosts = new List<float>(graph.NumNodes); _fCosts = new List<float>(graph.NumNodes); for (int i = 0; i < graph.NumNodes; i++) { ShortestPathTree.Add(null); SearchFrontier.Add(null); GCosts.Add(0); FCosts.Add(0); } _source = source; _target = target; //create the priority queue _pq = new IndexedPriorityQueueLow(FCosts, Graph.NumNodes); //put the source node on the queue PQ.Insert(source); }
//returns a score between 0 and 1 representing the desirability of the //strategy the concrete subclass represents public override float CalculateDesirability(BotEntity bot) { float desirability = 0.0f; //only do the calculation if there is a target present if (bot.TargetingSystem.IsTargetPresent) { float tweaker = GameManager.GameManager.Instance.Parameters.BotAggroGoalTweaker; int teammatesTargetingBot = bot.SensoryMemory.GetListOfRecentlySensedTeammates().FindAll(delegate(BotEntity teammate) { return teammate.TargetBot == bot.TargetBot; }).Count; const int maxBotsForMaxDesirability = 16; //f(x) = max((16 + 1) - (x-16)^2/16, 0) //in effect x=0 [no bots targeting the bot] means f(x) = 1 //x = 16, f(x) = 17 //x = 32, f(x) = 1 //x = 33, f(x) = 0 float teammatesTargetingBotMultiplier = (float)Math.Max( (maxBotsForMaxDesirability + 1) - Math.Pow(teammatesTargetingBot - maxBotsForMaxDesirability, 2) / maxBotsForMaxDesirability, 1.0f); desirability = tweaker* bot.HealthPercentage* Feature.TotalWeaponStrength(bot)* teammatesTargetingBotMultiplier; //bias the value according to the personality of the bot desirability *= _characterBias; } return desirability; }
public Formation(FormationType Type, BotEntity Lead, uint Pos, List<BotEntity> members) { _formationType = Type; _leader = Lead; _position = Pos; _members = members; }
//returns a score between 0 and 1 representing the desirability of the //strategy the concrete subclass represents public override float CalculateDesirability(BotEntity bot) { //first grab the distance to the closest instance of a health item float distance = Feature.DistanceToItem(bot, ItemTypes.Health); //if the distance feature is rated with a value of 1 it means that the //item is either not present on the map or too far away to be worth //considering, therefore the desirability is zero if (distance == 1) { return 0; } //the desirability of finding a health item is proportional to the amount //of health remaining and inversely proportional to the distance from the //nearest instance of a health item. float desirability = GameManager.GameManager.Instance.Parameters.BotHealthGoalTweaker* (1 - bot.HealthPercentage)/ (Feature.DistanceToItem(bot, ItemTypes.Health)); //ensure the value is in the range 0 to 1 desirability = MathHelper.Clamp(desirability, 0, 1); //bias the value according to the personality of the bot desirability *= _characterBias; return desirability; }
///<summary> ///Base goal constructor ///</summary> ///<param name="bot"></param> ///<param name="goalType"></param> protected Goal(BotEntity bot, GoalTypes goalType) { _bot = bot; _goalType = goalType; _status = StatusTypes.Inactive; _logPrefixText = String.Format("[{0,-8}] [{1,17}.", Bot.Name, goalType); }
///<summary> ///steering behavior constructor ///</summary> ///<param name="agent"></param> public Steering(BotEntity agent) { _bot = agent; Flags = 0; _weightSeparation = GameManager.GameManager.Instance.Parameters.SeparationWeight; _weightWander = GameManager.GameManager.Instance.Parameters.WanderWeight; _weightWallAvoidance = GameManager.GameManager.Instance.Parameters.WallAvoidanceWeight; _viewDistance = GameManager.GameManager.Instance.Parameters.ViewDistance; _wallDetectionFeelerLength = GameManager.GameManager.Instance.Parameters.WallDetectionFeelerLength; Feelers = new List<Vector2>(3); _deceleration = Decelerations.Normal; TargetAgent1 = null; TargetAgent2 = null; _wanderDistance = WANDER_DIST; _wanderJitter = WANDER_JITTER_PER_SEC; _wanderRadius = WANDER_RAD; _weightSeek = GameManager.GameManager.Instance.Parameters.SeekWeight; _weightArrive = GameManager.GameManager.Instance.Parameters.ArriveWeight; CellSpaceIsOn = true; SummingMethod = SummingMethods.Prioritized; //stuff for the wander behavior float theta = RandomUtil.RandomFloat()*(float) Math.PI*2.0f; //create a vector to a target position on the wander circle WanderTarget = new Vector2(WanderRadius*(float) Math.Cos(theta), WanderRadius*(float) Math.Sin(theta)); }
public Formation(Formation cloner) { _formationType = cloner.FormationType; _leader = cloner.Leader; _position = cloner.Position; _members = cloner.Members; }
///<summary> ///constructor for composite goal GetItem ///</summary> ///<param name="bot">bot entity that owns this goal</param> ///<param name="itemToGet">item to get</param> public GetItem(BotEntity bot, ItemTypes itemToGet) : base(bot, ItemTypeToGoalType(itemToGet)) { _itemToGet = itemToGet; _giverTrigger = null; _logItemToGetText = String.Format(" Item: [{0,-12}]", EnumUtil.GetDescription(_itemToGet)); }
//returns a score between 0 and 1 representing the desirability of the //strategy the concrete subclass represents public override float CalculateDesirability(BotEntity bot) { //grab the distance to the closest instance of the weapon type float distance = Feature.DistanceToItem(bot, Entity.Entity.WeaponTypeToItemType(_weaponType)); //Added by Morteza //If the number of rounds we have is less then maximum, instead of picking up another weapon then, //Lets grab ammo for the weapon we have if (bot.WeaponSystem.CurrentWeapon.NumRoundsRemaining < bot.WeaponSystem.CurrentWeapon.MaxRoundsCarried) { if (Feature.DistanceToItem(bot, Entity.Entity.WeaponTypeToItemType(_weaponType)) != 1) { return 1; } } //if the distance feature is rated with a value of 1 it means that the //item is either not present on the map or too far away to be worth //considering, therefore the desirability is zero if (distance == 1) { return 0; } //value used to tweak the desirability float tweaker; switch (_weaponType) { case WeaponTypes.Railgun: tweaker = GameManager.GameManager.Instance.Parameters.BotRailgunGoalTweaker; break; case WeaponTypes.RocketLauncher: tweaker = GameManager.GameManager.Instance.Parameters.BotRocketLauncherGoalTweaker; break; case WeaponTypes.Shotgun: tweaker = GameManager.GameManager.Instance.Parameters.BotShotgunGoalTweaker; break; default: tweaker = 1.0f; break; } float health = bot.HealthPercentage; float weaponStrength = Feature.IndividualWeaponStrength(bot, _weaponType); float desirability = (tweaker * health * (1 - weaponStrength) * bot.WeaponSystem.CurrentWeapon.PercentageRoundsLeft) / distance; //ensure the value is in the range 0 to 1 desirability = MathHelper.Clamp(desirability, 0, 1); desirability *= _characterBias; return desirability; }
public override void RenderInfo(Vector2 position, BotEntity bot) { TextUtil.DrawText(position, "H: " + CalculateDesirability(bot).ToString("F2")); return; //string s = // (1 - Feature.Health(bot)).ToString("F2") + // ", " + // Feature.DistanceToItem(bot, ItemTypes.Health).ToString("F2"); //TextUtil.DrawText(position + new Vector2(0, 15), s); }
public override void RenderInfo(Vector2 position, BotEntity bot) { TextUtil.DrawText(position, "AT: " + CalculateDesirability(bot).ToString("F2")); return; //string s = // Feature.Health(bot)).ToString("F2") + // ", " + // Feature.TotalWeaponStrength(bot).ToString("F2"); //TextUtil.DrawText(position+Vector2(0,12), s); }
//returns a value between 0 and 1 based on how much ammo the bot has for //the given weapon, and the maximum amount of ammo the bot can carry. The //closer the amount carried is to the max amount, the higher the score public static float IndividualWeaponStrength(BotEntity bot, WeaponTypes weaponType) { //grab a pointer to the gun (if the bot owns an instance) Weapon wp = bot.WeaponSystem.GetWeaponFromInventory(weaponType); if (wp != null) { return wp.NumRoundsRemaining/ GetMaxRoundsBotCanCarryForWeapon(weaponType); } return 0.0f; }
///<summary> ///constructor ///</summary> ///<param name="owner"></param> public WeaponBlaster(BotEntity owner) : base(WeaponTypes.Blaster, GameManager.GameManager.Instance.Parameters.BlasterDefaultRounds, GameManager.GameManager.Instance.Parameters.BlasterMaxRoundsCarried, GameManager.GameManager.Instance.Parameters.BlasterFiringFreq, GameManager.GameManager.Instance.Parameters.BlasterIdealRange, GameManager.GameManager.Instance.Parameters.BlasterMaxSpeed, owner) { //setup the fuzzy module InitializeFuzzyModule(); }
///<summary> ///constructor ///</summary> ///<param name="owner"></param> ///<param name="reactionTime"></param> ///<param name="aimAccuracy"></param> ///<param name="aimPersistence"></param> public WeaponSystem( BotEntity owner, float reactionTime, float aimAccuracy, float aimPersistence) { _owner = owner; _reactionTime = reactionTime; _aimAccuracy = aimAccuracy; _aimPersistence = aimPersistence; Initialize(); }
///<summary> ///when this is called the trigger determines if the entity is within ///the trigger's region of influence. If it is then the trigger will be ///triggered and the appropriate action will be taken. ///</summary> ///<param name="bot">entity activating the trigger</param> public override void Try(BotEntity bot) { if (!IsActive || !IsTouchingTrigger(bot.Position, bot.BoundingRadius)) return; TriggeringBot = bot; bot.IncreaseHealth(HealthGiven); Deactivate(); }
///<summary> ///constructor ///</summary> ///<param name="owner"></param> public WeaponRailgun(BotEntity owner) : base(WeaponTypes.Railgun, GameManager.GameManager.Instance.Parameters.RailgunDefaultRounds, GameManager.GameManager.Instance.Parameters.RailgunMaxRoundsCarried, GameManager.GameManager.Instance.Parameters.RailgunFiringFreq, GameManager.GameManager.Instance.Parameters.RailgunIdealRange, GameManager.GameManager.Instance.Parameters.SlugMaxSpeed, owner) { //setup the fuzzy module InitializeFuzzyModule(); }
///<summary> ///Constructor for composite goal FollowPath ///</summary> ///<param name="bot">Bot entity that owns this goal</param> ///<param name="path">path to follow</param> public FollowPath(BotEntity bot, List<PathEdge> path) : base(bot, GoalTypes.FollowPath) { _path = path; _sourceNodeIndex = bot.PathPlanner.GetClosestNodeToPosition(path[0].Source); _destinationNodeIndex = bot.PathPlanner.GetClosestNodeToPosition( path[path.Count - 1].Destination); _usedLookup = Bot.CalculateTimeToReachPosition( path[path.Count - 1].Destination, out _timeExpected); _startTime = Time.TimeNow; }
///<summary> ///constructor for atomic goal SeekToPosition ///</summary> ///<param name="bot">bot entity that owns this goal</param> ///<param name="destination">destination</param> public SeekToPosition(BotEntity bot, Vector2 destination) : base(bot, GoalTypes.SeekToPosition) { _destination = destination; _timeExpected = 0.0f; _sourceNodeIndex = bot.PathPlanner.GetClosestNodeToPosition( bot.Position); _destinationNodeIndex = bot.PathPlanner.GetClosestNodeToPosition( destination); }
///<summary> ///when triggered this adds the bot that made the sound to the ///triggering bot's perception by sending a message to be processed by ///the triggering bot's sensory memory. ///</summary> ///<param name="bot"></param> public override void Try(BotEntity bot) { //is this bot within range of this sound if (!IsTouchingTrigger(bot.Position, bot.BoundingRadius)) return; TriggeringBot = bot; MessageDispatcher.Instance.DispatchMsg( (int) MessageDispatcher.SEND_MSG_IMMEDIATELY, MessageDispatcher.SENDER_ID_IRRELEVANT, bot.ObjectId, MessageTypes.GunshotSound, SoundSource); }
///<summary> ///constructor ///</summary> ///<param name="owner"></param> public WeaponShotgun(BotEntity owner) : base(WeaponTypes.Shotgun, GameManager.GameManager.Instance.Parameters.ShotgunDefaultRounds, GameManager.GameManager.Instance.Parameters.ShotgunMaxRoundsCarried, GameManager.GameManager.Instance.Parameters.ShotgunFiringFreq, GameManager.GameManager.Instance.Parameters.ShotgunIdealRange, GameManager.GameManager.Instance.Parameters.PelletMaxSpeed, owner) { _numBallsInShell = GameManager.GameManager.Instance.Parameters.ShotgunNumBallsInShell; _spread = GameManager.GameManager.Instance.Parameters.ShotgunSpread; //setup the fuzzy module InitializeFuzzyModule(); }
///<summary> ///constructor for atomic goal TraverseEdge ///</summary> ///<param name="bot">bot entity that owns this goal</param> ///<param name="edgeToFollow">edge to follow</param> ///<param name="lastEdgeInPath">true if last edge in path</param> public TraverseEdge( BotEntity bot, PathEdge edgeToFollow, bool lastEdgeInPath) : base(bot, GoalTypes.TraverseEdge) { _edgeToFollow = edgeToFollow; _timeExpected = 0.0f; _lastEdgeInPath = lastEdgeInPath; _sourceNodeIndex = bot.PathPlanner.GetClosestNodeToPosition( edgeToFollow.Source); _destinationNodeIndex = bot.PathPlanner.GetClosestNodeToPosition( edgeToFollow.Destination); }
///<summary> ///constructor ///</summary> ///<param name="shooter"></param> ///<param name="target"></param> ///<param name="entitySceneObject"></param> public ProjectileBolt( BotEntity shooter, Vector2 target, IEntitySceneObject entitySceneObject) : base(entitySceneObject, target, shooter.ObjectId, shooter.Position, Vector2.Normalize(target - shooter.Position), (int) GameManager.GameManager.Instance.Parameters.BoltDamage, GameManager.GameManager.Instance.Parameters.BotScale, GameManager.GameManager.Instance.Parameters.BoltMaxSpeed, GameManager.GameManager.Instance.Parameters.BoltMass, GameManager.GameManager.Instance.Parameters.BoltMaxForce) { _previousPosition = Position; }
///<summary> ///Constructor for Think composite goal. If <paramref name="emptyBrain"/> ///is false, loads 'brain' with default evaluators and random biases. ///Otherwise, caller must manually add evaluators and biases. ///</summary> ///<param name="bot">Bot that owns this goal</param> ///<param name="emptyBrain">if false, don't add evaluators</param> public Think(BotEntity bot, bool emptyBrain) : base(bot, GoalTypes.Think) { if (emptyBrain) return; //these biases could be loaded in from a script on a per bot basis //but for now we'll just give them some random values const float lowRangeOfBias = 0.5f; const float highRangeOfBias = 1.5f; float healthBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); float exploreBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); float attackBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); //float evadeBias = // TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); float shotgunBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); float rocketLauncherBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); float railgunBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); //create the evaluator objects if(GameManager.GameManager.Instance.Parameters.PlayCaptureTheFlag) { float flagBias = TorqueUtil.GetRandomFloat(lowRangeOfBias, highRangeOfBias); _evaluators.Add(new EvaluatorCaptureFlag(flagBias)); } _evaluators.Add(new EvaluatorGetHealth(healthBias)); _evaluators.Add(new EvaluatorExplore(exploreBias)); _evaluators.Add(new EvaluatorAttackTarget(attackBias)); //_evaluators.Add(new EvaluatorEvadeBot(evadeBias)); _evaluators.Add(new EvaluatorGetWeapon(shotgunBias, WeaponTypes.Shotgun)); _evaluators.Add(new EvaluatorGetWeapon(railgunBias, WeaponTypes.Railgun)); _evaluators.Add(new EvaluatorGetWeapon(rocketLauncherBias, WeaponTypes.RocketLauncher)); }
///<summary> ///constructor ///</summary> ///<param name="source"></param> ///<param name="range"></param> public TriggerSoundNotify(BotEntity source, float range) : base(new EntitySceneObject(), (int) GameManager.GameManager.Instance.Parameters.BotTriggerUpdateFreq) { //TODO: integrate with Torque //SceneObject.CreateWithCollision = false; //SceneObject.CreateWithPhysics = false; _soundSource = source; //set position and range Position = SoundSource.Position; BoundingRadius = range; //create and set this trigger's region of fluence AddCircularTriggerRegion(Position, BoundingRadius); }
//adds the appropriate goal to the given bot's brain public override void SetGoal(BotEntity bot) { bot.Brain.AddGoalExplore(); //GoalComponent gc = // bc.Components.FindComponent<GoalComponent>(); //if (gc != null) //{ // if (gc.Goal != null) // { // Think t = gc.Goal as Think; // if (t != null) // { // t.AddGoalExplore(); // } // } //} }