|
Britbot
|
00001 #define MAP_DEBUG 00002 #undef MAP_DEBUG 00003 00004 #region #Usings 00005 00006 using System; 00007 using System.Collections.Generic; 00008 using Britbot.PriorityQueue; 00009 using Pirates; 00010 00011 #endregion 00012 00013 namespace Britbot 00014 { 00018 internal static partial class Navigator 00019 { 00020 #region Static Fields & Consts 00021 00022 public static List<long> time = new List<long>(); 00023 00024 #endregion 00025 00035 public static Direction CalculateDirectionToStationeryTarget(Location myLoc, HeadingVector myHeading, 00036 Location target) 00037 { 00038 /* 00039 00040 //get the desired direction 00041 HeadingVector desiredVector = HeadingVector.CalcDifference(myLoc, target); 00042 00043 //variable for the best direction so far 00044 Direction bestDirection = Direction.NOTHING; 00045 double directionFitCoeff = -1; 00046 00047 //going over all directions 00048 foreach (Direction dir in Bot.Game.GetDirections(myLoc, target)) 00049 { 00050 //calculate new heading vector if we choose this direction 00051 HeadingVector newHeading = HeadingVector.adjustHeading(myHeading, dir); 00052 //calculate the dot product with the desired direction and normalize, if it is close to 1 it 00053 //means that we are almost in the right direction 00054 double newFitCoef = newHeading.Normalize() * desiredVector.Normalize(); 00055 00056 //check if this direction is better (coefficient is larger) then the others 00057 if (newFitCoef > directionFitCoeff) 00058 { 00059 //replace best 00060 bestDirection = dir; 00061 directionFitCoeff = newFitCoef; 00062 } 00063 } 00064 00065 //return best direction found 00066 return bestDirection;*/ 00067 Logger.BeginTime("CalculateDirectionToStationeryTarget"); 00068 Direction d; 00069 //first check if we are already at the target 00070 if (myLoc.Equals(target)) 00071 d = Direction.NOTHING; 00072 else 00073 //otherwise use the A* thing 00074 00075 d = Navigator.CalculatePath(myLoc, target); 00076 Logger.StopTime("CalculateDirectionToStationeryTarget"); 00077 return d; 00078 } 00079 00091 public static Direction CalculateDirectionToMovingTarget(Location myLoc, HeadingVector myHeading, 00092 Location target, HeadingVector targetHeading) 00093 { 00094 //defining parameters for calculation (see image 1 under calculations) 00095 double a = targetHeading.Norm1(); 00096 double b = target.Col - myLoc.Col; 00097 double c = targetHeading.X; 00098 double d = target.Row - myLoc.Row; 00099 double e = targetHeading.Y; 00100 00101 //calculating r, hopefully 00102 double r = Navigator.SolveStupidEquation(a, b, c, d, e); 00103 00104 //finally, calculating the intersection point 00105 Location intersection = HeadingVector.AddvanceByVector(target, r * targetHeading); 00106 00107 //returning path to intersection 00108 return Navigator.CalculateDirectionToStationeryTarget(myLoc, myHeading, intersection); 00109 } 00110 00122 public static double SolveStupidEquation(double a, double b, double c, double d, double e) 00123 { 00124 //TODO fix this 00125 int[] signs = {-1, 1}; 00126 //there are 4 options, going over them 2 by 2 00127 for (int i = 0; i <= 1; i++) //i is the sign of c in r 00128 { 00129 int cSign = signs[i]; 00130 for (int j = 0; j <= 1; j++) //j is the sign of e in r 00131 { 00132 int eSign = signs[j]; 00133 double r = -(cSign * b + eSign * d) / (a + cSign * c + eSign * e); 00134 00135 //check if r isn't positive, if so we can skip it 00136 if (r <= 0) 00137 continue; 00138 00139 //else check the critirions 00140 if ((cSign * c * r <= -cSign * b) && (eSign * e * r <= -eSign * d)) 00141 { 00142 //it is (probably?) the correct r 00143 return r; 00144 } 00145 } 00146 } 00147 00148 //if we are here then i am wrong :) 00149 Logger.Write("MATAN K IS AN IDIOT"); 00150 return 1; 00151 } 00152 00161 public static double CalcDistFromLine(Location point, Location linePoint, HeadingVector dir) 00162 { 00163 //first check if no direction 00164 if (dir.NormSquared() == 0) 00165 return Bot.Game.Distance(point, linePoint); 00166 00167 //TODO fix this - Matan Kom 00168 //Find the difference vector between the point and the line point 00169 HeadingVector dif = HeadingVector.CalcDifference(point, linePoint); 00170 //find the minimum t parameter 00171 double tMin = (-1 / dir.NormSquared()) * dir * dif; 00172 00173 //calculating actual distance (see calculation) 00174 return (dif + tMin * dir).Norm(); 00175 ; 00176 } 00177 00185 public static int ComparePirateByDirection(int p1, int p2, HeadingVector hv) 00186 { 00187 HeadingVector originDif = new HeadingVector(Bot.Game.GetMyPirate(p1).Loc.Col, 00188 Bot.Game.GetMyPirate(p1).Loc.Row); 00189 int coef; 00190 00191 if (originDif * hv > 0) 00192 coef = 1; 00193 else 00194 coef = -1; 00195 //calculate both pirates position on the line created by hv 00196 double p1Dist = Navigator.CalcDistFromLine(new Location(0, 0), (Bot.Game.GetMyPirate(p1)).Loc, 00197 hv.Orthogonal()); 00198 double p2Dist = Navigator.CalcDistFromLine(new Location(0, 0), (Bot.Game.GetMyPirate(p2)).Loc, 00199 hv.Orthogonal()); 00200 00201 return coef * p1Dist.CompareTo(p2Dist); 00202 } 00203 00211 public static bool IsReachable(Location group, Location target, HeadingVector targetHeading) 00212 { 00213 //if the target is stationary then return true 00214 if (targetHeading.Norm() == 0) 00215 return true; 00216 //first check if it is running away (its direction is about the same as the difference between you 00217 if (HeadingVector.CalcDifference(group, target) * targetHeading > 0) 00218 return false; 00219 00220 00221 //----------------------calculation of naive maximum intersection---------------------- 00222 HeadingVector diffVector = HeadingVector.CalcDifference(target, group); 00223 00224 double cosAlpha = diffVector.Normalize() * targetHeading.Normalize(); 00225 double sacleCoeff = diffVector.Norm() * cosAlpha; 00226 00227 Location maxIntersection = HeadingVector.AddvanceByVector(target, sacleCoeff * targetHeading.Normalize()); 00228 //---------------------------------------------------------------------------------------- 00229 00230 //to account for numeric mistakes we take antitolerance coefficient 00231 const int antiToleranceCoeff = 2; 00232 00233 //compare distances 00234 //check who is closer 00235 if (Bot.Game.Distance(group, maxIntersection) < 00236 Bot.Game.Distance(target, maxIntersection) - antiToleranceCoeff) 00237 return true; 00238 00239 return false; 00240 } 00241 00250 public static Direction CalculatePath(Location start, Location target) 00251 { 00252 Logger.BeginTime("CalculatePath"); 00253 //first set up the for a new target calculation 00254 Node.SetUpCalculation(target); 00255 //Priority queue of the currently checked nodes. Thank You BlueRaja 00256 HeapPriorityQueue<Node> openset = new HeapPriorityQueue<Node>(Bot.Game.GetCols() * Bot.Game.GetRows()); 00257 00258 //set the beginning 00259 Node beginning = Node.GetLocationNodeFromMap(start); 00260 openset.Enqueue(beginning, beginning.F()); 00261 00262 //begin the iteration 00263 while (openset.Count > 0) 00264 { 00265 //get the current Node from the top of the openset priority queue 00266 Node currentNode = openset.Dequeue(); 00267 00268 //check if it is out target, if so we are done 00269 if (currentNode.Loc.Equals(target)) 00270 break; 00271 00272 //set current node status 00273 currentNode.IsEvaluated = true; 00274 00275 //going over the Neighbors of the current cell 00276 foreach (Node neighbor in currentNode.GetNeighbors()) 00277 { 00278 //if we already calculated this neighbor, skip to the next 00279 if (neighbor.IsEvaluated) 00280 continue; 00281 00282 //calculate the new G score from this rout 00283 double tentativeG = currentNode.G + neighbor.Weight; 00284 // double tentativeG = currentNode.G + 1; 00285 00286 //if the neighbor isn't in the open set 00287 //or we just found a better score for him (tentativeG < G) 00288 //or if G value is default -1 00289 //then add him to openset 00290 if ((!openset.Contains(neighbor)) || (neighbor.G == -1) || (tentativeG < neighbor.G)) 00291 { 00292 //update G score 00293 neighbor.G = tentativeG; 00294 00296 if (!openset.Contains(neighbor)) 00297 { 00298 openset.Enqueue(neighbor, neighbor.F()); 00299 } 00300 else //update 00301 { 00302 openset.UpdatePriority(neighbor, neighbor.F()); 00303 } 00304 } 00305 } 00306 //update current node 00307 currentNode.IsEvaluated = true; 00308 } 00309 Logger.StopTime("CalculatePath"); 00310 00311 #if MAP_DEBUG 00312 Node.DebugPasses(); 00313 #endif 00314 //now we have made the necessary calculations, just get the desired direction 00315 return Navigator.FindBestDirectionOutOfMap(beginning); 00316 } 00317 00324 private static Direction FindBestDirectionOutOfMap(Node beginning) 00325 { 00326 Node bestNextNode = null; 00327 00328 //go over the neighbors of the begining 00329 foreach (Node neighbor in beginning.GetNeighbors()) 00330 { 00331 //if bestNode is null update and skip to next iteration 00332 if (bestNextNode == null) 00333 { 00334 bestNextNode = neighbor; 00335 continue; 00336 } 00337 //if this neighbors score is better then update 00338 if (neighbor.F() < bestNextNode.F()) 00339 { 00340 bestNextNode = neighbor; 00341 } 00342 } 00343 //check if best node is null, if so then i am an idiot and YOU NEED TO INFORM ME OF THAT IMMIDIATELY 00344 if (bestNextNode == null) 00345 { 00346 Logger.Write("--------------------------------------------------------------------------"); 00347 Logger.Write("--------------------------------------------------------------------------"); 00348 Logger.Write("--------------------------------------------------------------------------"); 00349 Logger.Write(" Matan K is stupid as shit, please go and tell him that"); 00350 Logger.Write("--------------------------------------------------------------------------"); 00351 Logger.Write("--------------------------------------------------------------------------"); 00352 Logger.Write("--------------------------------------------------------------------------"); 00353 return Direction.NOTHING; 00354 //throw new Exception("Matan K is stupid as shit, please go and tell him that"); 00355 } 00356 return Bot.Game.GetDirections(beginning.Loc, bestNextNode.Loc)[0]; 00357 } 00358 00364 public static void UpdateMap(Group group) 00365 { 00366 Node.UpdateMap(group); 00367 } 00368 } 00369 }
1.7.6.1