/// <inheritdoc/> public Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (generationOptions is null) { throw new ArgumentNullException(nameof(generationOptions)); } var transitions = generationOptions.Transitions; var cellularAutomatonOptions = (ISectorCellularAutomataMapFactoryOptionsSubScheme)generationOptions.OptionsSubScheme; if (cellularAutomatonOptions == null) { throw new ArgumentException($"Для {nameof(generationOptions)} не задано {nameof(ISectorSubScheme.MapGeneratorOptions)} равно null."); } var matrixWidth = cellularAutomatonOptions.MapWidth; var matrixHeight = cellularAutomatonOptions.MapHeight; var chanceToStartAlive = cellularAutomatonOptions.ChanceToStartAlive; var targetRegionDraftCount = transitions.Count() + 1; var createResult = CreateInner( targetRegionDraftCount, chanceToStartAlive, matrixWidth, matrixHeight); var matrix = createResult.Matrix; var draftRegions = createResult.Regions; var map = CreateSectorMap(matrix, draftRegions, transitions); return(Task.FromResult(map)); }
/// <inheritdoc/> public Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (generationOptions is null) { throw new ArgumentNullException(nameof(generationOptions)); } var factoryOptions = (ISectorSquareMapFactoryOptionsSubScheme)generationOptions.OptionsSubScheme; if (factoryOptions == null) { throw new ArgumentException($"Для {nameof(generationOptions)} не задано {nameof(ISectorSubScheme.MapGeneratorOptions)} равно null."); } var mapSize = factoryOptions.Size; ISectorMap map = new SectorGraphMap(); MapFiller.FillSquareMap(map, mapSize); var mapRegion = new MapRegion(1, map.Nodes.ToArray()) { IsStart = true, IsOut = true, ExitNodes = new[] { map.Nodes.Last() } }; map.Regions.Add(mapRegion); return(Task.FromResult(map)); }
/// <summary> /// Создание карты. /// </summary> /// <returns> /// Возвращает экземпляр карты. /// </returns> public Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (generationOptions is null) { throw new System.ArgumentNullException(nameof(generationOptions)); } var roomFactoryOptions = generationOptions.OptionsSubScheme as ISectorRoomMapFactoryOptionsSubScheme; if (roomFactoryOptions is null) { throw new System.ArgumentException("Не задана схема генерации в настройках", nameof(generationOptions)); } var map = CreateMapInstance(); var edgeHash = new HashSet <string>(); // Генерируем случайные координаты комнат var transitions = generationOptions.Transitions; var rooms = _roomGenerator.GenerateRoomsInGrid(roomFactoryOptions.RegionCount, RoomMinSize, roomFactoryOptions.RegionSize, transitions); // Создаём узлы и рёбра комнат _roomGenerator.CreateRoomNodes(map, rooms, edgeHash); // Соединяем комнаты _roomGenerator.BuildRoomCorridors(map, rooms, edgeHash); // Указание регионов карты var regionIdCounter = 1; foreach (var room in rooms) { var passableRoomNodes = room.Nodes; var region = new MapRegion(regionIdCounter, passableRoomNodes.Cast <IGraphNode>().ToArray()); regionIdCounter++; map.Regions.Add(region); if (room.IsStart) { region.IsStart = true; continue; } if (room.Transitions?.Any() == true) { region.ExitNodes = (from regionNode in region.Nodes where map.Transitions.Keys.Contains(regionNode) select regionNode).ToArray(); continue; } } return(Task.FromResult(map)); }
public async Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (_factoryFuncAsync == null) { throw new InvalidOperationException("Не задана фабричная функция."); } //TODO Объяснить, почему тут нужно использовать ConfigureAwait(false) // Это рекомендация Codacy. // Но есть статья https://habr.com/ru/company/clrium/blog/463587/, // в которой объясняется, что не всё так просто. // Нужно чёткое понимание, зачем здесь ConfigureAwait(false) и // к какому результату это приводит по сравнению с простым await. var map = await _factoryFuncAsync(generationOptions).ConfigureAwait(false); return(map); }
public Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (generationOptions is null) { throw new ArgumentNullException(nameof(generationOptions)); } var factoryOptions = (ISectorOpenMapFactoryOptionsSubScheme)generationOptions.OptionsSubScheme; if (factoryOptions == null) { throw new ArgumentException( $"Map generation options {nameof(ISectorSubScheme.MapGeneratorOptions)} are not defined in {nameof(generationOptions)}."); } var mapSize = factoryOptions.Size; return(CreateInternalAsync(mapSize, generationOptions.Transitions)); }
/// <inheritdoc /> public Task <ISectorMap> CreateAsync(ISectorMapFactoryOptions generationOptions) { if (generationOptions is null) { throw new ArgumentNullException(nameof(generationOptions)); } var transitions = generationOptions.Transitions; var cellularAutomatonOptions = (ISectorCellularAutomataMapFactoryOptionsSubScheme)generationOptions.OptionsSubScheme; if (cellularAutomatonOptions == null) { throw new ArgumentException( $"Для {nameof(generationOptions)} не задано {nameof(ISectorSubScheme.MapGeneratorOptions)} равно null."); } var matrixWidth = cellularAutomatonOptions.MapWidth; var matrixHeight = cellularAutomatonOptions.MapHeight; var fillProbability = cellularAutomatonOptions.ChanceToStartAlive; var cellularAutomatonGenerator = new CellularAutomatonGenerator(_dice); var mapRuleManager = new MapRuleManager(); var rule = new RegionCountRule { Count = transitions.Count() + 1 }; mapRuleManager.AddRule(rule); var regionPostProcessors = new IRegionPostProcessor[] { new SplitToTargetCountRegionPostProcessor(mapRuleManager, _dice) }; for (var retryIndex = 0; retryIndex < RETRY_MAX_COUNT; retryIndex++) { var matrix = new Matrix <bool>(matrixWidth, matrixHeight); var regions = cellularAutomatonGenerator.Generate(ref matrix, fillProbability, 7); try { regions = PostProcess(regionPostProcessors, regions); ClosestRegionConnector.Connect(matrix, regions); var map = CreateSectorMap(matrix, regions.ToArray(), transitions); return(Task.FromResult(map)); } catch (CellularAutomatonException) { // This means that with the current starting data it is not possible to create a suitable map. // Start the next iteration. } } // If the cycle has ended, then no attempt has ended with a successful map building throw new InvalidOperationException("Failed to create a map within the maximum number of attempts."); }