public void GetNeighborBorderNodes_TopLeft_ReturnsTopRight()
        {
            // ARRANGE
            const int REGION_SIZE = 20;
            // У нас есть 2 региона, расположенных по соседству.

            var regionSchemeMock = new Mock <ILocationScheme>();
            var regionScheme     = regionSchemeMock.Object;

            var currentRegion = new GlobeRegion(REGION_SIZE);

            FillRegion(REGION_SIZE, regionScheme, currentRegion);

            // Берём правую верхнюю точку для перехода.
            var currentNode = currentRegion.Nodes.OfType <GlobeRegionNode>().Single(node => node.OffsetX == 0 && node.OffsetY == 0);

            var currentTerrainCell = new TerrainCell()
            {
                Coords = new OffsetCoords(1, 0)
            };

            var targetRegion = new GlobeRegion(REGION_SIZE);

            FillRegion(REGION_SIZE, regionScheme, targetRegion);
            var expectedTransitionNodes = new[] {
                targetRegion.Nodes.OfType <GlobeRegionNode>().Single(node => node.OffsetX == REGION_SIZE - 1 && node.OffsetY == 0),
                targetRegion.Nodes.OfType <GlobeRegionNode>().Single(node => node.OffsetX == REGION_SIZE - 1 && node.OffsetY == 1)
            };

            var targetRegionBorders = targetRegion.Nodes.OfType <GlobeRegionNode>().Where(node => node.IsBorder);
            var targetTerrainCell   = new TerrainCell()
            {
                Coords = new OffsetCoords(0, 0)
            };



            // ACT
            var factTransitionNodes = RegionTransitionHelper.GetNeighborBorderNodes(currentNode,
                                                                                    currentTerrainCell,
                                                                                    targetRegionBorders,
                                                                                    targetTerrainCell);



            // ASSERT
            factTransitionNodes.Should().BeEquivalentTo(expectedTransitionNodes);
        }
    private async void Start()
    {
        //TODO Разобраться, почему остаются блоки от перемещения при использовании перехода
        _commandBlockerService.DropBlockers();

        if (_globeManager.Globe == null)
        {
            if (!_progressStorageService.LoadGlobe())
            {
                var globeGenerationResult = await _globeGenerator.GenerateGlobeAsync();

                _globeManager.Globe = globeGenerationResult.Globe;
                _globeManager.GlobeGenerationHistory = globeGenerationResult.History;

                var startCell = _globeManager.Globe.StartProvince;

                _player.Terrain = startCell;

                var createdRegion = await CreateRegionAsync(_globeManager.Globe, _player.Terrain, _globeGenerator, _progressStorageService);
                await CreateNeighborRegionsAsync(_player.Terrain.Coords, _globeManager, _globeGenerator, _progressStorageService);

                _globeManager.Regions[_player.Terrain] = createdRegion;


                var startNode = createdRegion.RegionNodes.Single(x => x.IsStart);

                _player.GlobeNode = startNode;

                startNode.ObservedState = GlobeNodeObservedState.Visited;

                _globeModalManager.ShowHistoryBookModal();
            }
            else
            {
                _globeManager.GlobeGenerationHistory = new GlobeGenerationHistory();

                if (!_progressStorageService.LoadPlayer())
                {
                    var startCell = _globeManager.Globe.StartProvince;

                    _player.Terrain = startCell;
                }
            }
        }

        var currentGlobeCell = _player.Terrain;

        if (!_globeManager.Regions.TryGetValue(currentGlobeCell, out var currentRegion))
        {
            var createdRegion = await CreateRegionAsync(_globeManager.Globe, currentGlobeCell, _globeGenerator, _progressStorageService);

            _globeManager.Regions[_player.Terrain] = createdRegion;
        }

        // Создание соседних регионов
        await CreateNeighborRegionsAsync(_player.Terrain.Coords, _globeManager, _globeGenerator, _progressStorageService);

        Debug.Log($"Current: {currentGlobeCell}");
        Debug.Log($"Current: {_globeManager.Globe.HomeProvince}");

        _region = currentRegion;

        // Создание визуализации узлов провинции.
        _locationNodeViewModels = new List <MapLocation>(100);
        foreach (GlobeRegionNode globeRegionNode in _region.Nodes)
        {
            var worldCoords = HexHelper.ConvertToWorld(globeRegionNode.OffsetX + _player.Terrain.Coords.X * 20,
                                                       globeRegionNode.OffsetY + _player.Terrain.Coords.Y * 20);

            var locationObject = _container.InstantiatePrefab(LocationPrefab, transform);
            locationObject.transform.position = new Vector3(worldCoords[0], worldCoords[1], 0);
            var locationViewModel = locationObject.GetComponent <MapLocation>();
            locationViewModel.Node         = globeRegionNode;
            locationViewModel.ParentRegion = _region;
            _locationNodeViewModels.Add(locationViewModel);

            locationViewModel.OnSelect += LocationViewModel_OnSelect;
            locationViewModel.OnHover  += LocationViewModel_OnHover;
        }

        // Создание коннекторов между узлами провинции.
        var openNodeViewModels = new List <MapLocation>(_locationNodeViewModels);

        while (openNodeViewModels.Any())
        {
            var currentNodeViewModel = openNodeViewModels[0];
            openNodeViewModels.Remove(currentNodeViewModel);

            var neighbors          = _region.GetNext(currentNodeViewModel.Node);
            var neighborViewModels = openNodeViewModels.Where(x => neighbors.Contains(x.Node)).ToArray();
            foreach (var neibourNodeViewModel in neighborViewModels)
            {
                CreateConnector(currentNodeViewModel, neibourNodeViewModel);
            }
        }

        // Создание визуализаций соседних провинций
        var currentRegionBorders = _region.RegionNodes.Where(x => x.IsBorder).ToArray();

        // TODO в открытые можно помещать только бордюр для экономии.
        openNodeViewModels = new List <MapLocation>(_locationNodeViewModels);
        var currentBorderNodes = currentRegion.Nodes.OfType <GlobeRegionNode>().Where(x => x.IsBorder).ToArray();

        for (var offsetX = -1; offsetX <= 1; offsetX++)
        {
            for (var offsetY = -1; offsetY <= 1; offsetY++)
            {
                if (offsetX == 0 && offsetY == 0)
                {
                    // Это нулевое смещение от текущего элемента.
                    // Пропускаем, т.к. текущий элемент уже есть.
                    continue;
                }

                var terrainX = _player.Terrain.Coords.X + offsetX;
                var terrainY = _player.Terrain.Coords.Y + offsetY;

                if (_globeManager.Globe.Terrain.GetLowerBound(0) <= terrainX &&
                    terrainX <= _globeManager.Globe.Terrain.GetUpperBound(0) &&
                    _globeManager.Globe.Terrain[0].GetLowerBound(0) <= terrainY &&
                    terrainY <= _globeManager.Globe.Terrain[0].GetUpperBound(0))
                {
                    var terrainCell = _globeManager.Globe.Terrain[terrainX][terrainY];

                    var neighborRegion = _globeManager.Regions[terrainCell];

                    // Ищем узел текущей провинции, являющийся соседним с узлом соседней провинции.
                    var neighborBorderNodes = neighborRegion.Nodes.OfType <GlobeRegionNode>().Where(x => x.IsBorder);

                    foreach (var neighborBorderNode in neighborBorderNodes)
                    {
                        var transitionNodes = RegionTransitionHelper.GetNeighborBorderNodes(neighborBorderNode,
                                                                                            terrainCell,
                                                                                            currentRegionBorders,
                                                                                            _player.Terrain);

                        if (!transitionNodes.Any())
                        {
                            // Этот узел соседней провинции не имеет переходов в текущую.
                            // Соответственно, из текущей провинции никто не будет иметь переходов в этот узел соседней провинции.
                            // Значит его можно вообще не отрисовывать.
                            continue;
                        }

                        var worldCoords = HexHelper.ConvertToWorld(neighborBorderNode.OffsetX + terrainX * 20,
                                                                   neighborBorderNode.OffsetY + terrainY * 20);

                        var locationObject = _container.InstantiatePrefab(LocationPrefab, transform);
                        locationObject.transform.position = new Vector3(worldCoords[0], worldCoords[1], 0);
                        var locationViewModel = locationObject.GetComponent <MapLocation>();
                        locationViewModel.Node         = neighborBorderNode;
                        locationViewModel.ParentRegion = neighborRegion;
                        locationViewModel.OtherRegion  = true;
                        _locationNodeViewModels.Add(locationViewModel);

                        locationViewModel.OnSelect += LocationViewModel_OnSelect;
                        locationViewModel.OnHover  += LocationViewModel_OnHover;

                        // Создаём коннекторы от всех пограничных узлов,
                        // имеющий переходв в текущий узел соседней провинции.
                        var openTransitionNodes = openNodeViewModels.Where(x => transitionNodes.Contains(x.Node));
                        foreach (var openTransitionNode in openTransitionNodes)
                        {
                            CreateConnector(openTransitionNode, locationViewModel);
                        }
                    }
                }
            }
        }

        if (_player.MainPerson == null)
        {
            if (!_progressStorageService.LoadPerson())
            {
                _player.MainPerson = _humanPersonFactory.Create();
            }
        }

        var playerGroupNodeViewModel = _locationNodeViewModels.Single(x => x.Node == _player.GlobeNode);
        var groupObject = _container.InstantiatePrefab(HumanGroupPrefab, transform);

        _groupViewModel = groupObject.GetComponent <GroupVM>();
        _groupViewModel.CurrentLocation = playerGroupNodeViewModel;
        groupObject.transform.position  = playerGroupNodeViewModel.transform.position;
        Camera.Target = groupObject;
        Camera.GetComponent <GlobalFollowCamera>().SetPosition(groupObject.transform);

        var nodes = _locationNodeViewModels.Select(x => x.Node);
        var centerLocationNode          = GlobeHelper.GetCenterLocationNode(nodes);
        var centerLocationNodeViewModel = _locationNodeViewModels
                                          .Single(nodeViewModel => nodeViewModel.Node.OffsetX == centerLocationNode.OffsetX &&
                                                  nodeViewModel.Node.OffsetY == centerLocationNode.OffsetY);

        MapBackground.transform.position = centerLocationNodeViewModel.transform.position;

        _player.GlobeNodeChanged += HumanPlayer_GlobeNodeChanged;
        MoveGroupViewModel(_player.GlobeNode);
    }