Britbot
Enemy.cs
Go to the documentation of this file.
00001 #region #Usings
00002 
00003 using System;
00004 using System.Collections.Generic;
00005 using System.Linq;
00006 using System.Threading;
00007 using Pirates;
00008 
00009 #endregion
00010 
00011 namespace Britbot
00012 {
00016     public static class Enemy
00017     {
00018         #region Static Fields & Consts
00019 
00023         public static int EnemyIntelligenceSuspicionCounter = 0;
00024 
00025         #endregion
00026 
00027         #region Fields & Properies
00028 
00032         public static List<EnemyGroup> Groups { get; private set; }
00033 
00034         #endregion
00035 
00036         #region Constructors & Initializers
00037 
00041         static Enemy()
00042         {
00043             Enemy.Groups = new List<EnemyGroup>();
00044         }
00045 
00046         #endregion
00047 
00054         private static List<EnemyGroup> AnalyzeEnemyGroups(CancellationToken cancellationToken)
00055         {
00056             EnemyGroup[] analysis = Enemy.AnalyzeFull(cancellationToken).ToArray();
00057 
00058             if (Groups.Count == 0)
00059                 return analysis.ToList();
00060 
00061             List<EnemyGroup> veteranGroups = new List<EnemyGroup>(analysis.Length);
00062             bool[] removeAtAnalysis = new bool[analysis.Length];
00063 
00064             for (int i = 0; i < analysis.Length; i++)
00065             {
00066                 //Throwing an exception if cancellation was requested.
00067                 cancellationToken.ThrowIfCancellationRequested();
00068 
00069                 EnemyGroup enemyGroup = analysis[i];
00070                 foreach (EnemyGroup veteran in Enemy.Groups)
00071                 {
00072                     //Throwing an exception if cancellation was requested.
00073                     cancellationToken.ThrowIfCancellationRequested();
00074 
00075                     /*
00076                      * check if the groups are the same.
00077                      * Note that Equals() does a contextual comparison and not reference comparison
00078                      * (I overrided it to check if the pirates in each enemy group are the same)                    
00079                      */
00080                     if (veteran.Equals(enemyGroup))
00081                     {
00082                         /* 
00083                          * note that we are adding the group already in the old Groups list
00084                          * it's the same object
00085                          */
00086                         veteranGroups.Add(veteran);
00087                         removeAtAnalysis[i] = true;
00088                         break;
00089                     }
00090                 }
00091             }
00092 
00093             //add the groups to the veteran list..
00094             veteranGroups.AddRange(analysis.Where((t, i) => !removeAtAnalysis[i]));
00095 
00096             //..and return
00097             return veteranGroups;
00098         }
00099 
00104         public static bool ShouldWeTryToCatchEnemyShips()
00105         {
00106             return Enemy.EnemyIntelligenceSuspicionCounter <= Magic.NumberOfTimesTillWeLearn;
00107         }
00108 
00116         private static List<EnemyGroup> AnalyzeFull(CancellationToken cancellationToken)
00117         {
00118             List<EnemyGroup> updatedGroups = new List<EnemyGroup>();
00119             IEnumerable<Pirate> enemyAlivePirates = Bot.Game.AllEnemyPirates().Where(p => !p.IsLost);
00120 
00121             //iterate over all the alive pirate of the enemy
00122             foreach (Pirate pete in enemyAlivePirates)
00123             {
00124                 //Throwing an exception if cancellation was requested.
00125                 cancellationToken.ThrowIfCancellationRequested();
00126 
00127                 //create a new group and add the current pirate to it
00128                 EnemyGroup newGroup = new EnemyGroup();
00129                 newGroup.EnemyPirates.Add(pete.Id);
00130 
00131                 //check if there are any older group already containing the current pirate
00132                 List<EnemyGroup> containsPete = updatedGroups.Where(g => g.IsInGroup(pete.Id)).ToList();
00133                 if (containsPete.Count > 0)
00134                 {
00135                     //if there are, remove these groups
00136                     updatedGroups.RemoveAll(g => g.IsInGroup(pete.Id));
00137 
00138                     //Add the pirates from the groups we removed to the current new group
00139                     foreach (EnemyGroup gr in containsPete)
00140                     {
00141                         //Throwing an exception if cancellation was requested.
00142                         cancellationToken.ThrowIfCancellationRequested();
00143 
00144                         newGroup.EnemyPirates.AddRange(gr.EnemyPirates);
00145                     }
00146                 }
00147 
00148                 //important, it must be here or direction cant be calculated
00149                 //Set location
00150                 newGroup.PrevLoc = newGroup.GetLocation();
00151 
00152                 //add the new group to the list of groups
00153                 updatedGroups.Add(newGroup);
00154             }
00155 
00156             return updatedGroups;
00157         }
00158 
00164         public static void Update(CancellationToken cancellationToken)
00165         {
00166             //write out the enemy suspiction counter
00167             Logger.Write("Enemy Suspiction: " + Enemy.EnemyIntelligenceSuspicionCounter);
00168 
00169             //update the enemy data
00170             List<EnemyGroup> updated = Enemy.AnalyzeEnemyGroups(cancellationToken);
00171 
00172             //update the enemyGroups by logical stuff
00173             Enemy.Groups = Enemy.Groups.Intersect(updated).ToList();
00174             Enemy.Groups = Enemy.Groups.Union(updated).ToList();
00175 
00176             //update heading in all groups
00177             Enemy.Groups.ForEach(eGroup => eGroup.Update());
00178         }
00179     }
00180 }