Пример #1
0
        //TODO Постараться объединить GetStartProvinceCoords и GetHomeProvinceCoords
        private TerrainCell GetHomeProvinceCoords(Globe globe, TerrainCell startProvince)
        {
            // Выбираем основной город, являющийся стартовым.
            // По городу определяем провинцию.

            var currentCubeCoords   = HexHelper.ConvertToCube(startProvince.Coords);
            var availableLocalities = globe.Localities
                                      .Where(x => x.Cell != startProvince)
                                      .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) > 2)
                                      .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) <= 5)
                                      .ToArray();

            Locality selectedLocality;

            if (availableLocalities.Any())
            {
                var localityIndex = _dice.Roll(0, availableLocalities.Count() - 1);
                selectedLocality = availableLocalities[localityIndex];
            }
            else
            {
                selectedLocality = globe.Localities.LastOrDefault();
            }

            if (selectedLocality == null)
            {
                //TODO Создать отдельный класс исключений GlobeGenerationException.
                throw new InvalidOperationException("Не удалось выбрать локацию для дома.");
            }

            return(selectedLocality.Cell);
        }
        /// <summary>
        /// Создание
        /// </summary>
        /// <param name="globe">Объект игрового мира, для которого создаётся локация.</param>
        /// <param name="cell">Провинция игрового мира из указанного выше <see cref="Globe" />,
        /// для которого создаётся локация.</param>
        /// <returns>
        /// Возвращает граф локация для провинции.
        /// </returns>
        public Task <GlobeRegion> GenerateRegionAsync(Globe globe, TerrainCell cell)
        {
            var locationSchemeSids = new[] {
                "rat-hole",
                "rat-kingdom",
                "demon-dungeon",
                "demon-lair",
                "crypt",
                "elder-place",
                "genomass-cave"
            };
            var region = new GlobeRegion(LocationBaseSize);

            for (var x = 0; x < LocationBaseSize; x++)
            {
                for (var y = 0; y < LocationBaseSize; y++)
                {
                    //var hasNodeRoll = _dice.Roll(6);
                    //if (hasNodeRoll <= 2)
                    //{
                    //    continue;
                    //}

                    var hasDundeonRoll = _dice.Roll(100);
                    if (hasDundeonRoll > 90)
                    {
                        var locationSidIndex = _dice.Roll(0, locationSchemeSids.Length - 1);
                        var locationSid      = locationSchemeSids[locationSidIndex];
                        var locationScheme   = _schemeService.GetScheme <ILocationScheme>(locationSid);
                        var node             = new GlobeRegionNode(x, y, locationScheme);
                        region.AddNode(node);
                    }
                    else
                    {
                        var hasCityRoll = _dice.Roll(100);

                        if (hasCityRoll > 90)
                        {
                            var locationScheme = _schemeService.GetScheme <ILocationScheme>("city");
                            var node           = new GlobeRegionNode(x, y, locationScheme)
                            {
                                IsTown = true
                            };
                            region.AddNode(node);
                        }
                        else
                        {
                            var locationScheme = _schemeService.GetScheme <ILocationScheme>("forest");
                            var node           = new GlobeRegionNode(x, y, locationScheme);
                            region.AddNode(node);
                        }
                    }
                }
            }

            return(Task.FromResult(region));
        }
Пример #3
0
        /// <summary>
        /// Создание
        /// </summary>
        /// <param name="globe">Объект игрового мира, для которого создаётся локация.</param>
        /// <param name="cell">Провинция игрового мира из указанного выше <see cref="Globe" />,
        /// для которого создаётся локация.</param>
        /// <returns>
        /// Возвращает граф локация для провинции.
        /// </returns>
        public Task <GlobeRegion> GenerateRegionAsync(Globe globe, TerrainCell cell)
        {
            var region = new GlobeRegion(LocationBaseSize);

            // Сейчас допускаем, что паттерны квадратные, меньше размера провинции.
            // Пока не вращаем и не искажаем.
            // Там, где может быть объект, гарантированно создаём один город и два подземелья.
            var regionDraft  = new GlobeRegionDraftValue[LocationBaseSize, LocationBaseSize];
            var startPattern = GlobeRegionPatterns.Start;
            var homePattern  = GlobeRegionPatterns.Home;
            // Расчитываем размер паттернов.
            // Исходим из того, что пока все паттерны квадратные и одинаковые по размеру.
            // Поэтому размер произвольного паттерна будет справедлив для всех остальных.
            // Паттерн старта выбран произвольно.
            var patternSize = startPattern.Values.GetUpperBound(0) - startPattern.Values.GetLowerBound(0) + 1;

            // Вставляем паттерны в указанные области
            ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), 1, 1);
            ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), LocationBaseSize - patternSize - 1, 1);
            ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), 1, LocationBaseSize - patternSize - 1);
            ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), LocationBaseSize - patternSize - 1, LocationBaseSize - patternSize - 1);
            if (globe.StartProvince == cell)
            {
                ApplyRegionPattern(ref regionDraft, startPattern, (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2);
            }
            else if (globe.HomeProvince == cell)
            {
                ApplyRegionPattern(ref regionDraft, homePattern, (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2);
            }
            else
            {
                ApplyRegionPattern(ref regionDraft, GetDefaultPattrn(), (LocationBaseSize - patternSize) / 2, (LocationBaseSize - patternSize) / 2);
            }

            for (var x = regionDraft.GetLowerBound(0); x <= regionDraft.GetUpperBound(0); x++)
            {
                for (var y = regionDraft.GetLowerBound(1); y <= regionDraft.GetUpperBound(1); y++)
                {
                    ValidateRegion(region, regionDraft, x, y);
                }
            }

            return(Task.FromResult(region));
        }
Пример #4
0
 public static void AddAgentToCell(Dictionary <TerrainCell, List <Agent> > cells, TerrainCell cell, Agent agent)
 {
     if (cells.TryGetValue(cell, out var list))
     {
         list.Add(agent);
     }
     else
     {
         list = new List <Agent> {
             agent
         };
         cells[cell] = list;
     }
 }
Пример #5
0
 public static void RemoveAgentToCell(Dictionary <TerrainCell, List <Agent> > cells, TerrainCell cell, Agent agent)
 {
     if (cells.TryGetValue(cell, out var list))
     {
         list.Remove(agent);
     }
 }
Пример #6
0
        public static void RemoveAgentFromCell(Dictionary <TerrainCell, List <Agent> > cellDict, TerrainCell cell, Agent agent)
        {
            if (cellDict.TryGetValue(cell, out var list))
            {
                list.Remove(agent);

                if (!list.Any())
                {
                    cellDict.Remove(cell);
                }
            }
        }