Exemplo n.º 1
0
        private IPropContainer CreateContainerModuleByPurpose(IDropTableScheme[] trashDropTables,
                                                              IDropTableScheme[] treasuresDropTable, PropContainerPurpose containerPurpose)
        {
            IPropContainer container;

            switch (containerPurpose)
            {
            case PropContainerPurpose.Trash:
                container = new DropTablePropChest(trashDropTables, _dropResolver)
                {
                    Purpose = PropContainerPurpose.Trash
                };
                break;

            case PropContainerPurpose.Treasures:
                container = new DropTablePropChest(treasuresDropTable, _dropResolver)
                {
                    Purpose = PropContainerPurpose.Treasures
                };
                break;

            default:
                throw new InvalidOperationException($"Не корректное назначение {containerPurpose}.");
            }

            return(container);
        }
Exemplo n.º 2
0
        public void GivenЕстьСундукIdВЯчейкеСоСлучайнымЛутом(int chestId, int chestPosX, int chestPosY, Table table)
        {
            var schemeService       = Context.ServiceProvider.GetRequiredService <ISchemeService>();
            var sectorManager       = Context.ServiceProvider.GetRequiredService <ISectorManager>();
            var staticObjectManager = sectorManager.CurrentSector.StaticObjectManager;

            var nodeCoords = new OffsetCoords(chestPosX, chestPosY);
            var node       = sectorManager.CurrentSector.Map.Nodes.SelectByHexCoords(nodeCoords.X, nodeCoords.Y);

            var dropProps = new List <IProp>();

            foreach (var tableRow in table.Rows)
            {
                tableRow.TryGetValue("prop", out var propSchemeSid);
                tableRow.TryGetValue("count", out var resourceCount);

                var propScheme = schemeService.GetScheme <IPropScheme>(propSchemeSid);

                dropProps.Add(new Resource(propScheme, int.Parse(resourceCount)));
            }

            var dropResolverMock = new Mock <IDropResolver>();

            dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >()))
            .Returns(dropProps.ToArray());
            var dropResolver = dropResolverMock.Object;

            var chest        = new DropTablePropChest(System.Array.Empty <DropTableScheme>(), dropResolver);
            var staticObject = new StaticObject(node, chest.Purpose, chestId);

            staticObject.AddModule <IPropContainer>(chest);

            staticObjectManager.Add(staticObject);
        }
Exemplo n.º 3
0
        public void GivenЕстьСундукIdВЯчейкеСоСлучайнымЛутом(int chestId, int chestPosX, int chestPosY, Table table)
        {
            var schemeService    = Context.Container.GetInstance <ISchemeService>();
            var containerManager = Context.Container.GetInstance <IPropContainerManager>();
            var sectorManager    = Context.Container.GetInstance <ISectorManager>();

            var nodeCoords = new OffsetCoords(chestPosX, chestPosY);
            var node       = sectorManager.CurrentSector.Map.Nodes.Cast <HexNode>().SelectBy(nodeCoords.X, nodeCoords.Y);

            var dropProps = new List <IProp>();

            foreach (var tableRow in table.Rows)
            {
                tableRow.TryGetValue("prop", out var propSchemeSid);
                tableRow.TryGetValue("count", out var resourceCount);

                var propScheme = schemeService.GetScheme <IPropScheme>(propSchemeSid);

                dropProps.Add(new Resource(propScheme, int.Parse(resourceCount)));
            }

            var dropResolverMock = new Mock <IDropResolver>();

            dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >()))
            .Returns(dropProps.ToArray());
            var dropResolver = dropResolverMock.Object;

            var chest = new DropTablePropChest(node, new DropTableScheme[0], dropResolver, chestId);

            containerManager.Add(chest);
        }
Exemplo n.º 4
0
        public void AddModule_From()
        {
            // ARRANGE

            var dropResolverMock = new Mock <IDropResolver>();
            var dropResolver     = dropResolverMock.Object;

            var container = new DropTablePropChest(Array.Empty <IDropTableScheme>(), dropResolver);

            var nodeMock = new Mock <IGraphNode>();
            var node     = nodeMock.Object;

            var staticObject = new StaticObject(node, default, default);
Exemplo n.º 5
0
        private void CreateChests(Room[] rooms)
        {
            var defaultDropTable  = _schemeService.GetScheme <DropTableScheme>("default");
            var survivalDropTable = _schemeService.GetScheme <DropTableScheme>("survival");

            foreach (var room in rooms)
            {
                var absNodeIndex  = room.Nodes.Count();
                var containerNode = room.Nodes[absNodeIndex / 2];
                var container     = new DropTablePropChest(containerNode,
                                                           new[] { defaultDropTable, survivalDropTable },
                                                           _dropResolver);
                _propContainerManager.Add(container);
            }
        }
        /// <summary>
        /// Создать сундуки в секторе.
        /// </summary>
        /// <param name="map">Карта сектора. Нужна для определения доступного места для сундука.</param>
        /// <param name="sectorSubScheme">Схема сектора. По сути - настройки для размещения сундуков.</param>
        /// <param name="regions">Регионы, в которых возможно размещение сундуков.</param>
        public void CreateChests(ISectorMap map, ISectorSubScheme sectorSubScheme, IEnumerable <MapRegion> regions)
        {
            var dropTables   = GetDropTables(sectorSubScheme);
            var chestCounter = sectorSubScheme.TotalChestCount;

            //TODO В схемах хранить уже приведённое значение пропорции.
            var countChestRatioNormal = 1f / sectorSubScheme.RegionChestCountRatio;

            foreach (var region in regions)
            {
                var maxChestCountRaw = region.Nodes.Count() * countChestRatioNormal;
                var maxChestCount    = (int)Math.Max(maxChestCountRaw, 1);
                var rolledCount      = _chestGeneratorRandomSource.RollChestCount(maxChestCount);

                var availableNodes = from node in region.Nodes
                                     where !map.Transitions.Keys.Contains(node)
                                     select node;
                var openNodes = new List <IMapNode>(availableNodes);
                for (var i = 0; i < rolledCount; i++)
                {
                    // Выбрать из коллекции доступных узлов
                    var rollIndex     = _chestGeneratorRandomSource.RollNodeIndex(openNodes.Count);
                    var containerNode = MapRegionHelper.FindNonBlockedNode(openNodes[rollIndex], map, openNodes);
                    if (containerNode == null)
                    {
                        // в этом случае будет сгенерировано на один сундук меньше.
                        // узел, с которого не удаётся найти подходящий узел, удаляем,
                        // чтобы больше его не анализировать, т.к. всё равно будет такой же исход.
                        openNodes.Remove(openNodes[rollIndex]);
                        continue;
                    }

                    openNodes.Remove(containerNode);
                    var container = new DropTablePropChest(containerNode,
                                                           dropTables,
                                                           _dropResolver);
                    _propContainerManager.Add(container);

                    chestCounter--;

                    if (chestCounter <= 0)
                    {
                        // лимит сундуков в секторе исчерпан.
                        break;
                    }
                }
            }
        }
        public void DropTablePropContainerTest()
        {
            // ARRANGE
            var nodeMock = new Mock <IMapNode>();
            var node     = nodeMock.Object;

            var dropTableRecord = new TestDropTableRecordSubScheme
            {
                SchemeSid = "test-prop",
                Weight    = 1,
                MinCount  = 1,
                MaxCount  = 1
            };

            var dropTable = new TestDropTableScheme(1, dropTableRecord);

            var testPropScheme = new PropScheme
            {
                Sid = "test-prop"
            };

            var dropResolverMock = new Mock <IDropResolver>();

            dropResolverMock.Setup(x => x.Resolve(It.IsAny <IEnumerable <IDropTableScheme> >()))
            .Returns(new IProp[] { new Resource(testPropScheme, 1) });
            var dropResolver = dropResolverMock.Object;

            var container = new DropTablePropChest(node,
                                                   new IDropTableScheme[] { dropTable },
                                                   dropResolver);



            // ACT
            var factProps = container.Content.CalcActualItems();



            // ASSERT
            factProps.Length.Should().Be(1);
            factProps[0].Scheme.Should().BeSameAs(testPropScheme);
            ((Resource)factProps[0]).Count.Should().Be(1);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Создать сундуки в секторе.
        /// </summary>
        /// <param name="map">Карта сектора. Нужна для определения доступного места для сундука.</param>
        /// <param name="sectorSubScheme">Схема сектора. По сути - настройки для размещения сундуков.</param>
        /// <param name="regions">Регионы, в которых возможно размещение сундуков.</param>
        public void CreateChests(ISectorMap map, ISectorSubScheme sectorSubScheme, IEnumerable <MapRegion> regions)
        {
            var trashDropTables    = GetTrashDropTables(sectorSubScheme);
            var treasuresDropTable = GetTreasuresDropTable();
            var chestCounter       = sectorSubScheme.TotalChestCount;

            //TODO В схемах хранить уже приведённое значение пропорции.
            var countChestRatioNormal = 1f / sectorSubScheme.RegionChestCountRatio;

            foreach (var region in regions)
            {
                var maxChestCountRaw = region.Nodes.Count() * countChestRatioNormal;
                var maxChestCount    = (int)Math.Max(maxChestCountRaw, 1);

                if (region.Nodes.Count() <= 1)
                {
                    // Для регионов, где только один узел,
                    // не создаём сундуки, иначе проход может быть загорожен.
                    // Актуально для фабрики карт на основе клеточного автомата,
                    // потому что он может генерить регионы из одного узла.

                    //TODO Попробовать проверять соседей узла.
                    // Возможно, одноклеточный регион находится в конце тупика.
                    // Тогда в нём можно разместить сундук.
                    // Критерий доступности такого региона - у узла только одни сосед.
                    continue;
                }

                var rolledCount = _chestGeneratorRandomSource.RollChestCount(maxChestCount);

                var availableNodes = from node in region.Nodes
                                     where !map.Transitions.Keys.Contains(node)
                                     where map.IsPositionAvailableForContainer(node)
                                     select node;

                var openNodes = new List <IMapNode>(availableNodes);
                for (var i = 0; i < rolledCount; i++)
                {
                    var containerPurpose = _chestGeneratorRandomSource.RollPurpose();

                    // Выбрать из коллекции доступных узлов
                    var rollIndex     = _chestGeneratorRandomSource.RollNodeIndex(openNodes.Count);
                    var containerNode = MapRegionHelper.FindNonBlockedNode(openNodes[rollIndex], map, openNodes);
                    if (containerNode == null)
                    {
                        // в этом случае будет сгенерировано на один сундук меньше.
                        // узел, с которого не удаётся найти подходящий узел, удаляем,
                        // чтобы больше его не анализировать, т.к. всё равно будет такой же исход.
                        openNodes.Remove(openNodes[rollIndex]);
                        continue;
                    }

                    // Проверка, что сундук не перегораживает проход.
                    var isValid = CheckMap(map, (HexNode)containerNode);
                    if (!isValid)
                    {
                        // в этом случае будет сгенерировано на один сундук меньше.
                        // узел, с которого не удаётся найти подходящий узел, удаляем,
                        // чтобы больше его не анализировать, т.к. всё равно будет такой же исход.
                        openNodes.Remove(openNodes[rollIndex]);
                        continue;
                    }

                    openNodes.Remove(containerNode);

                    IPropContainer container;
                    switch (containerPurpose)
                    {
                    case PropContainerPurpose.Trash:
                        container = new DropTablePropChest(containerNode, trashDropTables, _dropResolver)
                        {
                            Purpose = PropContainerPurpose.Trash
                        };
                        break;

                    case PropContainerPurpose.Treasures:
                        container = new DropTablePropChest(containerNode, treasuresDropTable, _dropResolver)
                        {
                            Purpose = PropContainerPurpose.Treasures
                        };
                        break;

                    default:
                        throw new InvalidOperationException($"Не корректное назначение {containerPurpose}.");
                    }
                    _propContainerManager.Add(container);

                    chestCounter--;

                    if (chestCounter <= 0)
                    {
                        // лимит сундуков в секторе исчерпан.
                        break;
                    }
                }
            }
        }