Exemplo n.º 1
0
    public HashSet <HexCell> GetAvailableAttacks(HexCell fromCell, Int32 range)
    {
        var res      = new HashSet <HexCell>();
        var frontier = new HexCellPriorityQueue();

        fromCell.Distance = 0;
        frontier.Enqueue(fromCell);
        while (frontier.Count > 0)
        {
            var current = frontier.Dequeue();
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (neighbor == null || neighbor == fromCell)
                {
                    continue;
                }
                if (neighbor.HasEnemyUnit(fromCell.Unit.Team) && fromCell.Coordinates.DistanceTo(neighbor.Coordinates) <= range && !res.Contains(neighbor))
                {
                    res.Add(neighbor);
                    frontier.Enqueue(neighbor);
                }
            }
        }

        return(res);
    }
Exemplo n.º 2
0
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }
            int currentTurn = current.Distance / speed;
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }
                if (neighbor.IsUnderwater)
                {
                    continue;
                }
                int distance = current.Distance;
                neighbor.Distance = current.Distance + 1;
                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 3
0
 public void GenerateMap(int x, int z)
 {
     Random.State originalRandomState = Random.state;
     if (!useFixedSeed)
     {
         seed  = Random.Range(0, int.MaxValue);
         seed ^= (int)System.DateTime.Now.Ticks;
         seed ^= (int)Time.time;
         seed &= int.MaxValue;
     }
     Random.InitState(seed);
     cellCount = x * z;
     grid.CreateMap(x, z);
     if (searchFrontier == null)
     {
         searchFrontier = new HexCellPriorityQueue();
     }
     for (int i = 0; i < cellCount; i++)
     {
         grid.GetCell(i).WaterLevel = waterLevel;
     }
     CreateRegions();
     CreateLand();
     ErodeLand();
     SetTerrainType();
     for (int i = 0; i < cellCount; i++)
     {
         grid.GetCell(i).SearchPhase = 0;
     }
     Random.state = originalRandomState;
 }
Exemplo n.º 4
0
    public void GenerateMap(int x, int z, bool wrap)
    {
        Random.State originalRandomState = Random.state;
        if (!UseFixedSeed)
        {
            Seed  = Random.Range(0, int.MaxValue);
            Seed ^= (int)System.DateTime.Now.Ticks;
            Seed ^= (int)Time.unscaledTime;
            Seed &= int.MaxValue;
        }
        Random.InitState(Seed);

        HexGrid.CreateMap(x, z, wrap);
        if (m_hexCellPriorityQueue == null)
        {
            m_hexCellPriorityQueue = new HexCellPriorityQueue();
        }
        HexGrid.ResetSearchPhase();

        foreach (HexCell hexCell in HexGrid.GetHexCells())
        {
            hexCell.WaterLevel = WaterLevel;
        }

        CreateRegions(x, z);

        CreateLand();
        ErodeLand();

        CreateClimate();
        CreateRivers();
        SetTerrainType();

        Random.state = originalRandomState;
    }
Exemplo n.º 5
0
    List <HexCell> GetVisibleCells(HexCell fromCell, int range)
    {
        List <HexCell> visibleCells = ListPool <HexCell> .Get();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        range += fromCell.ViewElevation;
        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);

        HexCoordinates fromCoordinates = fromCell.coordinates;

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            visibleCells.Add(current);

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase || !neighbor.Explorable)
                {
                    continue;
                }

                int distance = current.Distance + 1;
                if (distance + neighbor.ViewElevation > range ||
                    distance > fromCoordinates.DistanceTo(neighbor.coordinates))
                {
                    continue;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.SearchHeuristic = 0;
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(visibleCells);
    }
Exemplo n.º 6
0
    public void GeneratorMap(int x, int z, bool wrapping)
    {
        Random.State originalRandomState = Random.state;
        if (!useFixedSeed)
        {
            randmSeed  = Random.Range(0, int.MaxValue);
            randmSeed ^= (int)System.DateTime.Now.Ticks;
            randmSeed ^= (int)Time.unscaledTime;
            randmSeed &= int.MaxValue;
            Random.InitState(randmSeed);
        }

        cellCount = x * z;
        hexGrid.CreateMap(x, z, wrapping);
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        for (int i = 0; i < cellCount; i++)
        {
            hexGrid.GetCell(i).WaterLevel = waterLevel;
        }
        CreateRegions(x, z);
        CreateLand();
        ErodeLand();
        CreateClimate();
        CreateRivers();
        SetTerrainType();
        for (int i = 0; i < cellCount; i++)
        {
            hexGrid.GetCell(i).SearchPhase = 0;
        }

        Random.state = originalRandomState;
    }
Exemplo n.º 7
0
    public void GenerateMap(int x, int z)
    {
        Random.State originalRandomState = Random.state;

        if (!useFixedSeed)
        {
            seed  = Random.Range(0, int.MaxValue);
            seed ^= (int)System.DateTime.Now.Ticks;
            seed ^= (int)Time.unscaledTime;
            seed &= int.MaxValue;
        }

        Random.InitState(seed);
        cellCount = x * z;
        grid.CreateMap(x, z);

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).WaterLevel = waterLevel;
        }
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }
        CreateRegion();
        Random.state    = originalRandomState;
        underWaterCells = cellCount;
        minLandCells    = Mathf.RoundToInt(cellCount * landPercentage * 0.01f);
        maxLandCells    = Mathf.RoundToInt(minLandCells + (minLandCells / 2f));
    }
    /// <summary>
    /// 生成随机地形
    /// </summary>
    public void GenerateMap(int x, int z, bool isWrapping)
    {
        //-----随机种子-----
        Random.State originalRandomState = Random.state;
        if (!useFixedSeed)
        {
            seed  = Random.Range(0, int.MaxValue);
            seed ^= (int)System.DateTime.Now.Ticks;
            seed ^= (int)Time.unscaledTime;
            seed &= int.MaxValue; //强制归正数
        }

        Random.InitState(seed);

        //-----生成基础地形
        var grid = HexGrid.Instance;

        cellCount = x * z;
        grid.CreateMap(x, z, isWrapping);

        //-----随机生成寻路队列
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        //-----全部初始化为水
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).WaterLevel = waterLevel;
        }

        //陆地生成的边界
        CreateRegions();

        //创建岛屿
        CreateLand();

        //侵蚀打磨边缘
        ErodeLand();

        //创建天气系统
        CreateClimate();

        //创建河流系统
        CreateRivers();

        //创建地图类型
        SetTerrainType();

        //重置寻路值
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }

        //重置种子
        Random.state = originalRandomState;
    }
    /// <summary>
    /// Сгенерировать карту
    /// </summary>
    /// <param name="x"></param>
    /// <param name="z"></param>
    public void GenerateMap(int x, int z, bool wrapping)
    {
        Random.State originalRandomState = Random.state;
        
        if (!useFixedSeed)
        {
            //рандомизация семени(4 строки)
            seed = Random.Range(0, int.MaxValue);
            seed ^= (int)System.DateTime.Now.Ticks;
            seed ^= (int)Time.time;
            seed &= int.MaxValue;
        }

        Random.InitState(seed);

        cellCount = x * z;
        grid.CreateMap(x, z, wrapping);//сначала простое создание карты

        //потом сама генерация
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        //Установка уровня воды
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).WaterLevel = waterLevel;
        }


        CreateRegions();//регионы
        CreateLand();//создание земли
        ErodeLand();//эррозия
        CreateClimate();
        CreateRivers();
        SetTerrainType();//типы ландшафта


        //даем всем ячейкам приоритет поиска 0
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }

        Random.state = originalRandomState;
    }
Exemplo n.º 10
0
    //========================================================

    public void GenerateMap(int x, int z)
    {
        cellCount = x * z;
        grid.CreateMap(x, z);

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        CreateLand();

        for (int i = 0; i < cellCount; ++i)
        {
            grid.GetCell(i).SearchPhase = 0;
        }
    }
Exemplo n.º 11
0
 public void GenerateMap()
 {
     if (searchFrontier == null)
     {
         searchFrontier = new HexCellPriorityQueue();
     }
     for (int x = -MapWidth / 2; x <= MapWidth / 2; x++)
     {
         for (int y = -MapHeight / 2; y <= MapHeight / 2; y++)
         {
             CreateCell(x, y);
         }
     }
     FindNeighbors();
     CreateLand();
     CreateHillsAndMountains();
     RenderLand();
 }
Exemplo n.º 12
0
    public void GenerateMap(int x, int z, int seed)
    {
        Log.Status(GetType(), "generate map with seed: " + seed + " size: " + x + ", " + z);

        Random.State originalRandomState = Random.state;
        if (!useFixedSeed)
        {
            seed  = Random.Range(0, int.MaxValue);
            seed ^= (int)System.DateTime.Now.Ticks;
            seed ^= (int)Time.unscaledTime;
            seed &= int.MaxValue;
        }
        Random.InitState(seed);

        cellCount = x * z;
        grid.CreateMap(x, z);

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        for (int i = 0; i < cellCount; i++)
        {
            HexCell cell = grid.GetCell(i);
            cell.WaterLevel = waterLevel;
        }

        CreateRegions();
        CreateLand();
        ErodeLand();
        CreateClimate();
        CreateRivers();
        SetTerrainType();

        grid.CreateMeshColliders();

        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }

        Random.state = originalRandomState;
    }
Exemplo n.º 13
0
    /// <summary>
    /// 生成随机地图
    /// </summary>
    /// <param name="x">横向格子数目</param>
    /// <param name="z">纵向格子数目</param>
    public void GenerateMap(int x, int z)
    {
        Random.State originalRandomState = Random.state;
        if (!useFixedSeed)
        {
            seed  = Random.Range(0, int.MaxValue);              // 初始化随机数种子
            seed ^= (int)System.DateTime.Now.Ticks;             // ^按位异或,二者,只有一个1的时候结果为1,0 ^ 0 = 0, 1 ^ 1 = 0, 1 ^ 0 = 1
            seed ^= (int)Time.unscaledTime;
            seed &= int.MaxValue;                               // 负数的符号位是1,int.MaxValue是正数,符号位是0,按位与把符号位设为0,使用负数转换成正数
        }
        Random.InitState(seed);

        cellCount = x * z;

        // 创建默认地图
        grid.CreateMap(x, z);

        // 初始化待访问队列
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        // 设置水平面
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).WaterLevel = waterLevel;
        }

        CreateRegions();        // 划分区域
        CreateLand();           // 生成陆地
        ErodeLand();            // 侵蚀
        CreateClimate();        // 气候
        CreateRivers();         // 河流
        SetTerrainType();       // 设置地形类型

        // 重置格子搜索阶段,以免影响寻路(因为后续HexGrid中也会用到,而且二者的searchFrontierPhase步长不一样)
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }

        Random.state = originalRandomState;
    }
Exemplo n.º 14
0
 public static void FindPath(HexCell fromCell, HexCell toCell, HexUnit unit, bool displayPath)
 {
     ClearPath();
     //New unit == Clear old pathfinding
     if (searcherUnit != unit)
     {
         unit.myGrid.ClearSearchHeuristics();
         searchFrontierPhase = 0;
         searchFrontier      = null;
     }
     searcherUnit    = unit;
     currentPathFrom = fromCell;
     currentPathTo   = toCell;
     HasPath         = Search(fromCell, toCell, unit);
     if (displayPath)
     {
         ShowPath(unit.defaultMovementPoints, unit.remainingMovementPoints);
     }
 }
Exemplo n.º 15
0
    public void GenerateMap(int x, int z, bool wrapping)
    {
        Random.State originalRandomState = Random.state;

        if (!UseFixedSeed)
        {
            Seed  = Random.Range(0, int.MaxValue);
            Seed ^= (int)System.DateTime.Now.Ticks;
            Seed ^= (int)Time.unscaledTime;
            Seed &= int.MaxValue; // Make positive
        }
        Random.InitState(Seed);

        cellCount = x * z;
        grid.CreateMap(x, z, wrapping);

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }

        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).WaterLevel = WaterLevel;
        }

        CreateRegions();
        CreateLand();
        ErodeLand();
        CreateClimate();
        CreateRivers();
        SetTerrainType();

        // ! Pathfinding needs a rework ofc
        // Pathfinding uses cell search phase so reset at the end
        for (int i = 0; i < cellCount; i++)
        {
            grid.GetCell(i).SearchPhase = 0;
        }

        Random.state = originalRandomState;
    }
Exemplo n.º 16
0
 /// <summary>
 /// 生成地图
 /// </summary>
 /// <param name="x"></param>
 /// <param name="z"></param>
 public void GenerateMap(int x, int z, bool wrapping)
 {
     Random.State originalRandomState = Random.state;
     if (!useFixedSeed)
     {
         seed  = Random.Range(0, int.MaxValue);
         seed ^= (int)System.DateTime.Now.Ticks;
         seed ^= (int)Time.unscaledTime;
         seed &= int.MaxValue;
     }
     Random.InitState(seed);
     cellCount = x * z;
     grid.CreateMap(x, z, wrapping);
     if (searchFrontier == null)
     {
         searchFrontier = new HexCellPriorityQueue();
     }
     for (int i = 0; i < cellCount; i++)
     {
         grid.GetCell(i).WaterLevel = waterLevel;
     }
     //region.xMin = mapBorderX;
     //region.xMax = x - mapBorderX;
     //region.zMin = mapBorderZ;
     //region.zMax = z - mapBorderZ;
     //for (int i = 0; i < 5; i++)
     //{
     //    RaiseTerrain(Random.Range(chunkSizeMin, chunkSizeMax + 1));
     //}
     CreateRegions();
     CreateLand();
     ErodeLand();
     CreateClimate();
     CreateRivers();
     SetTerrainType();
     for (int i = 0; i < cellCount; i++)
     {
         grid.GetCell(i).SearchPhase = 0;
     }
     Random.state = originalRandomState;
 }
Exemplo n.º 17
0
    bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        int speed = unit.Speed;

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase
                    )
                {
                    continue;
                }
                if (!unit.IsValidDestination(neighbor))
                {
                    continue;
                }
                int moveCost = unit.GetMoveCost(current, neighbor, d);
                if (moveCost < 0)
                {
                    continue;
                }

                int distance = current.Distance + moveCost;
                int turn     = (distance - 1) / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 18
0
    bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        int speed = unit.Speed;

        searchFrontierPhase += 2;

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }
            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase
                    )
                {
                    continue;
                }

                //if ( neighbor.IsUnderwater || neighbor.Unit ) {
                //    continue;
                //}

                //HexEdgeType edgeType = current.GetEdgeType(neighbor);
                //if ( edgeType == HexEdgeType.Cliff ) {
                //    continue;
                //}

                //int moveCost;

                //if ( current.HasRoadThroughEdge(d) ) {
                //    moveCost = 1;
                //}
                //else if(current.Walled != neighbor.Walled ) {
                //    continue;
                //}
                //else {
                //    moveCost = ( edgeType == HexEdgeType.Flat ? 5 : 10 );
                //    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                //}

                if (!unit.IsValidDestination(neighbor))
                {
                    continue;
                }
                int moveCost = unit.GetMoveCost(current, neighbor, d);
                if (moveCost < 0)
                {
                    continue;
                }

                int distance = current.Distance + moveCost;
                int turn     = (distance - 1) / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 19
0
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase
                    )
                {
                    continue;
                }
                if (neighbor.IsUnderwater || neighbor.Unit)
                {
                    continue;
                }
                if (neighbor.HasRiver && !neighbor.HasRoads)
                {
                    continue;
                }

                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                // modify by ztj
                // 移动力足够大的情况下悬崖也可以上去
                //if (edgeType == HexEdgeType.Cliff) {
                //	continue;
                //}
                float moveCost;
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    //moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    moveCost  = MoveCost_Elevation[(int)edgeType];
                    moveCost += MoveCost_Terrain[current.TerrainTypeIndex];
                    //moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                    moveCost += MoveCost_Building[neighbor.UrbanLevel] + MoveCost_Building[neighbor.FarmLevel] +
                                MoveCost_Building[neighbor.PlantLevel];
                }

                int distance = current.Distance + (int)moveCost;
                int turn     = (distance - 1) / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + (int)moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 20
0
    //A* search method
    private int FindDistanceTo(Coordinates sourceCell, Coordinates targetCell, List <Coordinates> path,
                               Action <Coordinates> toDo, int maxDistance = Int32.MaxValue, bool wantToMove = true)
    {
        path?.Clear();
        //_searchFrontierPhase += 2;
        foreach (var coord in _coords)
        {
            coord.distance = -1;
            coord.PathFrom = -1;
            //coord.QueueStatus = HexCellPriorityQueue.QueueStatus.PreQueue;
            coord.nextWithSamePriority = null;
        }

        if (_searchFrontier == null)
        {
            _searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            _searchFrontier.Clear();
        }

        if (sourceCell == null)
        {
            toDo?.Invoke(null);
            return(-1);
            //yield break;
        }

        //sourceCell.SearchPhase = _searchFrontierPhase;
        sourceCell.distance = 0;
        _searchFrontier.Enqueue(sourceCell);

        var foundTarget = false;
        var count       = 0;

        while (_searchFrontier.Count > 0)
        {
            var current = _searchFrontier.Dequeue();
            //current.SearchPhase += 1;

            for (var d = 0; d <= current.Neighbors; d++)
            {
                var neighbor = current.GetNeighbor(d);
                if (neighbor.index < 0 || neighbor.index >= _coords.Count)
                {
                    continue;
                }

                var neighborCoord = _coords[neighbor.index];
                if (neighborCoord == null || !neighborCoord.walkable || (wantToMove && neighborCoord.occupied) ||
                    neighborCoord.distance > -1)
                {
                    continue;
                }

                neighborCoord.PathFrom = current.index;
                var distance         = current.distance;
                var neighborDistance = neighborCoord.distance;
                if (neighborDistance == -1)
                {
                    neighborCoord.distance = distance + 1;
                    //neighborCoord.SearchPhase = _searchFrontierPhase;
                    neighborCoord.SearchHeuristic = neighborCoord.FindDistanceTo(targetCell.coords);
                    _searchFrontier.Enqueue(neighborCoord);
                }

                /*else if (distance < neighborDistance)
                 * {
                 *  var oldPriority = neighborCoord.SearchPriority;
                 *  neighborCoord.distance = distance + 1;
                 *  _searchFrontier.Change(neighborCoord, oldPriority);
                 * }*/

                if (distance >= maxDistance)
                {
                    _searchFrontier.Clear();
                    toDo?.Invoke(null);
                    return(-1);
                    //yield break;
                }

                if (neighborCoord == targetCell)
                {
                    foundTarget = true;

                    if (path != null)
                    {
                        path.Add(neighborCoord);
                        current = neighborCoord;
                        var count1 = 0;
                        while (current.PathFrom > -1 && current.PathFrom != sourceCell.index)
                        {
                            if (count1 > 10000)
                            {
                                Debug.LogError("What the f**k");
                                break;
                            }

                            if (current.PathFrom > -1 && current.PathFrom < _coords.Count)
                            {
                                current = _coords[current.PathFrom];
                                path.Add(current);
                                count1++;
                            }
                        }

                        path.Reverse();
                    }

                    break;
                }
            }

            if (foundTarget)
            {
                break;
            }

            /*if (count % 200 == 0)
             * {
             *  yield return null;
             * }*/

            count++;
        }

        if (targetCell.index < 0 || targetCell.index >= _coords.Count)
        {
            toDo?.Invoke(null);
            return(-1);
            //yield break;
        }

        toDo?.Invoke(targetCell);

        //yield return null;

        _searchFrontier.Clear();
        return(targetCell.distance);
    }
Exemplo n.º 21
0
    bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        int speed = unit.Speed;

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);

        // 遍历未访问的边界格子
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;                                               // +1,由待访问阶段,进入到已访问阶段

            // 判断是否找到目标格子
            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.Distance - 1) / speed;                       // 到达当前格子所需的回合数

            // 把当前格子未访问的可达邻居全部加到待访问格子里
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase) // 跳过对应方向没有邻居的或已经找到最短路径的单元格
                {
                    continue;
                }
                if (!unit.IsValidDestination(neighbor))
                {
                    continue;
                }

                int moveCost = unit.GetMoveCost(current, neighbor, d);              // 当前格子到邻居的移动成本
                if (moveCost < 0)
                {
                    continue;
                }


                int distance = current.Distance + moveCost;
                int turn     = (distance - 1) / speed;          // 用刚得到的邻居距离,算出起点出到达邻居所需的回合数, -1是为了避免distance与speed相同时,得到turn为1,但其实本回合就能到达

                // 判断该邻居是否在下一个回合才能到达
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;         // 不直接使用上面distance的原因是,当前回合剩余行动点在下一回合会清零,所以到达该邻居实际上的移动成本更高
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.Coordinates.DistanceTo(toCell.Coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 22
0
    List <HexCell> GetVisibleCells(HexCell fromCell, int range)
    {
        List <HexCell> visibleCells = ListPool <HexCell> .Get();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;
            visibleCells.Add(current);
            //			if (current == toCell) {
            //				return true;
            //			}

            //			int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase
                    )
                {
                    continue;
                }
                //				…
                //				int moveCost;
                //				…

                int distance = current.Distance + 1;
                if (distance > range)
                {
                    continue;
                }
                //				int turn = (distance - 1) / speed;
                //				if (turn > currentTurn) {
                //					distance = turn * speed + moveCost;
                //				}

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase = searchFrontierPhase;
                    neighbor.Distance    = distance;
                    //					neighbor.PathFrom = current;
                    neighbor.SearchHeuristic = 0;
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    //					neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(visibleCells);
    }
Exemplo n.º 23
0
    /// <summary>
    /// A*寻路
    /// </summary>
    /// <param name="fromCell"></param>
    /// <param name="toCell"></param>
    /// <returns></returns>
    bool Search(HexCell fromCell, HexCell toCell, int speed)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        //        for (int i = 0; i < cells.Length; i++)
        //        {
        //            //cells[i].Distance = int.MaxValue;
        //            cells[i].SetLabel(null);
        //            cells[i].DisableHighlight();
        //        }
        //
        //        fromCell.EnableHighlight(Color.blue);

        fromCell.SearchPhase = searchFrontierPhase;

        //toCell.EnableHighlight(Color.red);

        fromCell.Distance = 0;

        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            //每当一个cell被检索过之后,格子的搜索阶段+1
            current.SearchPhase += 1;
            ///搜索到目标位置不再搜索
            if (current == toCell)
            {
                return(true);
                //下边这些可以在搜索完成之后,另外一个方法调用
                //                while (current != fromCell)
                //                {
                //                    int turn = current.Distance / speed;
                //                    current.SetLabel(turn.ToString());
                //                    current.EnableHighlight(Color.white);
                //                    current = current.PathFrom;
                //                }
                //                toCell.EnableHighlight(Color.red);
                //                break;
            }

            //当前的回合数(逻辑强相关)
            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                //这里可以根据搜索是否完成,避免重复计算
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                if (neighbor.IsUnderwater || neighbor.hexUnit)
                {
                    continue;
                }

                //取到当前链接类型
                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff)
                {
                    continue;
                }

                //int distance = current.Distance;
                //移动所消耗的行动力
                int moveCost;

                //如果是有道路的情况距离为1
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else
                {
                    //如果不是平摊的链接,距离为10
                    moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    //加入场景内环境的因素导致距离的问题(游戏逻辑强相关)
                    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel +
                                neighbor.PlantLevel;
                }

                int distance = current.Distance + moveCost;

                //需要行动多少个回合
                int turn = (distance - 1) / speed;

                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                //如果没有被检测过的邻居添加到队里中
                //if (neighbor.Distance == int.MaxValue) {
                //如果是搜索阶段小于当前的搜索阶段,这样搜索可以在初始化的时候不再初始化每个cell的初始距离
                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.Distance    = distance;
                    neighbor.SearchPhase = searchFrontierPhase;
                    //                    neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic =
                        neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    //                    neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }

        return(false);
    }
Exemplo n.º 24
0
    /// <summary>
    /// 搜索
    /// </summary>
    /// <param name="fromCell">来的cell</param>
    /// <param name="toCell">要去的cell</param>
    /// <param name="unit">要移动的单位</param>
    /// <returns>是否可以寻路</returns>
    private /*IEnumerator*/ bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        int speed = unit.Speed;

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        /*foreach (var nowCell in cells)
         * {
         * if (nowCell != fromCell && nowCell != toCell)
         * {
         * nowCell.DisableHighlight();
         * }
         *
         * nowCell.SetLabel(null);
         * }*/

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            //yield return delay;
            var current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            var currentTurn = (current.Distance - 1) / speed;

            for (var d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                var neighbor = current.GetNeighbor(d);
                if (neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                if (!unit.IsValidDestination(neighbor))
                {
                    continue;
                }

                int moveCost = unit.GetMoveCost(current, neighbor, d);
                if (moveCost < 0)
                {
                    continue;
                }

                var distance = current.Distance + moveCost;
                var turn     = (distance - 1) / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates
                                               .DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (neighbor.Distance > distance)
                {
                    var oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }

        //coroutine = null;
        return(false);
    }
Exemplo n.º 25
0
    bool Search(HexCell_Script fromCell, HexCell_Script toCell, int speed)
    {
        searchFrontierPhase += 2;

        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }



        //WaitForSeconds delay = new WaitForSeconds(1 / 60f);
        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        while (searchFrontier.Count > 0)
        {
            //yield return delay;
            HexCell_Script current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current.SearchPhase == 10000)
            {
                Debug.LogError("Could not find Path after 10000 searches!");
                return(false);
            }

            if (current == toCell)
            {
                return(true);
            }


            int currentTurn = (current.Distance - 1) / speed;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell_Script neighbor = current.GetNeighbor(d);
                if (neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }
                if (neighbor.IsUnderwater || neighbor.Unit)
                {
                    continue;
                }


                HexEdgeType edgeType = current.GetEdgeType(neighbor);
                if (edgeType == HexEdgeType.Cliff)
                {
                    continue;
                }


                int moveCost;
                if (current.HasRoadThroughEdge(d))
                {
                    moveCost = 1;
                }
                else if (current.Walled != neighbor.Walled)
                {
                    continue;
                }
                else
                {
                    moveCost  = edgeType == HexEdgeType.Flat ? 5 : 10;
                    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel;
                }

                int distance = current.Distance + moveCost;
                int turn     = distance / speed;
                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase = searchFrontierPhase;
                    neighbor.Distance    = distance;
                    //neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    //neighbor.SetLabel(turn.ToString());
                    neighbor.PathFrom = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }

                //searchFrontier.Sort((x, y) => x.SearchPriority.CompareTo(y.SearchPriority));
            }
        }
        return(false);
    }
Exemplo n.º 26
0
    //Pathfinding search
    static bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase  = searchFrontierPhase;
        fromCell.MovementCost = 0;
        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                return(true);
            }

            int currentTurn = (current.MovementCost - 1) / unit.defaultMovementPoints;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                //Hexes forbidden to move to
                if (!unit.CanEnter(neighbor))
                {
                    continue;
                }
                if (!neighbor.Traversable)
                {
                    continue;
                }
                //

                int hexEnterCost = 0;

                //Special condition costs here
                hexEnterCost += neighbor.GetHexEnterMovementModifier(d, unit);

                //Default cost
                hexEnterCost += neighbor.IsOcean ? unit.oceanMovementCost : unit.landMovementCost;

                int combinedCost = current.MovementCost + hexEnterCost;
                int turn         = (combinedCost - 1) / unit.defaultMovementPoints;
                if (turn > currentTurn)
                {
                    combinedCost = turn * unit.defaultMovementPoints + hexEnterCost;
                }

                if (neighbor.SearchPhase < searchFrontierPhase) //Has not been set before
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.MovementCost    = combinedCost;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    searchFrontier.Enqueue(neighbor);
                }
                else if (combinedCost < neighbor.MovementCost) //Update cost
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.MovementCost = combinedCost;
                    neighbor.PathFrom     = current;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(false);
    }
Exemplo n.º 27
0
    /// <summary>
    /// Used to get all cells "range"-steps from the "fromCell"
    /// </summary>
    /// <param name="fromCell"></param>
    /// <param name="range"></param>
    /// <returns></returns>
    public static List <HexCell> GetCellsWithinRange(HexCell fromCell, int range, params Func <HexCell, bool>[] conditions)
    {
        ClearPath();
        //New unit == Clear old pathfinding
        if (searcherUnit != null)
        {
            fromCell.myGrid.ClearSearchHeuristics();
            searchFrontierPhase = 0;
            searchFrontier      = null;
        }
        searcherUnit = null;

        List <HexCell> cellsInRange = new List <HexCell>();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase  = searchFrontierPhase;
        fromCell.MovementCost = 0;
        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                neighbor = Utility.TestVariableAgainstConditions(neighbor, conditions);
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                int hexEnterCost = 0;

                //Special condition costs here

                //Default cost
                hexEnterCost += 1;

                int combinedCost = current.MovementCost + hexEnterCost;

                if (neighbor.SearchPhase < searchFrontierPhase) //Has not been set before
                {
                    neighbor.SearchPhase  = searchFrontierPhase;
                    neighbor.MovementCost = combinedCost;

                    if (neighbor.MovementCost <= range)
                    {
                        cellsInRange.Add(neighbor);
                        searchFrontier.Enqueue(neighbor);
                    }
                }
                else if (combinedCost < neighbor.MovementCost) //Update cost
                {
                    neighbor.MovementCost = combinedCost;
                }
            }
        }
        return(cellsInRange);
    }
Exemplo n.º 28
0
    public static List <HexCell> GetAllReachableCells(HexCell fromCell, HexUnit unit)
    {
        ClearPath();
        //New unit == Clear old pathfinding
        if (searcherUnit != unit)
        {
            unit.myGrid.ClearSearchHeuristics();
            searchFrontierPhase = 0;
            searchFrontier      = null;
        }
        searcherUnit = unit;


        List <HexCell> reachableCells = new List <HexCell>();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        fromCell.SearchPhase  = searchFrontierPhase;
        fromCell.MovementCost = 0;
        searchFrontier.Enqueue(fromCell);

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                {
                    continue;
                }

                //Hexes forbidden to move to
                if (!unit.CanEnter(neighbor))
                {
                    continue;
                }
                if (!neighbor.Traversable)
                {
                    continue;
                }
                //

                int hexEnterCost = 0;

                //Special condition costs here
                hexEnterCost += neighbor.GetHexEnterMovementModifier(d, unit);

                //Default cost
                hexEnterCost += neighbor.IsOcean ? unit.oceanMovementCost : unit.landMovementCost;

                int combinedCost = current.MovementCost + hexEnterCost;

                if (neighbor.SearchPhase < searchFrontierPhase) //Has not been set before
                {
                    neighbor.SearchPhase  = searchFrontierPhase;
                    neighbor.MovementCost = combinedCost;

                    if (neighbor.MovementCost <= unit.remainingMovementPoints)
                    {
                        reachableCells.Add(neighbor);
                        searchFrontier.Enqueue(neighbor);
                    }
                }
                else if (combinedCost < neighbor.MovementCost) //Update cost
                {
                    neighbor.MovementCost = combinedCost;
                }
            }
        }
        return(reachableCells);
    }
Exemplo n.º 29
0
    private PathSearchResult Search(HexCell fromCell, HexCell toCell, Int32 speed, Int32 attackRange = 0)
    {
        if (!fromCell || !toCell)
        {
            return(new PathSearchResult());
        }
        _searchFrontierPhase += 2;
        if (_searchFrontier == null)
        {
            _searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            _searchFrontier.Clear();
        }
        fromCell.SearchPhase = _searchFrontierPhase;
        fromCell.Distance    = 0;
        _searchFrontier.Enqueue(fromCell);

        var canReach  = true;
        var canAttack = false;

        while (_searchFrontier.Count > 0)
        {
            var current = _searchFrontier.Dequeue();
            current.SearchPhase += 1;
            Int32 currentTurn  = (current.Distance - 1) / speed;
            var   absoluteTurn = current.AbsoluteDistance - 1;

            if (currentTurn > 0)
            {
                canReach  = false;
                canAttack = current.AttackDistance <= attackRange && current.Unit && current.Unit.Team != fromCell.Unit.Team;
            }

            if (current == toCell)
            {
                return(new PathSearchResult(canReach, canAttack));
            }

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);

                if (neighbor == null || neighbor.SearchPhase > _searchFrontierPhase)
                {
                    continue;
                }
                if (neighbor.TerrainType == HexTerrainTypes.Lake || (neighbor.Unit && neighbor.Unit.Team == fromCell.Unit.Team))
                {
                    continue;
                }

                Int32 moveCost = 0;

                if (current.HasRoad(d))
                {
                    moveCost = 1;
                }
                else
                {
                    switch (neighbor.TerrainType)
                    {
                    case HexTerrainTypes.Flat:
                        moveCost += 5;
                        break;

                    case HexTerrainTypes.Hill:
                        moveCost += 10;
                        break;

                    case HexTerrainTypes.Forest:
                        moveCost += 7;
                        break;

                    case HexTerrainTypes.Road:
                        moveCost += 5;
                        break;

                    default:
                        moveCost += 10;
                        break;
                    }
                }

                Int32 distance         = (current.Distance - 1) + moveCost;
                Int32 absoluteDistance = (current.AbsoluteDistance - 1) + 1;
                Int32 attackDistance   = 1;

                Int32 turn         = distance / speed;
                var   absoluteStep = absoluteDistance;

                if (absoluteStep > absoluteTurn)
                {
                    absoluteDistance = absoluteStep + 1;
                    if (!canReach)
                    {
                        attackDistance = current.AttackDistance + 1;
                    }
                }

                if (turn > currentTurn)
                {
                    distance = turn * speed + moveCost;
                }
                if (neighbor.SearchPhase < _searchFrontierPhase)
                {
                    neighbor.SearchPhase      = _searchFrontierPhase;
                    neighbor.Distance         = distance;
                    neighbor.AbsoluteDistance = absoluteDistance;
                    neighbor.AttackDistance   = attackDistance;
                    neighbor.PathFrom         = current;
                    neighbor.SearchHeuristic  = neighbor.Coordinates.DistanceTo(toCell.Coordinates);
                    _searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    var oldPriority = neighbor.SearchPriority;
                    neighbor.Distance         = distance;
                    neighbor.AttackDistance   = attackDistance;
                    neighbor.AbsoluteDistance = absoluteDistance;
                    neighbor.PathFrom         = current;
                    _searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(new PathSearchResult());
    }
Exemplo n.º 30
0
    public List <HexCell> GetCellsInRange(HexCell fromCell, HexAngleType angleType, HexDirection unitDirection, int range, bool elevationAddsRange = false, bool canSeeTruWalls = false)
    {
        List <HexCell> visibleCells = ListPool <HexCell> .Get();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        range += elevationAddsRange ? fromCell.ViewElevation : 0;

        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        HexCoordinates fromCoordinates = fromCell.coordinates;

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;
            visibleCells.Add(current);
            HexDirection start;
            HexDirection end;
            if (angleType == HexAngleType.Narrow)
            {
                start = unitDirection.Opposite();
                end   = unitDirection.Opposite().Next();
                if (canSeeTruWalls)
                {
                    fromCoordinates = LookLimitedTruWalls(range, fromCoordinates, current, start, end);
                }
                else
                {
                    fromCoordinates = LookLimited(range, fromCoordinates, current, start, end);
                }
            }
            else if (angleType == HexAngleType.Regular)
            {
                start = unitDirection.Opposite().Previous();
                end   = unitDirection.Opposite().Next2();
                if (canSeeTruWalls)
                {
                    fromCoordinates = LookLimitedTruWalls(range, fromCoordinates, current, start, end);
                }
                else
                {
                    fromCoordinates = LookLimited(range, fromCoordinates, current, start, end);
                }
            }
            else if (angleType == HexAngleType.Wide)
            {
                start = unitDirection.Opposite().Previous2();
                end   = unitDirection;
                if (canSeeTruWalls)
                {
                    fromCoordinates = LookLimitedTruWalls(range, fromCoordinates, current, start, end);
                }
                else
                {
                    fromCoordinates = LookLimited(range, fromCoordinates, current, start, end);
                }
            }
            else
            {
                if (canSeeTruWalls)
                {
                    fromCoordinates = LookUnlimitedTruWalls(range, fromCoordinates, current);
                }
                else
                {
                    fromCoordinates = LookUnlimited(range, fromCoordinates, current);
                }
            }
        }
        return(visibleCells);
    }