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);
        }
Exemplo n.º 2
0
        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();
        }
Exemplo n.º 3
0
        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();
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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();
        }
Exemplo n.º 6
0
        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();
        }
Exemplo n.º 8
0
        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;
            }));
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
        /// <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);
        }