Britbot
void Britbot.Group.GenerateFormationInstructions ( Location[]  structure = null) [inline, private]

Generates instructions to form into optimal structure.

Parameters:
structureOptional pre-calculated structure to generate instructions to

Definition at line 517 of file Group.cs.

        {
            //reset the forming attempts counter
            this._formTurnsAttempt = 0;

            //find the average location of the group (not the center pirate!)
            Location center = this.FindCenter(false);

            //if we didn't get a pre calculated structure, calculate it below
            if (structure == null)
            {
                Logger.Write("Generating group structure");

                //Generate location array (structure) for the group
                while (true)
                {
                    try
                    {
                        //generate the structure
                        structure = this.GenerateGroupStructure(center).Flatten();
                        break;
                    }
                    catch (InvalidLocationException)
                    {
                        //if the location is invalid (i.e. the current center requires a location outside the map)
                        //advance the location towards the center of the map
                        center = center.AdvancePivot();
                    }
                }
            }

            Logger.Write("Generating group structure OK");

            //flag array to signal if a location in the structure is already taken 
            bool[] matchedLocations = new bool[structure.Length];

            //the orders to form to
            Dictionary<Pirate, Location> orders = new Dictionary<Pirate, Location>();

            //all the pirates in the group converted from their IDs
            List<Pirate> groupPirates = this.Pirates.Distinct().ToList().ConvertAll(p => Bot.Game.GetMyPirate(p));

            //sort the pirates by distance to the center (closer are first)
            groupPirates.Sort((b, a) => Bot.Game.Distance(a.Loc, center).CompareTo(Bot.Game.Distance(b.Loc, center)));

            //Match a pirate for each location in the structure
            foreach (Pirate pirate in groupPirates)
            {
                Location closestLocation = null;
                int minDistance = Bot.Game.GetCols() + Bot.Game.GetRows();
                int matchIndex = 0;

                //iterate over all the location in the structure
                for (int i = 0; i < structure.Length; i++)
                {
                    //Skip over taken spots
                    if (matchedLocations[i])
                        continue;

                    //find the best location in the structure, which is the closest one
                    if (Bot.Game.Distance(pirate.Loc, structure[i]) < minDistance)
                    {
                        minDistance = Bot.Game.Distance(pirate.Loc, structure[i]);
                        closestLocation = structure[i];
                        matchIndex = i;
                    }
                }

                //flag that this location is taken
                matchedLocations[matchIndex] = true;

                //add the instruction
                orders.Add(pirate, closestLocation);
            }

            //sort the orders so the closest pirates are first to avoid collisions and set them to the right class property
            this.FormOrders = orders.OrderBy(pair => Bot.Game.Distance(pair.Key.Loc, pair.Value))
                .ToDictionary(pair => pair.Key.Id, pair => pair.Value);

            //debug prints
            Logger.Write("====FORMING TO====");
            foreach (KeyValuePair<int, Location> formOrder in this.FormOrders)
            {
                Logger.Write(Bot.Game.GetMyPirate(formOrder.Key) + "," + formOrder.Value);
            }
            Logger.Write("==================");
        }