|
Britbot
|
00001 #region #Usings 00002 00003 using System.Collections.Generic; 00004 using Pirates; 00005 00006 #endregion 00007 00008 namespace Britbot 00009 { 00013 public class SmartIsland : ITarget 00014 { 00015 #region Fields & Properies 00016 00020 public readonly int Id; 00021 00025 public List<KeyValuePair<EnemyGroup,bool>> approachingEnemies; 00026 00033 public static List<SmartIsland> IslandList { get; private set; } 00034 00038 public int CaptureTurns 00039 { 00040 get { return Bot.Game.GetIsland(this.Id).CaptureTurns; } 00041 } 00042 00046 public int Value 00047 { 00048 get { return Bot.Game.GetIsland(this.Id).Value; } 00049 } 00050 00054 public Location Loc 00055 { 00056 get { return Bot.Game.GetIsland(this.Id).Loc; } 00057 } 00058 00062 public int TeamCapturing 00063 { 00064 get { return Bot.Game.GetIsland(this.Id).TeamCapturing; } 00065 } 00066 00070 public int TurnsBeingCaptured 00071 { 00072 get { return Bot.Game.GetIsland(this.Id).TurnsBeingCaptured; } 00073 } 00074 00078 public int Owner 00079 { 00080 get { return Bot.Game.GetIsland(this.Id).Owner; } 00081 } 00082 00086 private int _lastAssignmentTurn; 00087 00088 public int turnsTillColldown; 00089 00090 public int coolDownCount; 00091 #endregion 00092 00093 #region Constructors & Initializers 00094 00098 static SmartIsland() 00099 { 00100 SmartIsland.IslandList = new List<SmartIsland>(); 00101 foreach (Island island in Bot.Game.Islands()) 00102 { 00103 SmartIsland.IslandList.Add(new SmartIsland(island.Id)); 00104 } 00105 } 00106 00111 private SmartIsland(int encapsulate) 00112 { 00113 this.Id = encapsulate; 00114 this.approachingEnemies = new List<KeyValuePair<EnemyGroup, bool>>(); 00115 //this.SurroundingForces = new Queue<int>() 00116 this.coolDownCount = 0; 00117 this._lastAssignmentTurn = 0; 00118 } 00119 00120 #endregion 00121 00122 #region Interface Implementations 00123 00130 public Score GetScore(Group origin) 00131 { 00132 //constant defining how far to consider enemies capturing the island 00133 int CaptureZone = Bot.Game.GetAttackRadius(); 00134 00135 //check if there are more enemies than we can kill 00136 /*if (this.IsDangerousForGroup(origin) && Magic.UseBasicGlobalizing) 00137 { 00138 //Bot.Game.Debug("Danger--- Group " + origin.Id + " island: " + this.Id); 00139 return null; 00140 }*/ 00141 00142 //calculates the minimum distance between a group and said island 00143 int distance = Bot.Game.Distance(this.Loc, origin.FindCenter(true)); 00144 00145 //Amount of turns it takes to capture an island 00146 int captureTime = this.RealTimeTillCapture(Consts.ME); 00147 00148 //TODO this is disabled in the meanwhile because it caused us to lost 00149 //should be taken into consideration in the score globalizing function 00150 /*if (this.Owner == Consts.ENEMY) 00151 captureTime *= 2;*/ 00152 00153 //check if the island isn't already ours, if so disqualify it and return null 00154 // if (this.Owner != Consts.ME) 00155 return new Score(this, TargetType.Island, this.Value, this.NearbyEnemyCount(CaptureZone), 00156 distance + captureTime, this.TurnsToEnemyCapture(origin), this.islandDensity()); 00157 return null; 00158 } 00159 00164 public Location GetLocation() 00165 { 00166 return Loc; 00167 } 00168 00175 public Direction GetDirection(Group group) 00176 { 00177 //calculates the direction based on the geographical data from the game 00178 return Navigator.CalculateDirectionToStationeryTarget(group.FindCenter(true), group.Heading, GetLocation()); 00179 } 00180 00181 public TargetType GetTargetType() 00182 { 00183 return TargetType.Island; 00184 } 00185 00186 public string GetDescription() 00187 { 00188 return "Island, id: " + Id + " location: " + Loc; 00189 } 00190 00196 public bool Equals(ITarget operandB) 00197 { 00198 SmartIsland b = operandB as SmartIsland; 00199 if (b != null) 00200 { 00201 return this.Equals(b); 00202 } 00203 00204 return false; 00205 } 00206 00211 public void TargetAssignmentEvent() 00212 { 00213 00214 } 00215 00219 public void TargetDeAssignmentEvent() 00220 { 00221 } 00222 00223 #endregion 00224 00225 public override int GetHashCode() 00226 { 00227 return this.Id; 00228 } 00229 00230 public static bool IsNearNonOurIsland(Location loc, int Range) 00231 { 00232 foreach (SmartIsland island in SmartIsland.IslandList) 00233 { 00234 if (island.Owner == Consts.ME) 00235 continue; 00236 00237 if (Bot.Game.Distance(loc, island) < Range) 00238 return true; 00239 } 00240 return false; 00241 } 00242 00247 public int NearbyEnemyCount(int dangerRadius = 15) 00248 { 00249 int enemyCount = 0; //amount of enemy pirates in proximity to the Island 00250 /*int closestIslandDistance = 0; //The distance between this Island and the one nearest too it 00251 foreach (SmartIsland eIsland in SmartIsland.IslandList) 00252 //Calculates the distance between this island and the one nearest 00253 { 00254 int temp = Bot.Game.Distance(eIsland.Loc, this.Loc); 00255 if (temp < closestIslandDistance) 00256 { 00257 closestIslandDistance = temp; 00258 } 00259 }*/ 00260 foreach (EnemyGroup eGroup in Enemy.Groups) 00261 { 00262 double distance = eGroup.MinimalSquaredDistanceTo(this.Loc); 00263 //Checks if the group of islands is near the island and if they are getting closer or farther 00264 if (distance <= dangerRadius) 00265 { 00266 //Calculates the sum of pirates in proximity to the island 00267 //if distance is 0 then one of the pirates in on the island and we dont need to count it 00268 if (distance == 0) 00269 enemyCount = enemyCount + eGroup.EnemyPirates.Count - 1; 00270 else 00271 enemyCount = enemyCount + eGroup.EnemyPirates.Count; 00272 } 00273 } 00274 00275 return enemyCount; 00276 } 00277 00282 public int TurnsToEnemyCapture(Group myGroup) 00283 { 00284 int tempDistance; 00285 int minDistance = Bot.Game.GetCols() + Bot.Game.GetRows(); 00286 00287 foreach (EnemyGroup eGroup in Enemy.Groups) 00288 { 00289 tempDistance = Bot.Game.Distance(this.Loc, eGroup.GetLocation()); 00290 if ((minDistance > tempDistance) && (eGroup.GetMaxFightPower() >= myGroup.FightCount())) 00291 minDistance = tempDistance; 00292 } 00293 00294 return minDistance + this.CaptureTurns; 00295 } 00296 //TODO: Calculates the largest distance between islands and the shortest and creates a precentage 00297 // Another way: Calculate the distance to the nearest next island, the shorter the better 00298 public int islandDensity() 00299 { 00300 int distFromAllIslands=0 ; 00301 foreach (SmartIsland Islands in IslandList) 00302 { 00303 distFromAllIslands += Bot.Game.Distance(Islands.Loc, this.Loc); 00304 } 00305 //Note that a high score in this case is bad and therefor it is multiplied by -1 00306 //When used, the use of a coefficient will most likely be imperative 00307 return distFromAllIslands *-1 ; 00308 } 00309 00313 public void Update() 00314 { 00315 //---------------#Magic_Numbers-------------------- 00316 //constant defining how far to look for enemy ships 00317 //int DangerZone = 6 * Bot.Game.GetAttackRadius(); 00318 00319 //---------------#Magic_Numbers-------------------- 00320 /*const int HowLongToLookBack = 1; 00321 //add new data 00322 this.SurroundingForces.Enqueue(this.NearbyEnemyCount(Magic.DangerZone)); 00323 00324 //trim the end of the queue if needed 00325 if (this.SurroundingForces.Count > HowLongToLookBack) 00326 { 00327 this.SurroundingForces.Dequeue(); 00328 }*/ 00329 00330 //update enemy distances 00331 this.approachingEnemies.Clear(); 00332 foreach (EnemyGroup eGroup in Enemy.Groups) 00333 { 00334 // if(eGroup.MinimalETATo(this.Loc) < Magic.MaxEnemyPredictionDistnace) 00335 this.approachingEnemies.Add(new KeyValuePair<EnemyGroup, bool>(eGroup, eGroup.IsApproachingIsland(this))); 00336 } 00337 //sort the list by distance 00338 this.approachingEnemies.Sort( 00339 (e1, e2) => e1.Key.MinimalETATo(this.Loc).CompareTo(e2.Key.MinimalSquaredDistanceTo(this.Loc))); 00340 } 00341 00347 public double GetMinimumSquareDistanceFromEnemy() 00348 { 00349 //if isn't empty 00350 if (this.approachingEnemies.Count > 0) 00351 return this.approachingEnemies[0].Key.MinimalSquaredDistanceTo(this.Loc); 00352 00353 //otherwise return the constant in MAGIC representing the best case scenario 00354 return Magic.MaxCalculableDistance; 00355 } 00356 00357 public override string ToString() 00358 { 00359 return this.Debug(); 00360 } 00361 00362 00363 /*public int GetEnemyNum() 00364 { 00365 int max = 0; 00366 00367 00368 foreach (int s in this.SurroundingForces) 00369 { 00370 if (s > max) 00371 max = s; 00372 } 00373 return max; 00374 }*/ 00375 00376 public static void UpdateAll() 00377 { 00378 foreach (SmartIsland sIsland in SmartIsland.IslandList) 00379 { 00380 sIsland.Update(); 00381 } 00382 SmartIsland.DebugAll(); 00383 } 00384 00385 public string Debug() 00386 { 00387 return "Island " + this.Id + " enemies: " + string.Join(", ", this.approachingEnemies) + this.Loc; 00388 } 00389 00390 public static void DebugAll() 00391 { 00392 /*Bot.Game.Debug("--------ISLANDS DEBUG----------"); 00393 foreach (SmartIsland sIsland in SmartIsland.IslandList) 00394 sIsland.Debug();*/ 00395 } 00396 00403 public bool IsDangerousForGroup(Group g) 00404 { 00405 //Bot.Game.Debug("IsDangerousForGroup island: " + Id + " group " + g.Id); 00406 //calculate distance in turns till we reach the island 00407 int eta = Bot.Game.Distance(this.Loc, g.FindCenter(true)); 00408 00409 //find the distance of g from the island 00410 int distance = Bot.Game.Distance(this.Loc, g.FindCenter(true)); 00411 00412 00413 //go over all the enemy groups approaching and their distances 00414 //TODO: maybe consider the actual firepower of the enemy 00415 foreach (KeyValuePair<EnemyGroup,bool> eGroupPair in this.approachingEnemies) 00416 { 00417 if (!eGroupPair.Value) 00418 continue; 00419 00420 EnemyGroup eGroup = eGroupPair.Key; 00421 //calculate this enemy groups time of arival 00422 double EnemyETA = eGroup.MinimalETATo(this.Loc); 00423 00424 //read enemy force 00425 double enemyForce = eGroup.GetMaxFightPower(); 00426 00427 //We diffarentiate between two cases 00428 if (EnemyETA < distance) //case 1: Enemy is closer to the island then we are 00429 { 00430 //check if we arrive before capture 00431 if (distance < EnemyETA + this.RealTimeTillCapture(Consts.ENEMY)) 00432 { 00433 //the enemy who are closer are at disaddvantage since they lose one pirate capturing the island 00434 if (g.LiveCount() <= enemyForce - 1) 00435 return true; 00436 } 00437 } 00438 else //case 2: Enemy is farther away to the island then we are 00439 { 00440 //if the enemy reaches us before we capture 00441 if (EnemyETA < this.RealTimeTillCapture(Consts.ME) + distance) 00442 { 00443 //for the enemy who are farther, we are at a disaddvantage 00444 if ((enemyForce != 0) && (g.LiveCount() - 1 < enemyForce)) 00445 return true; 00446 00447 //special case: Manuver 00448 if ((enemyForce != 0) && (g.LiveCount() - 1 == enemyForce)) 00449 { 00450 //we would like to run from the island only when they are realy close so we will catch them 00451 if (eGroup.MinimalSquaredDistanceTo(this.Loc) < Magic.ManeuverDistance) 00452 { 00453 return true; 00454 } 00455 } 00456 } 00457 } 00458 } 00459 00460 //if we are here then everything is ok 00461 return false; 00462 } 00463 00470 public int RealTimeTillCapture(int conqueror) 00471 { 00472 //calculate total number of turns to capture (without partials) 00473 int totalCaptureTime; 00474 //check if conqueror is the owner 00475 if (this.Owner == conqueror) 00476 { 00477 totalCaptureTime = 0; 00478 } //if the isalnd is nutral 00479 else if (this.Owner == Consts.NO_OWNER) 00480 { 00481 totalCaptureTime = this.CaptureTurns; 00482 } //if the island is of the other team 00483 else 00484 { 00485 totalCaptureTime = 2 * this.CaptureTurns; 00486 } 00487 00488 //check if we already have some capture time 00489 if (this.TeamCapturing == conqueror) 00490 { 00491 return totalCaptureTime - this.TurnsBeingCaptured; 00492 } 00493 return totalCaptureTime; 00494 } 00495 00502 public static bool operator ==(SmartIsland a, SmartIsland b) 00503 { 00504 return object.Equals(a, b); 00505 } 00506 00513 public static bool operator !=(SmartIsland a, SmartIsland b) 00514 { 00515 return !object.Equals(a, b); 00516 } 00517 00523 protected bool Equals(SmartIsland other) 00524 { 00525 bool eq = this.Id == other.Id; 00526 return eq; 00527 } 00528 00534 public override bool Equals(object obj) 00535 { 00536 SmartIsland b = obj as SmartIsland; 00537 if (b != null) 00538 { 00539 return this.Equals(b); 00540 } 00541 return false; 00542 } 00543 } 00544 }
1.7.6.1