/// <summary>
        /// Reconstitutes the given tree into a new one (balances it)
        /// </summary>
        /// <param name="OldTree"></param>
        public Company_KDTree(Company_KDTree OldTree)
        {
            List<Company> CompanyList = new List<Company>();
            OldTree.GetAllCompanies(ref CompanyList);
            Company[] CompanyArray = CompanyList.ToArray();

            SplitDimensionIndex = 0;
            if (CompanyArray.Length > 2)
            {
                SortByDimension(ref CompanyArray, SplitDimensionIndex);
                int MedianIndex = CompanyArray.Length / 2;
                SplitPosition = CompanyArray[MedianIndex].Location[SplitDimensionIndex];
                Company[] LowerList = new Company[MedianIndex + 1];
                Company[] UpperList = new Company[CompanyArray.Length - MedianIndex - 1];
                Array.Copy(CompanyArray, 0, LowerList, 0, LowerList.Length);
                Array.Copy(CompanyArray, MedianIndex + 1, UpperList, 0, UpperList.Length);
                LessEqualNode = new Company_KDTree(SplitDimensionIndex, LowerList);
                GreaterNode = new Company_KDTree(SplitDimensionIndex, UpperList);
            }
            else
            {
                Constituents = CompanyArray;
                isLeafNode = true;
            }
        }
예제 #2
0
 public double DistanceTo(Company Other)
 {
     double Distance = 0.0;
     for (int i = 0; i < Location.Length; i++)
     {
         Distance += Math.Pow(Location[i] - Other.Location[i], 2);
     }
     Other.DistanceRegister = Math.Sqrt(Distance);
     return Other.DistanceRegister;
 }
 /// <summary>
 /// Organizes Companies by X Y Z coordinates
 /// More efficient to recreate a tree rather than update it
 /// </summary>
 /// <param name="ParentSplitDimensionIndex">Outside of this constructor, inputs should be -1</param>
 /// <param name="UnitList">Should be converted from a List</param>
 public Company_KDTree(int ParentSplitDimensionIndex, Company[] CompanyList)
 {
     SplitDimensionIndex = (ParentSplitDimensionIndex + 1) % 3;
     if (CompanyList.Length > 2)
     {
         SortByDimension(ref CompanyList, SplitDimensionIndex);
         int MedianIndex = CompanyList.Length / 2;
         SplitPosition = CompanyList[MedianIndex].Location[SplitDimensionIndex];
         Company[] LowerList = new Company[MedianIndex + 1];
         Company[] UpperList = new Company[CompanyList.Length - MedianIndex - 1];
         Array.Copy(CompanyList, 0, LowerList, 0, LowerList.Length);
         Array.Copy(CompanyList, MedianIndex + 1, UpperList, 0, UpperList.Length);
         LessEqualNode = new Company_KDTree(SplitDimensionIndex, LowerList);
         GreaterNode = new Company_KDTree(SplitDimensionIndex, UpperList);
     }
     else
     {
         Constituents = CompanyList;
         isLeafNode = true;
     }
 }
예제 #4
0
        public void Update()
        {
            Age += 0.01;

            //Assets slowly degrade and turn into money
            Assets *= Math.Pow(Math.E, -0.001 * SkillLevel);
            Money += Assets * (Math.Pow(Math.E, 0.0001 * SkillLevel) - 1.0);
            //Search through the closest businesses for the best bargains and opportunities
            List<Company> Shops = new List<Company>();
            double Distance = double.PositiveInfinity;
            Manager.Businesses.FindClosestBusinesses(this, ref Shops, ref Distance, MyGame.random.Next(5, 10));
            if (Dynasty == null)
            {
                if (Employer == null)
                {
                    //Look for a job or try to start one
                    if (Shops.Count > 0)
                    {
                        Shops[MyGame.random.Next(Shops.Count)].QueryForEmployment(this);
                        if (Employer == null)
                        {
                            Manager.FractionalDynasties += 0.05 * SkillLevel;
                            if (Manager.FractionalDynasties > 1.0 && Money > 10)
                            {
                                Manager.FractionalDynasties--;
                                Dynasty = new Conglomerate(Location, Money * 0.95);
                                Money *= 0.05;
                            }
                        }
                    }
                    else
                    {
                        //With nothing nearby, someone must be an entrepreneur
                        Manager.FractionalDynasties += 0.25 * SkillLevel;
                        if (Manager.FractionalDynasties > 1.0 && Money > 10)
                        {
                            Manager.FractionalDynasties--;
                            Dynasty = new Conglomerate(Location, Money * 0.95);
                            Money *= 0.05;
                        }
                    }
                }
                else
                {
                    //Consider quitting the job and starting a new Dynasty
                    if (MyGame.random.NextDouble() > 0.9)
                    {
                        Manager.FractionalDynasties += 0.01 * SkillLevel;
                        if (Manager.FractionalDynasties > 1.0 && Money > 10)
                        {
                            Manager.FractionalDynasties--;
                            Dynasty = new Conglomerate(Location, Money * 0.95);
                            Money *= 0.05;
                            Employer.Employees.Remove(this);
                            Employer = null;
                        }
                    }
                }
            }
            else
            {
                Dynasty.Update();
                if (Dynasty.Subsidaries.Count > 0)
                {
                    double SelfSalary = SkillLevel + Productivity;
                    if (Dynasty.Money > SelfSalary)
                    {
                        Dynasty.Money -= SelfSalary;
                        Money += SelfSalary;
                    }
                    else
                    {
                        Dynasty.Money *= 0.5;
                        Money += Dynasty.Money;
                    }
                }
                else
                {
                    Money += Dynasty.Money;
                    Contentness += Dynasty.SurplusInventory * Math.Pow(1.5, Dynasty.SurplusQuality);
                    Dynasty = null;
                }
            }

            if (Assets > Math.E)
            {
                Contentness -= Productivity / Math.Log(Assets);
            }
            else
            {
                Contentness -= Productivity;
            }
            //Iterate through the list of nearby Companies and buy goods with available money
            for (int i = 0; i < Shops.Count && Money > 0.0; i++)
            {
                if (Shops[i].Inventory > 0.0 && Shops[i].Effectiveness > 0.0)
                {
                    double units = Money / Shops[i].Price;
                    if (units > Shops[i].Inventory)
                    {
                        units = Shops[i].Inventory;
                    }
                    Money -= units * Shops[i].Price;
                    Shops[i].Inventory -= units;
                    Shops[i].Money += units * Shops[i].Price;
                    Assets += units * Shops[i].Effectiveness / 10.0;
                    Contentness += units * Shops[i].Effectiveness;
                }
            }
            //Evaluate the effects of Contentness on Productivity
            if (Contentness > 1)
            {
                Productivity += 0.001;
            }
            else if (Contentness < 0)
            {
                Productivity *= Math.Pow(Math.E, -0.001);
                Contentness /= 2;
            }
        }
 private static void SortByDimension(ref Company[] Unsorted, int DimensionIndex)
 {
     if (Unsorted.Length > 0)
     {
         List<List<Company>> Sorter = new List<List<Company>>();
         for (int i = 0; i < Unsorted.Length; i++)
         {
             Sorter.Add(new List<Company>());
             Sorter[i].Add(Unsorted[i]);
         }
         while (Sorter.Count > 1)
         {
             for (int i = 0; i < Sorter.Count - 1; i++)
             {
                 for (int a = 0; a < Sorter[i].Count; a++)
                 {
                     for (int b = 0; b < Sorter[i + 1].Count; b++)
                     {
                         if (Sorter[i + 1][b].Location[DimensionIndex] < Sorter[i][a].Location[DimensionIndex])
                         {
                             Sorter[i].Insert(a++, Sorter[i + 1][b]);
                             Sorter[i + 1].RemoveAt(b--);
                         }
                     }
                 }
                 Sorter[i].AddRange(Sorter[i + 1]);
                 Sorter.RemoveAt(i + 1);
             }
         }
         Unsorted = Sorter[0].ToArray();
     }
 }
 public void InsertCompany(Company Newbie)
 {
     if (isLeafNode)
     {
         Array.Resize<Company>(ref Constituents, Constituents.Length + 1);
         Constituents[Constituents.Length - 1] = Newbie;
     }
     else
     {
         if (Newbie.Location[SplitDimensionIndex] > SplitPosition)
         {
             GreaterNode.InsertCompany(Newbie);
         }
         else
         {
             LessEqualNode.InsertCompany(Newbie);
         }
     }
 }
 public void FindClosestBusinesses(Company Searcher
     , ref List<Company> CurrentClosest, ref double MaxDistance, int NumCompanies
     , double MinCapitalLevel, double MaxCapitalLevel)
 {
     if (isLeafNode)
     {
         for (int i = 0; i < Constituents.Length; i++)
         {
             if (Constituents[i].CapitalLevel > MinCapitalLevel
                 && Constituents[i].CapitalLevel < MaxCapitalLevel
                 && Constituents[i].Inventory > 0.0
                 && Constituents[i].Price > 0.0
                 && Searcher.DistanceTo(Constituents[i]) <= MaxDistance)
             {
                 if (CurrentClosest.Count == 0)
                 {
                     CurrentClosest.Add(Constituents[i]);
                 }
                 else
                 {
                     for (int j = CurrentClosest.Count - 1; j >= 0; j--)
                     {
                         if (Constituents[i].DistanceRegister > CurrentClosest[j].DistanceRegister)
                         {
                             CurrentClosest.Insert(j + 1, Constituents[i]);
                         }
                     }
                 }
             }
         }
         if (CurrentClosest.Count > NumCompanies)
         {
             CurrentClosest.RemoveRange(NumCompanies, CurrentClosest.Count - NumCompanies);
         }
     }
     else
     {
         if (Searcher.Location[SplitDimensionIndex] > SplitPosition)
         {
             GreaterNode.FindClosestBusinesses(Searcher
                 , ref CurrentClosest, ref MaxDistance, NumCompanies
                 , MinCapitalLevel, MaxCapitalLevel);
             if (Searcher.Location[SplitDimensionIndex] - MaxDistance < SplitPosition)
             {
                 LessEqualNode.FindClosestBusinesses(Searcher
                     , ref CurrentClosest, ref MaxDistance, NumCompanies
                     , MinCapitalLevel, MaxCapitalLevel);
             }
         }
         else
         {
             LessEqualNode.FindClosestBusinesses(Searcher
                 , ref CurrentClosest, ref MaxDistance, NumCompanies
                 , MinCapitalLevel, MaxCapitalLevel);
             if (Searcher.Location[SplitDimensionIndex] + MaxDistance > SplitPosition)
             {
                 GreaterNode.FindClosestBusinesses(Searcher
                     , ref CurrentClosest, ref MaxDistance, NumCompanies
                     , MinCapitalLevel, MaxCapitalLevel);
             }
         }
     }
 }