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()); } }
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))); } } ; } }