private static ISectorMap CreateSectorMap(Matrix <bool> matrix, RegionDraft[] draftRegions, IEnumerable <SectorTransition> transitions) { // Создание графа карты сектора на основе карты клеточного автомата. ISectorMap map = new SectorHexMap(); FillMapRegions(draftRegions, map); MapDraftRegionsToSectorMap(matrix, draftRegions, map); // Размещаем переходы и отмечаем стартовую комнату. // Общее описание: стараемся размещать переходы в самых маленьких комнатах. // Для этого сортируем все комнаты по размеру. // Первую занимаем под старт. // Последующие - это переходы. var regionOrderedBySize = map.Regions.OrderBy(x => x.Nodes.Length).ToArray(); if (regionOrderedBySize.Any()) { CreateTransitionInSmallestRegion(transitions, map, regionOrderedBySize); } return(map); }
public void TargetIsOnLine_MapWithGap_HasLine() { // ARRANGE var map = new SectorHexMap(); MapFiller.FillSquareMap(map, mapSize: 2); MapFiller.FillSquareMap(map, startX: 3, startY: 0, mapSize: 2); var startMap = map.HexNodes.SelectBy(0, 0); var targetMap = map.HexNodes.SelectBy(4, 0); // ACT var fact = map.TargetIsOnLine(startMap, targetMap); // ASSERT fact.Should().BeFalse(); }
public void TargetIsOnLine_MapWithObstacleInSide_HasNotLine() { // ARRANGE var map = new SectorHexMap(); MapFiller.FillSquareMap(map, 3, (x, y) => { return(new MapFiller.HexNodeOptions { IsObstacle = x == 1 && y == 1 // (1, 1) здесь будет препятсвие }); }); var startMap = map.HexNodes.SelectBy(0, 0); var targetMap = map.HexNodes.SelectBy(2, 1); // ACT var fact = map.TargetIsOnLine(startMap, targetMap); // ASSERT fact.Should().BeFalse(); }
public void Setup() { int mapSize = 1000; int baseX = 50; int baseY = 50; _radius = 5; // ARRANGE var map = new SectorHexMap(1000); for (var i = 0; i < mapSize; i++) { for (var j = 0; j < mapSize; j++) { var hexNode = new HexNode(i, j); map.AddNode(hexNode); } } _fowData = new HumanSectorFowData(); _baseNode = map.HexNodes.Single(x => x.OffsetCoords.X == baseX && x.OffsetCoords.Y == baseY); _fowContextMock = new TestFowContext(map); }
public void TargetIsOnLine_EmptyMap_HasLine() { // ARRANGE var map = new SectorHexMap(); MapFiller.FillSquareMap(map, 3); var startMap = map.HexNodes.SelectBy(0, 0); var targetMap = map.HexNodes.SelectBy(2, 1); // ACT var fact = map.TargetIsOnLine(startMap, targetMap); // ASSERT fact.Should().BeTrue(); }
public void UpdateFowData_SquareMap_ObseringNodesIsNotEmpty(int mapSize, int baseX, int baseY, int radius) { // ARRANGE var map = new SectorHexMap(1000); for (var i = 0; i < mapSize; i++) { for (var j = 0; j < mapSize; j++) { var hexNode = new HexNode(i, j); map.AddNode(hexNode); } } var nodeList = new List <SectorMapFowNode>(); var fowDataMock = new Mock <ISectorFowData>(); fowDataMock.Setup(x => x.AddNodes(It.IsAny <IEnumerable <SectorMapFowNode> >())) .Callback <IEnumerable <SectorMapFowNode> >(nodes => nodeList.AddRange(nodes)); fowDataMock.Setup(x => x.ChangeNodeState(It.IsAny <SectorMapFowNode>(), It.IsAny <SectorMapNodeFowState>())) .Callback <SectorMapFowNode, SectorMapNodeFowState>((fowNode, targetState) => fowNode.ChangeState(targetState)); var fowData = fowDataMock.Object; var fowContextMock = new Mock <IFowContext>(); fowContextMock.Setup(x => x.IsTargetVisible(It.IsAny <IGraphNode>(), It.IsAny <IGraphNode>())) .Returns <IGraphNode, IGraphNode>((baseNode, targetNode) => map.TargetIsOnLine(baseNode, targetNode)); fowContextMock.Setup(x => x.GetNext(It.IsAny <IGraphNode>())) .Returns <IGraphNode>(node => map.GetNext(node)); var fowContext = fowContextMock.Object; var baseNode = map.HexNodes.Single(x => x.OffsetCoords.CompsEqual(baseX, baseY)); var expectedObservingNodes = map.HexNodes.Where(x => map.DistanceBetween(x, baseNode) <= radius).ToArray(); // ACT FowHelper.UpdateFowData(fowData, fowContext, baseNode, radius); // ARRANGE var factObservingNodes = nodeList.Where(x => x.State == SectorMapNodeFowState.Observing).Select(x => x.Node) .ToArray(); factObservingNodes.Should().BeEquivalentTo(expectedObservingNodes); }
public void GenerateRoomsInGrid_WithFixLarge_NotThrowsExceptions() { // ARRANGE var random = new FixLargeRoomGeneratorRandomSource(); var generator = new RoomGenerator(random); var graphMap = new SectorHexMap(); // ACT Action act = () => { var rooms = generator.GenerateRoomsInGrid(20, 2, 20, new[] { RoomTransition.CreateGlobalExit() }); var edgeHash = new HashSet <string>(); generator.CreateRoomNodes(graphMap, rooms, edgeHash); generator.BuildRoomCorridors(graphMap, rooms, edgeHash); }; // ASSERT act.Should().NotThrow(); }
public async Task <ISectorMap> CreateInternalAsync(int mapSize, IEnumerable <SectorTransition> transitions) { var mapWidth = (mapSize * 2) + 2; var mapHeight = mapWidth; return(await Task.Run(() => { ISectorMap map = new SectorHexMap(mapWidth); var centerNode = new HexNode(mapSize, mapSize); map.AddNode(centerNode); FillMap(map, mapWidth, mapHeight, mapSize, centerNode); CreateRegionsAndTranstions(map, mapSize, centerNode, transitions); map.Regions.Add(new MapRegion(1, map.Nodes.ToArray())); return map; })); }
public void UpdateFowData_RealHumanSectorFowData_ObseringNodesIsNotEmpty(int mapSize, int baseX, int baseY, int radius) { // ARRANGE var map = new SectorHexMap(1000); for (var i = 0; i < mapSize; i++) { for (var j = 0; j < mapSize; j++) { var hexNode = new HexNode(i, j); map.AddNode(hexNode); } } var fowData = new HumanSectorFowData(); var baseNode = map.HexNodes.Single(x => x.OffsetCoords.CompsEqual(baseX, baseY)); var fowContextMock = new Mock <IFowContext>(); fowContextMock.Setup(x => x.IsTargetVisible(It.IsAny <IGraphNode>(), It.IsAny <IGraphNode>())) .Returns <IGraphNode, IGraphNode>((baseNode, targetNode) => map.TargetIsOnLine(baseNode, targetNode)); fowContextMock.Setup(x => x.GetNext(It.IsAny <IGraphNode>())) .Returns <IGraphNode>(node => map.GetNext(node)); var fowContext = fowContextMock.Object; var expectedObservingNodes = map.HexNodes.Where(x => map.DistanceBetween(x, baseNode) <= radius).ToArray(); // ACT FowHelper.UpdateFowData(fowData, fowContext, baseNode, radius); // ARRANGE var factObservingNodes = fowData.GetFowNodeByState(SectorMapNodeFowState.Observing).Select(x => x.Node); factObservingNodes.Should().BeEquivalentTo(expectedObservingNodes); }
/// <summary> /// Создание карты. /// </summary> /// <param name="options">Параметры создания карты.</param> /// <returns> /// Возвращает экземпляр карты. /// </returns> public Task <ISectorMap> CreateAsync(object options) { const int START_ROOM_SIZE = 2; var mapSize = (int)options; ISectorMap map = new SectorHexMap(); MapFiller.FillSquareMap(map, mapSize); var startRoomLeftBorder = mapSize / 2 - START_ROOM_SIZE / 2; var startRoomTopBorder = mapSize / 2 - START_ROOM_SIZE / 2; var startRoomRightBorder = startRoomLeftBorder + START_ROOM_SIZE - 1; var startRoomBottomBorder = startRoomTopBorder + START_ROOM_SIZE - 1; var startNodes = map.Nodes.OfType <HexNode>() .Where(node => (startRoomLeftBorder <= node.OffsetX && node.OffsetX <= startRoomRightBorder) && (startRoomTopBorder <= node.OffsetY && node.OffsetY <= startRoomBottomBorder)) .ToArray(); var startRegion = new MapRegion(1, startNodes) { IsStart = true, }; var outerNodes = map.Nodes.Where(x => !startNodes.Contains(x)).ToArray(); var outerRegion = new MapRegion(2, outerNodes) { IsOut = true, ExitNodes = new[] { outerNodes.Last() } }; map.Regions.Add(startRegion); map.Regions.Add(outerRegion); map.Transitions.Add(outerNodes.Last(), RoomTransition.CreateGlobalExit()); return(Task.FromResult(map)); }
private static ISectorMap CreateSectorMap(Matrix <bool> matrix, RegionDraft[] draftRegions, IEnumerable <RoomTransition> transitions) { // Создание графа карты сектора на основе карты клеточного автомата. ISectorMap map = new SectorHexMap(); var regionIdCounter = 1; foreach (var draftRegion in draftRegions) { var regionNodeList = new List <IGraphNode>(); foreach (var coord in draftRegion.Coords) { var node = new HexNode(coord.X, coord.Y); map.AddNode(node); regionNodeList.Add(node); } var region = new MapRegion(regionIdCounter, regionNodeList.ToArray()); map.Regions.Add(region); regionIdCounter++; } MapDraftRegionsToSectorMap(matrix, draftRegions, map); // Размещаем переходы и отмечаем стартовую комнату. // Общее описание: стараемся размещать переходы в самых маленьких комнатах. // Для этого сортируем все комнаты по размеру. // Первую занимаем под старт. // Последующие - это переходы. var regionOrderedBySize = map.Regions.OrderBy(x => x.Nodes.Length).ToArray(); if (regionOrderedBySize.Any()) { var startRegion = regionOrderedBySize.First(); startRegion.IsStart = true; var transitionArray = transitions.ToArray(); // Пропускаем 1, потому что 1 занять стартом. var trasitionRegionDrafts = regionOrderedBySize.Skip(1).ToArray(); Debug.Assert(trasitionRegionDrafts.Length >= transitionArray.Length, "Должно быть достаточно регионов для размещения всех переходов."); for (var i = 0; i < transitionArray.Length; i++) { var transitionRegion = trasitionRegionDrafts[i]; var transition = transitionArray[i]; var transitionNode = transitionRegion.Nodes.First(); map.Transitions.Add(transitionNode, transition); if (transition.SectorNode == null) { transitionRegion.IsOut = true; } transitionRegion.ExitNodes = (from regionNode in transitionRegion.Nodes where map.Transitions.Keys.Contains(regionNode) select regionNode).ToArray(); } } return(map); }
private ISectorMap CreateSectorMap(Matrix <bool> matrix, RegionDraft[] draftRegions, IEnumerable <RoomTransition> transitions) { // Создание графа карты сектора на основе карты клеточного автомата. ISectorMap map = new SectorHexMap(); var allCoords = draftRegions.SelectMany(x => x.Coords).ToArray(); var interiorCoords = _interiorObjectRandomSource.RollInteriorObjects(allCoords); var interiorCoordHashset = interiorCoords.ToDictionary(x => x.Coords, x => x); var regionIdCounter = 1; foreach (var draftRegion in draftRegions) { var regionNodeList = new List <IMapNode>(); foreach (var coord in draftRegion.Coords) { var isObstacle = interiorCoordHashset.ContainsKey(coord); var node = new HexNode(coord.X, coord.Y, isObstacle); map.AddNode(node); regionNodeList.Add(node); } var region = new MapRegion(regionIdCounter, regionNodeList.ToArray()); map.Regions.Add(region); regionIdCounter++; } // Добавляем узлы каридоров. CreateCorridors(matrix, draftRegions, map); // Размещаем переходы и отмечаем стартовую комнату. // Общее описание: стараемся размещать переходы в самых маленьких комнатах. // Для этого сортируем все комнаты по размеру. // Первую занимаем под старт. // Последующие - это переходы. var regionOrderedBySize = map.Regions.OrderBy(x => x.Nodes.Count()).ToArray(); if (regionOrderedBySize.Any()) { var startRegion = regionOrderedBySize.First(); startRegion.IsStart = true; var transitionArray = transitions.ToArray(); // Пропускаем 1, потому что 1 занять стартом. var trasitionRegionDrafts = regionOrderedBySize.Skip(1).ToArray(); Debug.Assert(trasitionRegionDrafts.Count() >= transitionArray.Count(), "Должно быть достаточно регионов для размещения всех переходов."); for (var i = 0; i < transitionArray.Length; i++) { var transitionRegion = trasitionRegionDrafts[i]; var transition = transitionArray[i]; var transitionNode = transitionRegion.Nodes.First(); map.Transitions.Add(transitionNode, transition); if (transition.SectorSid == null) { transitionRegion.IsOut = true; } transitionRegion.ExitNodes = (from regionNode in transitionRegion.Nodes where map.Transitions.Keys.Contains(regionNode) select regionNode).ToArray(); } } return(map); }