/Code/src/com/game/AI/CalculateCirclePathTask.java

https://bitbucket.org/DeveloperUX/behaviortree · Java · 239 lines · 146 code · 36 blank · 57 comment · 29 complexity · e75170f545edf4b8caf5fdcf483cbf33 MD5 · raw file

  1. package com.game.AI;
  2. import java.util.Iterator;
  3. import java.util.Vector;
  4. import com.game.Constants;
  5. import com.game.Cursor;
  6. import com.game.Map;
  7. import com.game.Tile;
  8. import com.game.Vec2;
  9. /**
  10. * Task to calculate a path along the border of the nearest enemy
  11. * army.
  12. * @author Ying
  13. *
  14. */
  15. public class CalculateCirclePathTask extends LeafTask
  16. {
  17. /**
  18. * Max length of the path we want
  19. */
  20. private static final int pathLen = 10;
  21. /**
  22. * Minimum distance at which we attempt to circle
  23. * TODO: Calculate from map size.
  24. */
  25. private static final float minDistance = 40;
  26. /**
  27. * Creates a new instance of the CalculateCirclePathTask class
  28. * @param blackboard Reference to the AI Blackboard data
  29. */
  30. public CalculateCirclePathTask(Blackboard blackboard)
  31. {
  32. super(blackboard);
  33. }
  34. /**
  35. * Creates a new instance of the CalculateCirclePathTask class
  36. * @param blackboard Reference to the AI Blackboard data
  37. * @param name Name of the class, used for debugging
  38. */
  39. public CalculateCirclePathTask(Blackboard blackboard, String name)
  40. {
  41. super(blackboard, name);
  42. }
  43. /**
  44. * Confirms the data we need exists and that we are not
  45. * too far away to circle.
  46. */
  47. @Override
  48. public boolean CheckConditions()
  49. {
  50. LogTask("Checking conditions");
  51. if(bb.path == null && bb.closestEnemyCursor == null)
  52. {
  53. return false;
  54. }
  55. float distanceToEnemy = (float) bb.player.GetCursor().GetPosition().GetVectorTo(bb.closestEnemyCursor.GetPosition()).Length();
  56. if(distanceToEnemy > minDistance)
  57. {
  58. return false;
  59. }
  60. return true;
  61. }
  62. /**
  63. * Calculates a path of tiles around the enemy army
  64. * and stores it in the Blackboard
  65. */
  66. @Override
  67. public void DoAction()
  68. {
  69. LogTask("Doing action");
  70. Cursor chosenEnemy = bb.closestEnemyCursor;
  71. Vec2 lineToEnemy = bb.player.GetCursor().GetPosition().GetVectorTo(chosenEnemy.GetPosition());
  72. //Log.i("CircleStrategy", "Start: Selected enemy " + chosenEnemy.GetID());
  73. // Get the last empty tile before the cursor density
  74. Map mapRef = Blackboard.map;
  75. Tile curTile = mapRef.AtWorld(
  76. (int)chosenEnemy.GetPosition().X(),
  77. (int)chosenEnemy.GetPosition().Y());
  78. lineToEnemy.Normalize();
  79. lineToEnemy.Scale(Constants.TileWidth);
  80. // If no starting tile, we're done here.
  81. if(curTile == null)
  82. {
  83. LogTask("Not found initial tile, bailing out");
  84. this.control.FinishWithFailure();
  85. return;
  86. }
  87. //curTile.GetPos().Print("CircleStrategy", "Start: Enemy cursor closest tile is ");
  88. //lineToEnemy.Print("CircleStrategy", "Start: Line to enemy is ");
  89. while( curTile != null && curTile.GetMaxCapacity() > 0 && !curTile.HasEnemyDensity(chosenEnemy.GetPlayer().GetID()))
  90. {
  91. //curTile.GetPos().Print("CircleStrategy", "Start: Checking tile ");
  92. int x = (int)Math.round((curTile.GetRealPos().X()-lineToEnemy.X() ));
  93. int y = (int)Math.round((curTile.GetRealPos().Y()-lineToEnemy.Y()) );
  94. //curTile.GetRealPos().Print("CircleStrategy", "Start: (" + x+", " +y +") Checking tile ");
  95. Tile nextTile = mapRef.AtWorld( x , y);
  96. // To avoid infinite loops caused by float precision, if we're stuck on the same tile twice
  97. // Just jump to the closest in that direction.
  98. if(curTile == nextTile)
  99. {
  100. curTile = mapRef.AtWorld(
  101. (int)(curTile.GetRealPos().X()-(Math.signum(lineToEnemy.X()) * Constants.TileWidth) ) ,
  102. (int)(curTile.GetRealPos().Y()-(Math.signum(lineToEnemy.Y()) * Constants.TileWidth) ));
  103. }
  104. else
  105. {
  106. curTile = nextTile;
  107. }
  108. }
  109. //Log.i("CircleStrategy", "Start: Finished looking for initial tile");
  110. // If no starting tile, we're done here.
  111. if(curTile == null)
  112. {
  113. LogTask("Not found initial tile, bailing out");
  114. this.control.FinishWithFailure();
  115. return;
  116. }
  117. //curTile.GetPos().Print("CircleStrategy", "Start: Initial selected tile is ");
  118. // In the direction of the cursor, find the emptiest tile of the surrounding ones
  119. Vector<Tile> path= new Vector<Tile>();
  120. path.add(curTile);
  121. //Log.i("CircleStrategy", "Start: Looking for tile path");
  122. for(int i = 0; i < pathLen; i++)
  123. {
  124. Tile toAdd = null;
  125. curTile = mapRef.AtWorld(
  126. (int)(path.lastElement().GetRealPos().X()+lineToEnemy.X()),
  127. (int)(path.lastElement().GetRealPos().Y()+lineToEnemy.Y()));
  128. for(int j = 0; j < 9; j++)
  129. {
  130. Tile next = Blackboard.map.GetNeighbour(curTile, j);
  131. if(next != null)
  132. {
  133. if(toAdd == null)
  134. {
  135. if(next.GetCurrentCapacity() > 0)
  136. {
  137. if(NotInPath(next,path))
  138. {
  139. toAdd = next;
  140. }
  141. }
  142. }
  143. else
  144. {
  145. if(next.GetCurrentCapacity() > toAdd.GetCurrentCapacity())
  146. {
  147. if(NotInPath(next,path))
  148. {
  149. toAdd = next;
  150. }
  151. }
  152. }
  153. }
  154. }
  155. if(toAdd != null)
  156. {
  157. //toAdd.GetPos().Print("CircleStrategy", "Start: -- Adding tile ");
  158. path.add(toAdd);
  159. }
  160. else
  161. {
  162. //Log.i("CircleStrategy", "Start: No more tiles to add. Path ended");
  163. break;
  164. }
  165. }
  166. bb.path = path;
  167. this.control.FinishWithSuccess();
  168. }
  169. /**
  170. * Ends the task
  171. */
  172. @Override
  173. public void End()
  174. {
  175. LogTask("Ending");
  176. }
  177. /**
  178. * Starts the task
  179. */
  180. @Override
  181. public void Start()
  182. {
  183. LogTask("Starting");
  184. }
  185. /**
  186. * Checks if a said tile is not in the path so far
  187. * @param tile Tile to check against.
  188. * @return True if it's not on the path, false if it is
  189. */
  190. private boolean NotInPath(Tile tile, Vector<Tile> path)
  191. {
  192. boolean found = false;
  193. for (Iterator<Tile> iterator = path.iterator(); iterator.hasNext();)
  194. {
  195. if(tile == (Tile) iterator.next())
  196. {
  197. found = true;
  198. break;
  199. }
  200. }
  201. return !found;
  202. }
  203. }