private static IGraphNode[] GetObservingNodes(IFowContext fowContext, IGraphNode baseNode, int radius) { var border = new List <IGraphNode> { baseNode }; var resultList = new List <IGraphNode> { baseNode }; // Шаги заливки for (var stepIndex = 1; stepIndex <= radius; stepIndex++) { var newBorder = GetNextForBorder(border, resultList, fowContext); var visibleBorder = newBorder.AsParallel().Where(x => fowContext.IsTargetVisible(x, baseNode)) .ToArray(); border.Clear(); border.AddRange(visibleBorder); resultList.AddRange(visibleBorder); } return(resultList.ToArray()); }
/// <summary> /// Обновление состояния тумана войны для актёра с учётом карты и опорного узла карты. /// </summary> /// <param name="fowData">Состояние тумана войны которого обновляется.</param> /// <param name="fowContext">Контекст тумана войны.</param> /// <param name="baseNode">Опорный узел.</param> /// <param name="radius">Радиус обзора персонажа.</param> public static void UpdateFowData(ISectorFowData fowData, IFowContext fowContext, IGraphNode baseNode, int radius) { if (fowData is null) { throw new ArgumentNullException(nameof(fowData)); } if (fowContext is null) { throw new ArgumentNullException(nameof(fowContext)); } if (baseNode is null) { throw new ArgumentNullException(nameof(baseNode)); } // Все наблюдаемые из базового узла узлы карты. var observingNodes = GetObservingNodes(fowContext, baseNode, radius); var currentObservedFowNodes = fowData.GetFowNodeByState(SectorMapNodeFowState.Observing); var newObservedFowNodes = UpdateOrCreateFowNodes(fowData, observingNodes); var notObservingFowNodes = currentObservedFowNodes.Except(newObservedFowNodes).ToArray(); foreach (var fowNode in notObservingFowNodes) { fowData.ChangeNodeState(fowNode, SectorMapNodeFowState.Explored); } }
private static IGraphNode[] GetNextForBorder(IEnumerable <IGraphNode> border, IEnumerable <IGraphNode> result, IFowContext fowContext) { var borderTotal = new List <IGraphNode>(); foreach (var node in border) { var next = fowContext.GetNext(node); var except = border.Union(result).Union(borderTotal); var newBorder = next.Except(except); borderTotal.AddRange(newBorder); } return(borderTotal.ToArray()); }