Пример #1
0
        public static WizardPath[] DijkstraFindPath(AWizard start, DijkstraPointStopFunc stopFunc, DijkstraPointCostFunc costFunc)
        {
            start       = new AWizard(start);
            _startState = start;

            _obstacles = Combats
                         .Where(x => !x.IsOpponent && x.Id != start.Id && x.GetDistanceTo2(start) < Geom.Sqr(start.VisionRange)) // (нейтральные включительно)
                         .ToArray();

            var startCell = FindNearestCell(start);

            if (startCell == null)
            {
                return new WizardPath[] {}
            }
            ;

            var endCells = new List <Cell>();

            DijkstraStart(startCell, cell =>
            {
                var point  = _points[cell.I, cell.J];
                var status = stopFunc(point);

                if (status == DijkstraStopStatus.Take || status == DijkstraStopStatus.TakeAndStop)
                {
                    endCells.Add(cell);
                }

                if (status == DijkstraStopStatus.Stop || status == DijkstraStopStatus.TakeAndStop)
                {
                    return(true);
                }
                return(false);
            }, costFunc);

            return(endCells.Select(endCell =>
            {
                var cellsPath = DijkstraGeneratePath(startCell, endCell);

                var res = new WizardPath {
                    start
                };
                res.AddRange(cellsPath.Select(cell => _points[cell.I, cell.J]));
                return res;
            }).ToArray());
        }
    }
Пример #2
0
        public static void DijkstraStart(Cell start, DijkstraCellStopFunc stopCondition, DijkstraPointCostFunc costFunc)
        {
            var q = new PriorityQueue <Pair <double, Cell> >();

            q.Push(new Pair <double, Cell>(0.0, start));
            for (var i = 0; i <= GridSize; i++)
            {
                for (var j = 0; j <= GridSize; j++)
                {
                    _distMap[i, j]  = Const.Infinity;
                    _distPrev[i, j] = null;
                }
            }

            _distMap[start.I, start.J] = 0;
            while (q.Count > 0)
            {
                var cur     = q.Top().Second;
                var minDist = -q.Top().First;
                q.Pop();

                if (minDist > _distMap[cur.I, cur.J])
                {
                    continue;
                }

                if (stopCondition(cur))
                {
                    break;
                }

                for (var k = 0; k < _dx.Length; k++)
                {
                    var I = cur.I + _dx[k];
                    var J = cur.J + _dy[k];
                    if (I < 0 || J < 0 || I > GridSize || J > GridSize)
                    {
                        continue;
                    }

                    var distTo = _distMap[cur.I, cur.J] + WizardPath.GetSegmentWeight(_points[cur.I, cur.J], _points[I, J], false);
                    if (costFunc != null)
                    {
                        distTo += costFunc(_points[I, J]);
                    }

                    if (distTo < _distMap[I, J] && CanPass(_points[cur.I, cur.J], _points[I, J]))
                    {
                        _distMap[I, J]  = distTo;
                        _distPrev[I, J] = cur;
                        q.Push(new Pair <double, Cell>(-distTo, new Cell(I, J)));
                    }
                }
                ;
            }
        }