コード例 #1
0
    public void MoveUnit()
    {
        AttackUnit = null;
        if (path.Count == 0)
        {
            return;
        }
        List <HexCell> move = new List <HexCell>();

        move.Add(path[0]);
        int cellNumber = 1;

        while (movementLeft > 0 && path.Count > 1)
        {
            if (path.Count > cellNumber)
            {
                int movementCost = HexUnit.GetMoveCost(path[cellNumber - 1], path[cellNumber], path[cellNumber - 1].GetNeighborDirection(path[cellNumber]), true);
                if (movementCost == -1 || movementCost > movementLeft)
                {
                    break;
                }
                else
                {
                    move.Add(path[cellNumber]);
                    movementLeft -= movementCost;
                    cellNumber++;
                }
            }
            else
            {
                break;
            }
        }

        if (move.Count > 1)
        {
            AttackUnit = null;
            AttackCity = null;
            City city = move[move.Count - 1].City;
            if (city && hexUnit.HexUnitType == HexUnit.UnitType.COMBAT && GetCityState() != city.GetCityState())
            {
                AttackCity = city;
                CombatSystem.CityFight(this, city);
                SetMovementLeft(0);
            }
            else
            {
                HexUnit unitToFight = move[move.Count - 1].GetFightableUnit(HexUnit);
                if (unitToFight)
                {
                    AttackUnit = unitToFight;
                    CombatSystem.UnitFight(this, unitToFight.GetComponent <Unit>());
                    SetMovementLeft(0);
                }
            }

            path.RemoveRange(0, move.Count - 1);
            HexUnit.Travel(move);
        }
    }
コード例 #2
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);
    }
コード例 #3
0
ファイル: HexGrid.cs プロジェクト: hafewa/Hex_Map_Learn
    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);
    }
コード例 #4
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);
    }
コード例 #5
0
ファイル: HexGrid.cs プロジェクト: JackeyZ/HexMap
    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);
    }
コード例 #6
0
    /// <summary>
    /// Поиск пути
    /// </summary>
    /// <param name="fromCell"></param>
    /// <param name="toCell"></param>
    /// <returns></returns>
    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);
    }
コード例 #7
0
    void Search(HexCell fromCell, HexCell toCell, HexUnit hexUnit, List <HexCell> results)
    {
        m_currentPathFrom = fromCell;
        m_currentPathTo   = toCell;

        int speed = hexUnit.Speed;

        m_searchFrontierPhase = 2;
        ClearPath();
        ResetSearchPhase();

        for (int i = 0; i < m_cells.Count; i++)
        {
            m_cells[i].SetLabel(null);
            m_cells[i].DisableHighlight();
        }

        WaitForSeconds delay = new WaitForSeconds(1 / 60f);

        fromCell.Distance    = 0;
        fromCell.SearchPhase = m_searchFrontierPhase;
        m_searchQueue.Enqueue(fromCell);
        while (m_searchQueue.Count > 0)
        {
            //yield return delay;s
            HexCell current = m_searchQueue.Dequeue();
            current.SearchPhase += 1;

            if (current == toCell)
            {
                BuildFinalPath(fromCell, toCell);
                if (results != null && m_finalPath.Count > 0)
                {
                    results.AddRange(m_finalPath);
                }
                break;
            }

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

            for (HexDirection dir = HexDirection.NE; dir <= HexDirection.NW; dir++)
            {
                HexCell neighbour = current.GetNeighbour(dir);

                if (neighbour == null || neighbour.SearchPhase > m_searchFrontierPhase)
                {
                    continue;
                }

                if (!hexUnit.IsValidDestination(neighbour))
                {
                    continue;
                }

                int moveCost = hexUnit.GetMoveCost(current, neighbour, dir);
                if (moveCost < 0)
                {
                    continue;
                }

                int distance = current.Distance;

                int newDistance = distance + moveCost;

                int turn = (newDistance - 1) / speed;
                if (turn > currentTurn)
                {
                    newDistance = (turn * speed) + moveCost;
                }


                if (neighbour.SearchPhase < m_searchFrontierPhase)
                {
                    neighbour.SearchPhase = m_searchFrontierPhase;
                    neighbour.Distance    = newDistance;
                    SetPathCurrentNext(current, neighbour);
                    neighbour.SearchHeuristic = neighbour.Coordinates.DistanceTo(toCell.Coordinates);
                    m_searchQueue.Enqueue(neighbour);
                }
                else if (newDistance < neighbour.Distance)
                {
                    neighbour.Distance = newDistance;
                    SetPathCurrentNext(current, neighbour);
                    m_searchQueue.Change(neighbour);
                }
            }
        }


        //for (int i = 0; i < m_cells.Count; i++)
        //{
        //    yield return delay;
        //    m_cells[i].Distance = cell.Coordinates.DistanceTo(m_cells[i].Coordinates);
        //}
    }
コード例 #8
0
    private bool Search(HexCell fromCell, HexCell toCell, HexUnit unit)
    {
        int speed = unit.Speed;

        this.searchFrontierPhase += 2;

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

        fromCell.EnableHighlight(Color.blue);
        fromCell.SearchPhase = this.searchFrontierPhase;
        fromCell.Distance    = 0;
        this.searchFrontier.Enqueue(fromCell);

        while (this.searchFrontier.Count > 0)
        {
            var current = this.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 > this.searchFrontierPhase) || neighbor.Unit)
                {
                    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 < this.searchFrontierPhase)
                {
                    neighbor.SearchPhase     = this.searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.PathFrom        = current;
                    neighbor.SearchHeuristic = neighbor.coordinates.DistanceTo(toCell.coordinates);
                    this.searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    var oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    neighbor.PathFrom = current;
                    this.searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }

        return(false);
    }