Esempio n. 1
0
        private static void ConnectOpenRegionsToUnited(Matrix <bool> matrix, List <RegionDraft> openRegions,
                                                       List <RegionDraft> unitedRegions)
        {
            var unitedRegionCoords = unitedRegions.SelectMany(x => x.Coords).ToArray();

            // Ищем две самые ближние точки между объединённым регионом и
            // и всеми открытыми регионами.

            FindClosestNodesBetweenOpenAndUnited(
                openRegions,
                unitedRegionCoords,
                out OffsetCoords? currentOpenRegionCoord,
                out OffsetCoords? currentUnitedRegionCoord,
                out RegionDraft nearbyOpenRegion);

            // Если координаты, которые нужно соединить, найдены,
            // то прорываем тоннель.
            if (nearbyOpenRegion != null &&
                currentOpenRegionCoord != null &&
                currentUnitedRegionCoord != null)
            {
                var openCubeCoord   = HexHelper.ConvertToCube(currentOpenRegionCoord.Value);
                var unitedCubeCoord = HexHelper.ConvertToCube(currentUnitedRegionCoord.Value);

                DrawLineBetweenNodes(matrix, openCubeCoord, unitedCubeCoord);

                openRegions.Remove(nearbyOpenRegion);
                unitedRegions.Add(nearbyOpenRegion);
            }
        }
        private static void FindClosestNodesBetweenOpenAndUnited(List <RegionDraft> openRegions, OffsetCoords[] unitedRegionCoords, out OffsetCoords?currentOpenRegionCoord, out OffsetCoords?currentUnitedRegionCoord, out RegionDraft nearbyOpenRegion)
        {
            var currentDistance = int.MaxValue;

            currentOpenRegionCoord   = null;
            currentUnitedRegionCoord = null;
            nearbyOpenRegion         = null;
            foreach (var currentOpenRegion in openRegions)
            {
                foreach (var openRegionCoord in currentOpenRegion.Coords)
                {
                    var openCubeCoord = HexHelper.ConvertToCube(openRegionCoord);

                    foreach (var unitedRegionCoord in unitedRegionCoords)
                    {
                        var unitedCubeCoord = HexHelper.ConvertToCube(unitedRegionCoord);
                        var distance        = openCubeCoord.DistanceTo(unitedCubeCoord);

                        if (distance < currentDistance)
                        {
                            currentDistance          = distance;
                            currentOpenRegionCoord   = openRegionCoord;
                            currentUnitedRegionCoord = unitedRegionCoord;
                            nearbyOpenRegion         = currentOpenRegion;
                        }
                    }
                }
            }
        }
        private static int CountAliveNeighbours(Matrix <bool> matrix, int x, int y)
        {
            var aliveCount = 0;

            var cubeCoords      = HexHelper.ConvertToCube(x, y);
            var offsetsImplicit = HexHelper.GetOffsetClockwise();
            var offsetsDiagonal = HexHelper.GetDiagonalOffsetClockwise();
            var offsets         = offsetsImplicit.Union(offsetsDiagonal);

            foreach (var offset in offsets)
            {
                var neighbour = cubeCoords + offset;

                var offsetCoords = HexHelper.ConvertToOffset(neighbour);

                var nX = offsetCoords.X;
                var nY = offsetCoords.Y;

                // Границу мертвым живым соседом.
                // Сделано, чтобы углы не заполнялись.

                if (nX >= 0 && nY >= 0 && nX < matrix.Width && nY < matrix.Height)
                {
                    if (matrix.Items[nX, nY])
                    {
                        aliveCount++;
                    }
                }
            }

            return(aliveCount);
        }
Esempio n. 4
0
        //TODO Постараться объединить GetStartProvinceCoords и GetHomeProvinceCoords
        private TerrainCell GetHomeProvinceCoords(Globe globe, TerrainCell startProvince)
        {
            // Выбираем основной город, являющийся стартовым.
            // По городу определяем провинцию.

            var currentCubeCoords   = HexHelper.ConvertToCube(startProvince.Coords);
            var availableLocalities = globe.Localities
                                      .Where(x => x.Cell != startProvince)
                                      .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) > 2)
                                      .Where(x => HexHelper.ConvertToCube(x.Cell.Coords).DistanceTo(currentCubeCoords) <= 5)
                                      .ToArray();

            Locality selectedLocality;

            if (availableLocalities.Any())
            {
                var localityIndex = _dice.Roll(0, availableLocalities.Count() - 1);
                selectedLocality = availableLocalities[localityIndex];
            }
            else
            {
                selectedLocality = globe.Localities.LastOrDefault();
            }

            if (selectedLocality == null)
            {
                //TODO Создать отдельный класс исключений GlobeGenerationException.
                throw new InvalidOperationException("Не удалось выбрать локацию для дома.");
            }

            return(selectedLocality.Cell);
        }
Esempio n. 5
0
        public HexNode(int x, int y, bool isObstacle)
        {
            OffsetX    = x;
            OffsetY    = y;
            IsObstacle = isObstacle;

            CubeCoords = HexHelper.ConvertToCube(x, y);
        }
Esempio n. 6
0
        public HexNode(OffsetCoords coords)
        {
            OffsetCoords = coords;

            var x = coords.X;
            var y = coords.Y;

            CubeCoords = HexHelper.ConvertToCube(x, y);
        }
Esempio n. 7
0
        private static Locality GetNeighborLocality(Agent agent, Globe globe, int coordRollIndex)
        {
            Locality targetLocality  = null;
            var      nextCoords      = GetRandomCoords(coordRollIndex);
            var      agentCubeCoords = HexHelper.ConvertToCube(agent.Location.Coords.X, agent.Location.Coords.Y);

            for (var i = 0; i < nextCoords.Length; i++)
            {
                var scanCubeCoords   = agentCubeCoords + nextCoords[i];
                var scanOffsetCoords = HexHelper.ConvertToOffset(scanCubeCoords);

                var freeX = scanOffsetCoords.X;
                var freeY = scanOffsetCoords.Y;

                if (freeX < 0)
                {
                    continue;
                }

                if (freeX >= globe.Terrain.Length)
                {
                    continue;
                }

                if (freeY < 0)
                {
                    continue;
                }

                if (freeY >= globe.Terrain[freeX].Length)
                {
                    continue;
                }

                var freeLocaltion1 = globe.Terrain[freeX][freeY];

                if (globe.LocalitiesCells.TryGetValue(freeLocaltion1, out var otherCheckLocality))
                {
                    // Захватываем только города, которые не принадлежат нашему государству.
                    if (otherCheckLocality.Owner != agent.Realm)
                    {
                        // Захватываем город, если он не последний у вражеского государства
                        // Это нужно будет переделать, потому что это разрушает идею о возникновении и падении империй.
                        var otherRealmLocalities = globe.Localities.Where(x => x.Owner == otherCheckLocality.Owner);
                        if (otherRealmLocalities.Count() > 1)
                        {
                            targetLocality = otherCheckLocality;
                            break;
                        }
                    }
                }
            }

            return(targetLocality);
        }
Esempio n. 8
0
        public void ConvertToCubeTest(int offsetX, int offsetY, int cubeX, int cubeY, int cubeZ)
        {
            // ARRANGE
            var expectedCubeCoords = new CubeCoords(cubeX, cubeY, cubeZ);

            // ACT
            var factCubeCoords = HexHelper.ConvertToCube(offsetX, offsetY);

            // ASSERT
            factCubeCoords.Should().BeEquivalentTo(expectedCubeCoords);
        }
Esempio n. 9
0
        private IEnumerable <IGraphNode> GetNextFromMatrix(int localOffsetX, int localOffsetY, int segmentX,
                                                           int segmentY, IGraphNode[,] matrix)
        {
            var directions        = HexHelper.GetOffsetClockwise();
            var currentCubeCoords = HexHelper.ConvertToCube(localOffsetX, localOffsetY);

            for (var i = 0; i < 6; i++)
            {
                var dir = directions[i];
                var neighborLocalCube = new CubeCoords(dir.X + currentCubeCoords.X,
                                                       dir.Y + currentCubeCoords.Y,
                                                       dir.Z + currentCubeCoords.Z);

                var neighborLocalOffset = HexHelper.ConvertToOffset(neighborLocalCube);

                var neighborSegmentX = segmentX;
                var neighborSegmentY = segmentY;

                if (neighborLocalOffset.X < 0)
                {
                    neighborSegmentX--;
                }
                else if (neighborLocalOffset.X >= _segmentSize)
                {
                    neighborSegmentX++;
                }

                if (neighborLocalOffset.Y < 0)
                {
                    neighborSegmentY--;
                }
                else if (neighborLocalOffset.Y >= _segmentSize)
                {
                    neighborSegmentY++;
                }

                IGraphNode currentNeibour;
                if (neighborSegmentX == segmentX &&
                    neighborSegmentY == segmentY)
                {
                    currentNeibour = matrix[neighborLocalOffset.X, neighborLocalOffset.Y];

                    if (currentNeibour == null)
                    {
                        continue;
                    }

                    yield return(currentNeibour);
                }
            }
        }
Esempio n. 10
0
        private static Locality GetNeighborLocality(Agent agent, Globe globe)
        {
            Locality targetLocality = null;

            var nextCoords      = HexHelper.GetOffsetClockwise().OrderBy(item => Guid.NewGuid()).ToArray();
            var agentCubeCoords = HexHelper.ConvertToCube(agent.Localtion.Coords.X, agent.Localtion.Coords.Y);

            for (var i = 0; i < nextCoords.Length; i++)
            {
                var scanCubeCoords   = agentCubeCoords + nextCoords[i];
                var scanOffsetCoords = HexHelper.ConvertToOffset(scanCubeCoords);

                var freeX = scanOffsetCoords.X;
                var freeY = scanOffsetCoords.Y;

                if (freeX < 0)
                {
                    continue;
                }

                if (freeX >= globe.Terrain.Length)
                {
                    continue;
                }

                if (freeY < 0)
                {
                    continue;
                }

                if (freeY >= globe.Terrain[freeX].Length)
                {
                    continue;
                }

                var freeLocaltion1 = globe.Terrain[freeX][freeY];

                if (globe.LocalitiesCells.TryGetValue(freeLocaltion1, out var otherCheckLocality))
                {
                    targetLocality = otherCheckLocality;
                    break;
                }
            }

            return(targetLocality);
        }
Esempio n. 11
0
 private static void FillMap(ISectorMap map, int mapWidth, int mapHeight, int mapSize, HexNode centerNode)
 {
     for (var x = 0; x < mapWidth; x++)
     {
         for (var y = 0; y < mapHeight; y++)
         {
             var testOffsetCoords = new OffsetCoords(x, y);
             var testCubeCoords   = HexHelper.ConvertToCube(testOffsetCoords);
             var distanceToCenter = centerNode.CubeCoords.DistanceTo(testCubeCoords);
             if (distanceToCenter > 0 && distanceToCenter <= mapSize)
             {
                 var node = new HexNode(testOffsetCoords);
                 map.AddNode(node);
             }
         }
     }
 }
        private static IEnumerable <OffsetCoords> GetAvailableCoords(OffsetCoords[] regionDraftCoords)
        {
            var coordHash = new HashSet <OffsetCoords>(regionDraftCoords);

            var neighborCubeOffsets = HexHelper.GetOffsetClockwise();

            foreach (var coords in regionDraftCoords)
            {
                var cube = HexHelper.ConvertToCube(coords);

                var isValid = HasAllHeighbors(coordHash, neighborCubeOffsets, cube);

                if (isValid)
                {
                    yield return(coords);
                }
            }
        }
Esempio n. 13
0
        public void CubeDrawLine_DifferentPoints_ReverseEquals(int sOffsetX, int sOffsetY, int offsetX, int offsetY)
        {
            // ARRANGE

            var startCubeCoords  = HexHelper.ConvertToCube(sOffsetX, sOffsetY);
            var finishCubeCoords = HexHelper.ConvertToCube(offsetX, offsetY);

            // ACT
            var line        = CubeCoordsHelper.CubeDrawLine(startCubeCoords, finishCubeCoords);
            var reverseLine = CubeCoordsHelper.CubeDrawLine(finishCubeCoords, startCubeCoords);

            // ASSERT
            for (int i = 0; i < line.Length; i++)
            {
                var linePoint    = line[i];
                var reversePoint = reverseLine[reverseLine.Length - i - 1];

                reversePoint.Should().Be(linePoint);
            }
        }
        public static IEnumerable <GlobeRegionNode> GetNeighborBorderNodes(GlobeRegionNode currentTerrainNode,
                                                                           TerrainCell currentTerrainCell,
                                                                           IEnumerable <GlobeRegionNode> targetRegionBorderNodes,
                                                                           TerrainCell targetNeighborTerrainCell)
        {
            if (targetRegionBorderNodes == null)
            {
                throw new ArgumentNullException(nameof(targetRegionBorderNodes));
            }

            if (currentTerrainCell == null)
            {
                throw new ArgumentNullException(nameof(currentTerrainCell));
            }

            if (targetNeighborTerrainCell == null)
            {
                throw new ArgumentNullException(nameof(targetNeighborTerrainCell));
            }

            const int REGION_SIZE = 20;

            var regionNodeOffsetX = targetNeighborTerrainCell.Coords.X - currentTerrainCell.Coords.X;
            var regionNodeOffsetY = targetNeighborTerrainCell.Coords.Y - currentTerrainCell.Coords.Y;

            var targetRegionBorderNodeOffsetCoords = targetRegionBorderNodes.Select(node =>
                                                                                    new
            {
                RegionOffsetCoords = new OffsetCoords(
                    regionNodeOffsetX >= 0 ? node.OffsetX + regionNodeOffsetX * REGION_SIZE : -(REGION_SIZE - node.OffsetX),
                    regionNodeOffsetY >= 0 ? node.OffsetY + regionNodeOffsetY * REGION_SIZE : -(REGION_SIZE - node.OffsetY)
                    ),
                Node = node
            });

            var transitionNodeCoords = targetRegionBorderNodeOffsetCoords.Where(coords =>
                                                                                HexHelper.ConvertToCube(coords.RegionOffsetCoords.X, coords.RegionOffsetCoords.Y)
                                                                                .DistanceTo(currentTerrainNode.CubeCoords) <= 1);

            return(transitionNodeCoords.Select(x => x.Node));
        }
Esempio n. 15
0
        public void CubeDrawLine_DifferentPoints_LineIsSolid(int sOffsetX, int sOffsetY, int offsetX, int offsetY)
        {
            // ARRANGE

            var startCubeCoords  = HexHelper.ConvertToCube(sOffsetX, sOffsetY);
            var finishCubeCoords = HexHelper.ConvertToCube(offsetX, offsetY);



            // ACT
            var line = CubeCoordsHelper.CubeDrawLine(startCubeCoords, finishCubeCoords);



            // ASSERT
            foreach (var coord in line)
            {
                var sameCoords = line.Where(x => x == coord);
                sameCoords.Count().Should().Be(1);

                // Проверяем, что у каждой точки линии есть соседи,
                // т.е. нет изолированных разорванных точк.
                var neibourOffsets = HexHelper.GetOffsetClockwise();
                var hasNeighbor    = false;

                foreach (var neibourOffset in neibourOffsets)
                {
                    var neighborCoord = coord + neibourOffset;
                    var foundCoords   = line.Where(x => x == neighborCoord);

                    var hasNeighborInThisDirection = foundCoords.Any();

                    if (hasNeighborInThisDirection)
                    {
                        hasNeighbor = true;
                    }
                }

                hasNeighbor.Should().Be(true);
            }
        }
        private static RegionDraft[] MakeUnitedRegions(Matrix <bool> matrix)
        {
            // Формирование регионов.
            // Регионы, кроме дальнейшего размещения игровых предметов,
            // в рамках этой генерации будут служить для обнаружения
            // изолированных регионов.
            // В секторе не должно быть изолированых регионов, поэтому
            // дальше все регионы объединяются в единый граф.

            var openNodes = new List <OffsetCoords>();

            for (var x = 0; x < matrix.Width; x++)
            {
                for (var y = 0; y < matrix.Height; y++)
                {
                    if (matrix.Items[x, y])
                    {
                        openNodes.Add(new OffsetCoords(x, y));
                    }
                }
            }

            if (!openNodes.Any())
            {
                throw new CellularAutomatonException("Ни одна из клеток не выжила.");
            }

            // Разбиваем все проходимые (true) клетки на регионы
            // через заливку.
            var regions = new List <RegionDraft>();

            while (openNodes.Any())
            {
                var openNode     = openNodes.First();
                var regionCoords = FloodFillRegions(matrix, openNode);
                var region       = new RegionDraft(regionCoords.ToArray());

                openNodes.RemoveAll(x => region.Coords.Contains(x));

                regions.Add(region);
            }

            // Соединяем все регионы в единый граф.
            var openRegions   = new List <RegionDraft>(regions);
            var unitedRegions = new List <RegionDraft>();

            var startRegion = openRegions[0];

            openRegions.RemoveAt(0);
            unitedRegions.Add(startRegion);

            while (openRegions.Any())
            {
                var unitedRegionCoords = unitedRegions.SelectMany(x => x.Coords).ToArray();

                // Ищем две самые ближние точки между объединённым регионом и
                // и всеми открытыми регионами.

                var          currentDistance          = int.MaxValue;
                OffsetCoords?currentOpenRegionCoord   = null;
                OffsetCoords?currentUnitedRegionCoord = null;
                RegionDraft  nearbyOpenRegion         = null;

                foreach (var currentOpenRegion in openRegions)
                {
                    foreach (var openRegionCoord in currentOpenRegion.Coords)
                    {
                        var openCubeCoord = HexHelper.ConvertToCube(openRegionCoord);

                        foreach (var unitedRegionCoord in unitedRegionCoords)
                        {
                            var unitedCubeCoord = HexHelper.ConvertToCube(unitedRegionCoord);
                            var distance        = openCubeCoord.DistanceTo(unitedCubeCoord);

                            if (distance < currentDistance)
                            {
                                currentDistance          = distance;
                                currentOpenRegionCoord   = openRegionCoord;
                                currentUnitedRegionCoord = unitedRegionCoord;
                                nearbyOpenRegion         = currentOpenRegion;
                            }
                        }
                    }
                }

                // Если координаты, которые нужно соединить, найдены,
                // то прорываем тоннель.
                if (nearbyOpenRegion != null &&
                    currentOpenRegionCoord != null &&
                    currentUnitedRegionCoord != null)
                {
                    var openCubeCoord   = HexHelper.ConvertToCube(currentOpenRegionCoord.Value);
                    var unitedCubeCoord = HexHelper.ConvertToCube(currentUnitedRegionCoord.Value);

                    var line = CubeCoordsHelper.CubeDrawLine(openCubeCoord, unitedCubeCoord);
                    foreach (var lineItem in line)
                    {
                        var offsetCoords = HexHelper.ConvertToOffset(lineItem);

                        matrix.Items[offsetCoords.X, offsetCoords.Y] = true;
                    }

                    openRegions.Remove(nearbyOpenRegion);
                    unitedRegions.Add(nearbyOpenRegion);
                }
            }

            return(regions.ToArray());
        }
        private static RegionDraft[] MakeUnitedRegions(Matrix <bool> matrix)
        {
            // Формирование регионов.
            // Регионы, кроме дальнейшего размещения игровых предметов,
            // в рамках этой генерации будут служить для обнаружения
            // изолированных регионов.
            // В секторе не должно быть изолированых регионов, поэтому
            // дальше все регионы объединяются в единый граф.

            var openNodes = new List <OffsetCoords>();

            AddAllPassableNodesToOpenList(matrix, openNodes);

            if (!openNodes.Any())
            {
                throw new CellularAutomatonException("Ни одна из клеток не выжила.");
            }

            // Разбиваем все проходимые (true) клетки на регионы
            // через заливку.
            var regions = new List <RegionDraft>();

            while (openNodes.Any())
            {
                var openNode     = openNodes.First(x => MapFactoryHelper.IsAvailableFor7(matrix, x));
                var regionCoords = FloodFillRegions(matrix, openNode);
                var region       = new RegionDraft(regionCoords.ToArray());

                openNodes.RemoveAll(x => region.Contains(x));

                regions.Add(region);
            }

            // Соединяем все регионы в единый граф.
            var openRegions   = new List <RegionDraft>(regions);
            var unitedRegions = new List <RegionDraft>();

            var startRegion = openRegions[0];

            openRegions.RemoveAt(0);
            unitedRegions.Add(startRegion);

            while (openRegions.Any())
            {
                var unitedRegionCoords = unitedRegions.SelectMany(x => x.Coords).ToArray();

                // Ищем две самые ближние точки между объединённым регионом и
                // и всеми открытыми регионами.

                FindClosestNodesBetweenOpenAndUnited(
                    openRegions,
                    unitedRegionCoords,
                    out OffsetCoords? currentOpenRegionCoord,
                    out OffsetCoords? currentUnitedRegionCoord,
                    out RegionDraft nearbyOpenRegion);

                // Если координаты, которые нужно соединить, найдены,
                // то прорываем тоннель.
                if (nearbyOpenRegion != null &&
                    currentOpenRegionCoord != null &&
                    currentUnitedRegionCoord != null)
                {
                    var openCubeCoord   = HexHelper.ConvertToCube(currentOpenRegionCoord.Value);
                    var unitedCubeCoord = HexHelper.ConvertToCube(currentUnitedRegionCoord.Value);

                    DrawLineBetweenNodes(matrix, openCubeCoord, unitedCubeCoord);

                    openRegions.Remove(nearbyOpenRegion);
                    unitedRegions.Add(nearbyOpenRegion);
                }
            }

            return(regions.ToArray());
        }
Esempio n. 18
0
        public void Use(Agent agent, Globe globe, IDice dice)
        {
            globe.LocalitiesCells.TryGetValue(agent.Location, out var currentLocality);

            var highestBranchs = agent.Skills
                                 .Where(x => /*x.Key != BranchType.Politics &&*/ x.Value >= 1)
                                 .OrderBy(x => x.Value);

            if (!highestBranchs.Any())
            {
                return;
            }

            var firstBranch = highestBranchs.First();


            // Обнаружение свободных узлов для размещения населённого пункта.
            // Свободные узлы ишутся от текущей локации агента.

            TerrainCell freeLocaltion = null;

            var nextCoords      = HexHelper.GetOffsetClockwise();
            var agentCubeCoords = HexHelper.ConvertToCube(agent.Location.Coords.X, agent.Location.Coords.Y);

            for (var i = 0; i < nextCoords.Length; i++)
            {
                var scanCubeCoords   = agentCubeCoords + nextCoords[i];
                var scanOffsetCoords = HexHelper.ConvertToOffset(scanCubeCoords);

                var freeX = scanOffsetCoords.X;
                var freeY = scanOffsetCoords.Y;

                // Убеждаемся, что проверяемый узел находится в границах мира.
                var isPointInside = IsPointInsideWorld(freeX, freeY, globe.Terrain);
                if (!isPointInside)
                {
                    continue;
                }

                // Проверка, есть ли в найденной локации населённые пункты.
                var freeLocaltion1 = globe.Terrain[freeX][freeY];

                if (!globe.LocalitiesCells.TryGetValue(freeLocaltion1, out var freeCheckLocality))
                {
                    freeLocaltion = globe.Terrain[freeX][freeY];
                }
            }

            if (freeLocaltion != null)
            {
                // Свободный узел был найден.
                // Тогда создаём здесь населённый пункт с доминирующей специаьностью агента.
                // Популяция нового нас.пункта минимальна.
                // Одна единица популяци из текущего нас.пункта снимается.
                // Считается, что часть жителей мигрировали для начала строительства нового нас.пункта.

                var localityName = globe.GetLocalityName(dice);

                var createdLocality = new Locality
                {
                    Name     = localityName,
                    Branches = new Dictionary <BranchType, int> {
                        { firstBranch.Key, 1 }
                    },
                    Cell = freeLocaltion,

                    Population = 1,
                    Owner      = currentLocality.Owner
                };

                currentLocality.Population--;

                globe.Localities.Add(createdLocality);
                globe.LocalitiesCells[freeLocaltion] = createdLocality;
                globe.ScanResult.Free.Remove(freeLocaltion);
            }
            else
            {
                // Если не удалось найти свободный узел,
                // то агент перемещается в произвольный населённый пункт своего государства.

                TransportHelper.TransportAgentToRandomLocality(globe, dice, agent, currentLocality);
            }
        }
Esempio n. 19
0
        /// <summary>Возвращает узлы, напрямую соединённые с указанным узлом.</summary>
        /// <param name="node">Опорный узел, относительно которого выбираются соседние узлы.</param>
        /// <returns>Возвращает набор соседних узлов.</returns>
        public override IEnumerable <IMapNode> GetNext(IMapNode node)
        {
            var hexCurrent   = (HexNode)node;
            var offsetCoords = new OffsetCoords(hexCurrent.OffsetX, hexCurrent.OffsetY);
            var segmentX     = offsetCoords.X / _segmentSize;

            if (offsetCoords.X < 0)
            {
                segmentX--;
            }

            var segmentY = offsetCoords.Y / _segmentSize;

            if (offsetCoords.Y < 0)
            {
                segmentY--;
            }

            var localOffsetX = NormalizeNeighborCoord(offsetCoords.X % _segmentSize);
            var localOffsetY = NormalizeNeighborCoord(offsetCoords.Y % _segmentSize);

            var segmentKey = new SegmentKey(segmentX, segmentY);
            var matrix     = _segmentDict[segmentKey];

            var directions        = HexHelper.GetOffsetClockwise();
            var currentCubeCoords = HexHelper.ConvertToCube(localOffsetX, localOffsetY);

            for (var i = 0; i < 6; i++)
            {
                var dir = directions[i];
                var neighborLocalCube = new CubeCoords(dir.X + currentCubeCoords.X,
                                                       dir.Y + currentCubeCoords.Y,
                                                       dir.Z + currentCubeCoords.Z);

                var neighborLocalOffset = HexHelper.ConvertToOffset(neighborLocalCube);

                var neighborSegmentX = segmentX;
                var neighborSegmentY = segmentY;

                if (neighborLocalOffset.X < 0)
                {
                    neighborSegmentX--;
                }
                else if (neighborLocalOffset.X >= _segmentSize)
                {
                    neighborSegmentX++;
                }

                if (neighborLocalOffset.Y < 0)
                {
                    neighborSegmentY--;
                }
                else if (neighborLocalOffset.Y >= _segmentSize)
                {
                    neighborSegmentY++;
                }

                IMapNode currentNeibour;
                if (neighborSegmentX == segmentX &&
                    neighborSegmentY == segmentY)
                {
                    currentNeibour = matrix[neighborLocalOffset.X, neighborLocalOffset.Y];

                    if (currentNeibour == null)
                    {
                        continue;
                    }

                    yield return(currentNeibour);
                }
            }
        }
Esempio n. 20
0
 public HexNode(int x, int y)
 {
     OffsetX    = x;
     OffsetY    = y;
     CubeCoords = HexHelper.ConvertToCube(x, y);
 }