private Result CalculateMap(Vertex v, Wrappy w, Status status) { List <Goal> goals = status.goals; List <PriGoal> priGoals = new List <PriGoal>(); Map <int> distMap = new Map <int>(map.W, map.H, UNREACHABLE); distMap[w.Loc] = 0; //int min = int.MaxValue; var crossingEdges = new MinHeap <int, int>(N); var minVertices = new bool[N]; minVertices[v.Id] = true; int max_goals = Math.Min(map.H, goals.Count); foreach (var outgoingEdge in v.OutgoingEdges) { // Use a Heapify operation! crossingEdges.Insert(outgoingEdge.V2, outgoingEdge.Length); } while (crossingEdges.Count > 0) { //DijkstraPrettyPrinter.printDijkstraMap(distMap, w); var minEdge = crossingEdges.ExtractMin(); int v2 = minEdge.Key; var newVertex = vertices[v2]; int X = v2 % map.W, Y = v2 / map.W; distMap[X, Y] = minEdge.Value; if (minEdge.Value != 0) { // cerca il GoTo di coordinate X, Y (cioè il più vicino, appena estratto dal minheap) int i; if ((i = goals.FindIndex((g) => { if (g.IsGoTo) { Goal.GoTo goTo = (Goal.GoTo)g; int x = goTo.Item1, y = goTo.Item2; return(x == X && y == Y); } else { return(false); } })) >= 0) { Goal.GoTo goTo = (Goal.GoTo)goals[i]; int x = goTo.Item1, y = goTo.Item2; double pri = minEdge.Value; if (w.remainingFastWheel > 0) { if (Math.Abs(w.Loc.x - x) % 2 == 1 || Math.Abs(w.Loc.y - y) % 2 == 1) { pri *= SKIP_PRI; } else { pri *= GOTO_PRI; } } else { if (status.boosters.Exists((kvp) => kvp.Value.x == x && kvp.Value.y == y && kvp.Key == Booster.CloningPlatform)) { if (status.collectedBoosters.Contains(Booster.Cloning) || status.map[x, y] == Tile.Empty) { pri *= GOTO_PRI; } else { pri *= SKIP_PRI; } } if (status.boosters.Exists((kvp) => kvp.Value.x == x && kvp.Value.y == y && kvp.Key == Booster.Manipulator)) { pri *= GOTO_PRI; } } priGoals.Add(new PriGoal { goal = goTo, pri = pri }); //if (priGoals.Count >= max_goals) goto quit; //return new Result { distMap = distMap, priGoals = priGoals }; } } minVertices[v2] = true; //if (minEdge.Value < min) // min = minEdge.Value; foreach (var newEdge in newVertex.OutgoingEdges) { if (minVertices[newEdge.V2] || newEdge.Length == UNREACHABLE) { continue; } var edgeLength = newEdge.Length + minEdge.Value; var edge = crossingEdges.Find(newEdge.V2); if (edge != null) { if (edgeLength < edge.Value) { crossingEdges.Update(newEdge.V2, edgeLength); } } else { crossingEdges.Insert(newEdge.V2, edgeLength); } } } quit: return(new Result { distMap = distMap, priGoals = priGoals }); }
public Point(Goal.GoTo GoTo) { this.x = GoTo.Item1; this.y = GoTo.Item2; }