/// <summary> /// Checks if any player is within 20 blocks of the minion. If they are, then this method /// sets the minion's target to the character and returns true, otherwise it sets the minion's /// target to null and returns false. /// /// If the minion can't see any enemies this method will put the minion in an idle time state /// </summary> /// <param name="m"></param> /// <returns></returns> public bool chooseNextNode(Minion m) { //Check if the closest player is within 20 blocks if (m.containingLevel.players.Count == 0) { return false; } float dist = Vector3.Distance(Constants.UnconvertFromXNAScene(m.position), Constants.UnconvertFromXNAScene(m.containingLevel.players[0].position)); Character closestPlayer = m.containingLevel.players[0]; //This probably breaks encapsulation for (int i = 1; i < m.containingLevel.players.Count; ++i) { float checkDist = Vector3.Distance(Constants.UnconvertFromXNAScene(m.position), Constants.UnconvertFromXNAScene(m.containingLevel.players[i].position)); if (checkDist < dist) { dist = checkDist; closestPlayer = m.containingLevel.players[i]; } } //Enemy out of sight if (dist / Constants.TILE_SIZE > Constants.MINION_SIGHT) { //m.gotoIdleState(); return false; } else { m.target = closestPlayer; return true; } }
private AI_STATE evaluateTreeRec(Minion m, ADecisionTreeNode root) { if (root == null) { throw new Exception("The decision tree isn't working properly. We hit a null node"); } //The tree should only have leaves and 2 child nodes...hopefully //if (root.isLeaf()) //{ // choice = root.chooseAction(m); // return false; //} //else //{ // if (root.chooseNextNode(m)) // { // return evaluateTreeRec(m, root.yes, out choice); // } // else // { // return evaluateTreeRec(m, root.no, out choice); // } //} AI_STATE result = root.chooseAction(m); if (result == AI_STATE.NO) { return evaluateTreeRec(m, root.no); } else if (result == AI_STATE.YES) { return evaluateTreeRec(m, root.yes); } return result; }
/// <summary> /// This method will evaluate if the minion's target is within attacking range. The target must /// be set by the previous node in the tree (SeeEnemy), otherwise this returns false /// </summary> /// <param name="m"></param> /// <returns></returns> private bool chooseNextNode(Minion m) { if (m.target == null) { return false; } return (Vector3.Distance(Constants.UnconvertFromXNAScene(m.position), Constants.UnconvertFromXNAScene(m.target.position))) / Constants.TILE_SIZE < Constants.MINION_ATTACK_RANGE; }
public override AI_STATE chooseAction(Minion m) { //If we don't see an enemy, patrol if (!chooseNextNode(m)) { return AI_STATE.NO; } else { return AI_STATE.YES; } }
public AI_STATE evaluateTree(Minion m) { return evaluateTreeRec(m, root); }
private bool chooseNextNode(Minion m) { return m.lastMoved <= 0; }
private bool chooseNextNode(Minion m) { //We have a path to the target if the queue is not null //??? return m.pathToTarget.Count != 0;// && !m.closeTo(m.pathToTarget.Peek()); }
public override AI_STATE chooseAction(Minion m) { //If we have a path to the target, follow it, otherwise calculate it return chooseNextNode(m) ? AI_STATE.YES : AI_STATE.NO; }
/// <summary> /// Call this method when traversing the decision tree, it will tell you whether /// to go left or right, depending on the situation of the level. If this node doesn't /// have any children, then use the result of chooseAction /// </summary> /// <param name="m"></param> /// <returns></returns> //public abstract bool chooseNextNode(Minion m); /// <summary> /// A method that returns the action associated with the given node. If this is /// an internal node it will return either left or right. Otherwise if it's a leaf /// it will return a specific action --HACK-- /// </summary> /// <param name="m"></param> /// <returns></returns> public abstract AI_STATE chooseAction(Minion m);