public static void UpdateDijkstraMap(PosArray<int> map,IntLocationDelegate get_cost) { PriorityQueue<cell> frontier = new PriorityQueue<cell>(c => -c.value); int height = map.objs.GetLength(0); int width = map.objs.GetLength(1); for(int i=0;i<height;++i){ for(int j=0;j<width;++j){ if(map[i,j] != U.DijkstraMin){ int v = map[i,j]; bool good = true; for(int s=-1;s<=1 && good;++s){ for(int t=-1;t<=1 && good;++t){ if(i+s >= 0 && i+s < height && j+t >= 0 && j+t < width){ if(map[i+s,j+t] < v && map[i+s,j+t] != U.DijkstraMin){ good = false; } } } } if(good){ //find local minima and add them to the frontier frontier.Add(new cell(i,j,v)); } } } } while(frontier.list.Count > 0){ cell c = frontier.Pop(); for(int s=-1;s<=1;++s){ for(int t=-1;t<=1;++t){ if(c.row+s >= 0 && c.row+s < height && c.col+t >= 0 && c.col+t < width){ int cost = get_cost(c.row+s,c.col+t); if(map[c.row+s,c.col+t] > c.value+cost){ map[c.row+s,c.col+t] = c.value+cost; frontier.Add(new cell(c.row+s,c.col+t,c.value+cost)); } } } } } }
//todo: remove dijkstra from this file, use the one in Utility? (do I have UpdateDijkstra in Utility?) public static PosArray<int> GetDijkstraMap(int height,int width,BooleanLocationDelegate is_blocked,IntLocationDelegate get_cost,List<cell> sources) { PriorityQueue<cell> frontier = new PriorityQueue<cell>(c => -c.value); PosArray<int> map = new PosArray<int>(height,width); for(int i=0;i<height;++i){ for(int j=0;j<width;++j){ if(is_blocked(i,j)){ map[i,j] = U.DijkstraMin; } else{ map[i,j] = U.DijkstraMax; } } } foreach(cell c in sources){ map[c.row,c.col] = c.value; frontier.Add(c); } while(frontier.list.Count > 0){ cell c = frontier.Pop(); for(int s=-1;s<=1;++s){ for(int t=-1;t<=1;++t){ if(c.row+s >= 0 && c.row+s < height && c.col+t >= 0 && c.col+t < width){ int cost = get_cost(c.row+s,c.col+t); if(map[c.row+s,c.col+t] > c.value+cost){ map[c.row+s,c.col+t] = c.value+cost; frontier.Add(new cell(c.row+s,c.col+t,c.value+cost)); } } } } } for(int i=0;i<height;++i){ for(int j=0;j<width;++j){ if(map[i,j] == U.DijkstraMax){ map[i,j] = U.DijkstraMin; //any unreachable areas are marked unpassable } } } return map; }