示例#1
0
        IProcessableWorld IWorldGenerator.Generate(Action <string> feedback)
        {
            feedback("Initializing Script Engine");
            Engine.Execute <bool>("true", Engine.NewSession);
            feedback("Creating world");
            World world     = new World(_dailyNotifications, _liveNotifications, _dataLock);
            int   zoneCount = ConfigurationManager.Config.NumberOfRegions;

            feedback("Generating base shapes");
            world.Size = ConfigurationManager.Config.WorldSize;
            List <VoronoiSite> sites = Generator.Create(world.Size.X, world.Size.Y, zoneCount, 1, 1256);

            feedback("Dividing the world");
            Dictionary <string, Zone> zones = new Dictionary <string, Zone>();

            foreach (VoronoiSite site in sites)
            {
                Zone zone = (Zone)site;
                zones.Add(zone.Id, zone);
                site.ZoneId = zone.Id;
            }
            feedback("Meeting new neighbourgs");
            foreach (VoronoiSite site in sites)
            {
                Zone zone = zones[site.ZoneId];
                foreach (VoronoiSite neighbourgSite in site.Neighbourgs)
                {
                    Zone            neighbourg   = zones[neighbourgSite.ZoneId];
                    List <Vector3D> commonPoints = zone.Points.Where(p => neighbourg.Points.Contains(p)).ToList();
                    if (commonPoints.Count != 2)
                    {
                        continue;
                    }
                    zone.AddAdjacency(new ZoneAdjacency(zone, neighbourg, commonPoints));
                }
            }
            feedback("Expanding provinces");
            //foreach (int clusterId in sites.Where(s=>!s.IsWater).Select(s=>s.Cluster.Id).Distinct())
            //{
            //    const int targetSize = 4;
            //    List<Zone> todo = sites.Where(s=>s.Cluster.Id == clusterId).Select(s=>zones[s.ZoneId]).OrderByRandom().ToList();
            //    int numberOfClusters = (todo.Count/targetSize)+1;
            //    List<ZoneCluster> clusters = new List<ZoneCluster>();
            //    //First clusterisation
            //    for (int i = 0; i < numberOfClusters; i++)
            //    {
            //        Zone seed = todo.RandomItem();
            //        clusters.Add(new ZoneCluster {seed});
            //        todo.Remove(seed);
            //    }
            //    while(todo.Count!=0)
            //    {
            //        foreach (ZoneCluster cluster in clusters)
            //        {
            //            Zone neighbourg =
            //                todo.FirstOrDefault(
            //                    z => cluster.SelectMany(c => c.Adjacencies.Select(a => a.Neighbourg)).Contains(z));
            //            if (neighbourg == null)
            //                continue;
            //            cluster.Add(neighbourg);
            //            todo.Remove(neighbourg);
            //        }
            //    }
            //    //Optimization to try to reach the optimal number of zones per cluster
            //    int optimumFunction;
            //    do
            //    {
            //        optimumFunction = clusters.Sum(c => c.Count * c.Count);
            //        foreach (ZoneCluster currentCluster in clusters.OrderByDescending(c=>c.Count))
            //        {
            //            List<ZoneCluster> neighbourgClusters = clusters
            //                .Where(
            //                    c =>
            //                        c.Any(p => currentCluster.SelectMany(x => x.Neighbourgs).Contains(p)) &&
            //                        c != currentCluster)
            //                .OrderBy(c => c.Count)
            //                .ToList();
            //            neighbourgClusters = neighbourgClusters.Where(c => c.Count < currentCluster.Count).ToList();
            //            foreach (ZoneCluster neighbourgCluster in neighbourgClusters)
            //            {
            //                if(neighbourgCluster.Count >= currentCluster.Count)
            //                    continue;
            //                foreach (Zone switchingZone in
            //                    currentCluster
            //                    .Where(p => neighbourgCluster.SelectMany(x => x.Neighbourgs).Contains(p))
            //                    .OrderByRandom())
            //                {
            //                    if(currentCluster.Count == 0)
            //                        break;
            //                    if (IsContiguousCluster(currentCluster, switchingZone))
            //                    {
            //                        neighbourgCluster.Add(switchingZone);
            //                        currentCluster.Remove(switchingZone);
            //                        break;
            //                    }
            //                }
            //            }
            //        }
            //    } while (optimumFunction != clusters.Sum(c => c.Count * c.Count));
            //    //Actual creation of the provinces
            //    foreach (ZoneCluster cluster in clusters)
            //        world.ProvinceManager.CreateProvince(new LandProvince(world, cluster));
            //}


            world.ProvinceManager.LoadProvinces(
                sites.Where(s => !s.IsWater).Select(s => new LandProvince(world, zones[s.ZoneId])).
                Union <Province>(sites.Where(s => s.IsWater).Select(s => new SeaProvince(world, new List <Zone> {
                zones[s.ZoneId]
            }))));

            feedback("Planting fields");
            foreach (LandProvince province in world.ProvinceManager.LandProvinces)
            {
                int numberOfResources = RandomGenerator.Get(1, 5);
                for (int i = 0; i < numberOfResources; i++)
                {
                    province.AddResource(
                        ResourceTypes.Types
                        .Except(province.Resources.Select(r => r.Type))
                        .RandomWeightedItem(r => r.Probability.For(province))
                        , world.ProvinceManager.ResourceLevels.RandomWeightedItem((l) => 1.0f));
                }
            }
            feedback("Forging realms");
            for (int i = 0; i < 11; i++)
            {
                world.RealmManager.CreateRealm(new Realm("Realm " + i));
            }
            feedback("Spreading realms");
            List <Tuple <Vector3D, Realm> > realmPosition =
                world.ProvinceManager.LandProvinces.OrderByRandom()
                .Take(world.RealmManager.Realms.Count())
                .Select(p => p.Center)
                .Zip(world.RealmManager.Realms, (v, r) => new Tuple <Vector3D, Realm>(v, r)).ToList();

            foreach (LandProvince province in world.ProvinceManager.LandProvinces)
            {
                realmPosition.MinBy(t => Vector3D.Distance(province.Center, t.Item1)).Item2.AddProvince(province);
            }
            feedback("Launching the fleets");
            foreach (Realm realm in world.RealmManager.Realms)
            {
                world.FleetManager.CreateFleet(new Fleet(world, "Royal fleet of " + realm.Name, realm, world.ProvinceManager.SeaProvinces.RandomItem().Zones.RandomItem(), new List <Ship> {
                    new Ship()
                }));
            }
            feedback("Polishing");
            return(world);
        }