public Wickiup() { Size = new Size(2, 3); IsPassable = false; Id = 0x00001E00; _map = new InnerMap((int)Size.Width, (int)Size.Height); HorizontalBorder = new bool[Size.Width + 2,2]; VerticalBorder = new bool[Size.Height, 2]; for (int i = 0; i < (int)Size.Width + 2; i++) { HorizontalBorder[i, 0] = true; HorizontalBorder[i, 1] = true; } }
private InnerMap GoGenerateInternal(InnerMap map, IRandom random, Action <int, int, long, long> pixelChangedCallback) { if (pixelChangedCallback == null) { pixelChangedCallback = (vvv, yyy, zzz, www) => { }; } long totSteps = (map.Width - 1L) / 2L * ((map.Height - 1L) / 2L); long currentStep = 1; int width = map.Width; int height = map.Height; int x = 1; int y = 1; var stackje = new Stack <MazePoint>(); stackje.Push(new MazePoint(x, y)); map[x, y] = true; pixelChangedCallback.Invoke(x, y, currentStep, totSteps); MazePoint[] targets = new MazePoint[4]; while (stackje.Count != 0) { MazePoint cur = stackje.Peek(); x = cur.X; y = cur.Y; int targetCount = 0; if (x - 2 > 0 && !map[x - 2, y]) { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (x + 2 < width - 1 && !map[x + 2, y]) { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (y - 2 > 0 && !map[x, y - 2]) { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (y + 2 < height - 1 && !map[x, y + 2]) { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } if (targetCount > 0) { var target = targets[random.Next(targetCount)]; stackje.Push(target); map[target.X, target.Y] = true; currentStep++; if (target.X < x) { map[x - 1, y] = true; pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps); } else if (target.X > x) { map[x + 1, y] = true; pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps); } else if (target.Y < y) { map[x, y - 1] = true; pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps); } else if (target.Y > y) { map[x, y + 1] = true; pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps); } pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps); } else { stackje.Pop(); } } return(map); }
private void GoGenerate(InnerMap map, Maze maze, Random r, Action <int, int, long, long> pixelChangedCallback) { long totSteps = (((long)maze.Width - 1L) / 2L) * (((long)maze.Height - 1L) / 2L); long currentStep = 1; int width = maze.Width; int height = maze.Height; int x = 1; int y = 1; //Stack<MazePoint> stackje = new Stack<MazePoint>(); //stackje.Push(new MazePoint(x, y)); map[x, y] = true; pixelChangedCallback.Invoke(x, y, currentStep, totSteps); MazePoint[] targets = new MazePoint[4]; QuatroStack quatro = new QuatroStack(); //0 == top, 1 == right, 2 == bot, 3 == left Boolean backtracking = false; int prex = 0; int prey = 0; while (true) { //Console.WriteLine(quatro.Count + ", X: " + x + " Y: " + y); int targetCount = 0; if (x - 2 > 0 && !map[x - 2, y]) { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (x + 2 < width - 1 && !map[x + 2, y]) { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (y - 2 > 0 && !map[x, y - 2]) { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (y + 2 < height - 1 && !map[x, y + 2]) { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } //Thread.Sleep(1000); if (targetCount > 0) { var target = targets[r.Next(targetCount)]; if (backtracking) { backtracking = false; targetCount = 0; if (map[x - 1, y]) //Wall open at the left { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (map[x + 1, y]) //Wall open at the right { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (map[x, y - 1]) //Wall open at the top { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (map[x, y + 1]) //Wall open at the bottom { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } if (targetCount <= 2) //If currently only 2 exist at this tile, create junction { for (int i = 0; i < targetCount; i++) { var curMazePoint = targets[i]; if (curMazePoint.X != prex || curMazePoint.Y != prey) { if (curMazePoint.Y < y) { quatro.Push(0); //g.FillRectangle(Brushes.Green, x * 5, y * 5, 5, 5); } else if (curMazePoint.X > x) { quatro.Push(1); //g.FillRectangle(Brushes.Violet, x * 5, y * 5, 5, 5); } else if (curMazePoint.Y > y) { quatro.Push(2); //g.FillRectangle(Brushes.Blue, x * 5, y * 5, 5, 5); } else if (curMazePoint.X < x) { quatro.Push(3); //g.FillRectangle(Brushes.Brown, x * 5, y * 5, 5, 5); } break; } } } } //stackje.Push(target); map[target.X, target.Y] = true; currentStep++; if (target.X < x) { map[x - 1, y] = true; pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps); } else if (target.X > x) { map[x + 1, y] = true; pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps); } else if (target.Y < y) { map[x, y - 1] = true; pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps); } else if (target.Y > y) { map[x, y + 1] = true; pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps); } x = target.X; y = target.Y; prex = -1; prey = -1; pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps); } else { backtracking = true; if (map[x - 1, y]) //Wall open at the left { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (map[x + 1, y]) //Wall open at the right { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (map[x, y - 1]) //Wall open at the top { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (map[x, y + 1]) //Wall open at the bottom { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } if (targetCount > 2) //Junction { prex = x; prey = y; int whereToGo = quatro.Pop(); if (whereToGo == 0) { y -= 2; } else if (whereToGo == 1) { x += 2; } else if (whereToGo == 2) { y += 2; } else if (whereToGo == 3) { x -= 2; } } else { for (int i = 0; i < targetCount; i++) { var curMazePoint = targets[i]; if (curMazePoint.X != prex || curMazePoint.Y != prey) { prex = x; prey = y; x = curMazePoint.X; y = curMazePoint.Y; break; } } } pixelChangedCallback.Invoke(x, y, currentStep, totSteps); } if (x == 1 && y == 1) { break; } } }
public LineOfSightDeterminer(InnerMap innerMap, List <MazePoint> path) { this.innerMap = innerMap; this.path = path; }
protected void FlushMap(InnerMap map) { FlushMapImage(GetCmdletBook(), map); }
/// <summary> /// Finds the path between the start and the endpoint in a maze /// </summary> /// <param name="map">The maze.InnerMap</param> /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param> /// <returns>The shortest path in a list of points</returns> public static List <MazePoint> GoFind(InnerMap map, Action <int, int, Boolean> callBack) { return(GoFind(new MazePoint(1, 1), new MazePoint(map.Width - 3, map.Height - 3), map, callBack)); }
private void GoGenerate(InnerMap map, Maze maze, Random r, Action <int, int, long, long> pixelChangedCallback) { long totSteps = (((long)maze.Width - 1L) / 2L) * (((long)maze.Height - 1L) / 2L); long currentStep = 1; int width = maze.Width; int height = maze.Height; int x = 1; int y = 1; Stack <MazePoint> stackje = new Stack <MazePoint>(); stackje.Push(new MazePoint(x, y)); map[x, y] = true; pixelChangedCallback.Invoke(x, y, currentStep, totSteps); MazePoint[] targets = new MazePoint[4]; //form.drawPixel(x, y, brushThisUses); while (stackje.Count != 0) { MazePoint cur = stackje.Peek(); x = cur.X; y = cur.Y; int targetCount = 0; if (x - 2 > 0 && !map[x - 2, y]) { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (x + 2 < width - 1 && !map[x + 2, y]) { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (y - 2 > 0 && !map[x, y - 2]) { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (y + 2 < height - 1 && !map[x, y + 2]) { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } //Thread.Sleep(1000); if (targetCount > 0) { var target = targets[r.Next(targetCount)]; stackje.Push(target); map[target.X, target.Y] = true; currentStep++; if (target.X < x) { map[x - 1, y] = true; pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps); //form.drawPixel(x - 1, y, brushThisUses); } else if (target.X > x) { map[x + 1, y] = true; pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps); //form.drawPixel(x + 1, y, brushThisUses); } else if (target.Y < y) { map[x, y - 1] = true; pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps); //form.drawPixel(x, y - 1, brushThisUses); } else if (target.Y > y) { map[x, y + 1] = true; pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps); //form.drawPixel(x, y + 1, brushThisUses); } pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps); //form.drawPixel(target.X, target.Y, brushThisUses); } else { stackje.Pop(); } } }
public ISet <TValue> GetOrAdd(TKey key, ISet <TValue> values) { return(InnerMap.GetOrAdd(key, k => values)); }
public void CopyTo(KeyValuePair <string, object>[] array, int arrayIndex) { InnerMap.CopyTo(array, arrayIndex); }
bool ICollection <KeyValuePair <string, object> > .Contains(KeyValuePair <string, object> item) { return(InnerMap.Contains(item)); }
void ICollection <KeyValuePair <string, object> > .Clear() { InnerMap.Clear(); }
protected override void EndProcessing() { Utils.StartProfile("MapCmdlet"); var map = new InnerMap() { EnableAnimation = false, EnableScrolling = false, EnableZooming = false, EnableDelayedScrolling = false }; map.NavigationPanelOptions.ShowCoordinates = false; map.NavigationPanelOptions.ShowKilometersScale = false; map.NavigationPanelOptions.ShowMilesScale = false; switch (CoordinateSystem) { case MapCoordinateSystem.Geo: map.CoordinateSystem = new GeoMapCoordinateSystem(); break; case MapCoordinateSystem.Cartesian: map.CoordinateSystem = new CartesianMapCoordinateSystem(); break; } if (map.CoordinateSystem is GeoMapCoordinateSystem geoCoordSystem) { switch (Projection ?? MapProjection.Default) { case MapProjection.Default: //Leave projection as is break; case MapProjection.BraunStereographic: geoCoordSystem.Projection = new BraunStereographicProjection(); break; case MapProjection.EllipticalMercator: geoCoordSystem.Projection = new EllipticalMercatorProjection(); break; case MapProjection.EqualArea: geoCoordSystem.Projection = new EqualAreaProjection(); break; case MapProjection.Equidistant: geoCoordSystem.Projection = new EquidistantProjection(); break; case MapProjection.Equirectangular: geoCoordSystem.Projection = new EquirectangularProjection(); break; case MapProjection.Kavrayskiy: geoCoordSystem.Projection = new KavrayskiyProjection(); break; case MapProjection.LambertCylindricalEqualArea: geoCoordSystem.Projection = new LambertCylindricalEqualAreaProjection(); break; case MapProjection.Miller: geoCoordSystem.Projection = new MillerProjection(); break; case MapProjection.Sinusoidal: geoCoordSystem.Projection = new SinusoidalProjection(); break; case MapProjection.SphericalMercator: geoCoordSystem.Projection = new SphericalMercatorProjection(); break; } } else if ((Projection ?? MapProjection.Default) != MapProjection.Default) { throw new Exception("Projection can be set only in Geo coordinate system."); } if (ImageList != null && ImageList.Length > 0) { ExecuteLocked(() => { var images = new ImageCollection(); if (ImageSize.HasValue) { images.ImageSize = ImageSize.Value; } foreach (var imageFile in ImageList) { var imagePath = Project.Current.MapPath(imageFile); if (string.IsNullOrWhiteSpace(imagePath) || !System.IO.File.Exists(imagePath)) { throw new Exception($"Cannot find image: '{imagePath}'."); } var bmp = new Bitmap(imagePath); images.AddImage(bmp); } map.ImageList = images; }, LockFiles ? LockObject : null); } var backColor = Utils.ColorFromString(BackColor); if (backColor != Color.Empty) { map.BackColor = backColor; } var context = new MapContext() { Map = map }; WriteObject(context); }
/// <summary> /// Finds the path between the start and the endpoint in a maze /// </summary> /// <param name="start">The start point</param> /// <param name="end">The end point</param> /// <param name="map">The maze.InnerMap</param> /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param> /// <returns>The direction from begin to end</returns> public static QuatroStack GoFind(MazePoint start, MazePoint end, InnerMap map, Action <int, int, PathFinderAction> callBack) { if (callBack == null) { callBack = (x, y, z) => { }; } //Callback won't work nice with this since it will find its path from back to front //Swap them so we don't have to reverse at the end ;) MazePoint temp = start; start = end; end = temp; int width = map.Width; int height = map.Height; //List<MazePoint> stackje = new List<MazePoint>(); //stackje.Add(start); QuatroStack quatro = new QuatroStack(); //0 == top, 1 == right, 2 == bot, 3 == left MazePoint cur = start; MazePoint prev = new MazePoint(-1, -1); Boolean backtracking = false; var possibleDirections = new MazePoint[4]; int possibleDirectionsCount = 0; int maxTimesAtStart = -1; while (true) { //cur = stackje[stackje.Count - 1]; var x = cur.X; var y = cur.Y; if (!backtracking) { callBack(x, y, PathFinderAction.Step); } else { callBack(x, y, PathFinderAction.Backtrack); } possibleDirectionsCount = 0; if ((prev.X != x - 1 || prev.Y != y) && isValid(x - 1, y, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x - 1; possibleDirections[possibleDirectionsCount].Y = y; possibleDirectionsCount++; } if ((prev.X != x || prev.Y != y - 1) && isValid(x, y - 1, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x; possibleDirections[possibleDirectionsCount].Y = y - 1; possibleDirectionsCount++; } if ((prev.X != x + 1 || prev.Y != y) && isValid(x + 1, y, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x + 1; possibleDirections[possibleDirectionsCount].Y = y; possibleDirectionsCount++; } if ((prev.X != x || prev.Y != y + 1) && isValid(x, y + 1, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x; possibleDirections[possibleDirectionsCount].Y = y + 1; possibleDirectionsCount++; } if (maxTimesAtStart == -1) { //Only the first time when we are actually at start maxTimesAtStart = possibleDirectionsCount; } else if (cur.X == start.X && cur.Y == start.Y) { maxTimesAtStart--; if (maxTimesAtStart == 0) { Console.WriteLine("No path found..."); break; } } //If we have more then 2 directions we got a junction (only if we're not backtracking) (This is actually 3 directions but we only count 2 because we don't count previous direction) //If we are however at the start (which is actually the end because we swap them around) we don't create a direction because you're at the end and don't need directions //If we are however at the end (which is the start) we will create a direction if we have more then 2 directions (This is 2 because we don't have a previous one yet) if ((possibleDirectionsCount >= 2 && !backtracking && (x != start.X || y != start.Y)) || (possibleDirectionsCount >= 1 && x == end.X && y == end.Y)) { //Create junction callBack(x, y, PathFinderAction.Junction); int directionWeCameFrom = -1; if (prev.X > cur.X) { directionWeCameFrom = 1; //Previous x was bigger so we came from the right } else if (prev.Y > cur.Y) { directionWeCameFrom = 2; } else if (prev.X < cur.X) { directionWeCameFrom = 3; } else if (prev.Y < cur.Y) { directionWeCameFrom = 0; } quatro.Push(directionWeCameFrom); } if (x == end.X && y == end.Y) { //path found return(quatro); } if (possibleDirectionsCount > 0) { if (backtracking && cur.X == start.X && cur.Y == start.Y) { //This is because we don't have a junction at the start point but we want to stop backtracking anyway backtracking = false; } if (backtracking) { if (possibleDirectionsCount >= 2) //Make sure we don't start searching again in the direction we originally came from { callBack(x, y, PathFinderAction.RefoundJunction); //Set the direction we backtracked from var lastBackTrackDir = -1; if (prev.X < cur.X) { lastBackTrackDir = 0; } else if (prev.Y < cur.Y) { lastBackTrackDir = 1; } else if (prev.X > cur.X) { lastBackTrackDir = 2; } else if (prev.Y > cur.Y) { lastBackTrackDir = 3; } var foundJunction = quatro.Peek(); int previousDirectionX = 0; int previousDirectionY = 0; switch (foundJunction) { case 0: previousDirectionY = -1; break; case 1: previousDirectionX = 1; break; case 2: previousDirectionY = 1; break; case 3: previousDirectionX = -1; break; } Boolean foundSomething = false; for (int i = 0; i < possibleDirectionsCount; i++) { var probDir = possibleDirections[i]; if (probDir.X != x + previousDirectionX || probDir.Y != y + previousDirectionY) { var directionOfThisDir = -1; if (probDir.X < cur.X) { directionOfThisDir = 0; } else if (probDir.Y < cur.Y) { directionOfThisDir = 1; } else if (probDir.X > cur.X) { directionOfThisDir = 2; } else if (probDir.Y > cur.Y) { directionOfThisDir = 3; } if (directionOfThisDir > lastBackTrackDir) { prev = cur; cur = probDir; foundSomething = true; backtracking = false; break; } } } if (!foundSomething) { callBack(x, y, PathFinderAction.RemovingJunction); quatro.Pop(); prev = cur; cur.X += previousDirectionX; cur.Y += previousDirectionY; } } else { prev = cur; cur = possibleDirections[0]; } } else { prev = cur; cur = possibleDirections[0]; } } else { MazePoint curtemp = cur; cur = prev; prev = curtemp; backtracking = true; } } return(new QuatroStack()); }
public static IEnumerable <MazePointPos> DeterminePathFromDirectionsInternal(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map) { int currentDirectionPos = directions.Count - 1; var possibleDirections = new MazePointPos[4]; int possibleDirectionsCount = 0; MazePointPos prev = new MazePointPos(); MazePointPos cur = new MazePointPos(start.X, start.Y, 0); int width = map.Width; int height = map.Height; while (true) { yield return(cur); if (cur.X == end.X && cur.Y == end.Y) { //We found the path break; } int x = cur.X; int y = cur.Y; possibleDirectionsCount = 0; if ((prev.X != x - 1 || prev.Y != y) && isValid(x - 1, y, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x - 1; possibleDirections[possibleDirectionsCount].Y = y; possibleDirectionsCount++; } if ((prev.X != x || prev.Y != y - 1) && isValid(x, y - 1, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x; possibleDirections[possibleDirectionsCount].Y = y - 1; possibleDirectionsCount++; } if ((prev.X != x + 1 || prev.Y != y) && isValid(x + 1, y, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x + 1; possibleDirections[possibleDirectionsCount].Y = y; possibleDirectionsCount++; } if ((prev.X != x || prev.Y != y + 1) && isValid(x, y + 1, map, width, height)) { possibleDirections[possibleDirectionsCount].X = x; possibleDirections[possibleDirectionsCount].Y = y + 1; possibleDirectionsCount++; } if (possibleDirectionsCount == 1) { prev = cur; cur = possibleDirections[0]; } else if (possibleDirectionsCount > 1) { int directionToGo = directions.InnerList[currentDirectionPos]; currentDirectionPos--; prev = cur; switch (directionToGo) { case 0: cur.Y -= 1; break; case 1: cur.X += 1; break; case 2: cur.Y += 1; break; case 3: cur.X -= 1; break; } } } }
public static IEnumerable <MazePointPos> DeterminePathFromDirections(QuatroStack directions, MazePoint start, MazePoint end, InnerMap map) { long current = 0; long max = DeterminePathFromDirectionsInternal(directions, start, end, map).LongCount(); //This needs to happen twice sadly but else it we can't know the complete path length foreach (var point in DeterminePathFromDirectionsInternal(directions, start, end, map)) { byte formulathing = (byte)((double)current / (double)max * 255.0); current++; yield return(new MazePointPos(point.X, point.Y, formulathing)); } }
/// <summary> /// Finds the path between the start and the endpoint in a maze /// </summary> /// <param name="map">The maze.InnerMap</param> /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param> /// <returns>The direction from begin to end</returns> public static QuatroStack GoFind(InnerMap map, Action <int, int, PathFinderAction> callBack) { return(GoFind(new MazePoint(1, 1), new MazePoint(map.Width - 3, map.Height - 3), map, callBack)); }
public ISet <TValue> GetOrAdd(TKey key, Func <TKey, ISet <TValue> > valuesFactory) { return(InnerMap.GetOrAdd(key, valuesFactory)); }
protected virtual void ClearPropertyCore(string property) { InnerMap.Remove(property); }
/// <summary> /// 컬렉션을 반복하는 열거자를 반환합니다. /// </summary> /// <returns> /// 컬렉션을 반복하는 데 사용할 수 있는 <see cref="T:System.Collections.Generic.IEnumerator`1"/>입니다. /// </returns> /// <filterpriority>1</filterpriority> public IEnumerator <KeyValuePair <TKey, ISet <TValue> > > GetEnumerator() { return(InnerMap.GetEnumerator()); }
/// <summary> /// Finds the path between the start and the endpoint in a maze /// </summary> /// <param name="start">The start point</param> /// <param name="end">The end point</param> /// <param name="map">The maze.InnerMap</param> /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param> /// <returns>The shortest path in a list of points</returns> public static List <MazePoint> GoFind(MazePoint start, MazePoint end, InnerMap map, Action <int, int, Boolean> callBack) { if (callBack == null) { callBack = (x, y, z) => { }; } //Callback won't work nice with this since it will find its path from back to front //Swap them so we don't have to reverse at the end ;) //MazePoint temp = start; //start = end; //end = temp; int width = map.Width; int height = map.Height; InnerMap visitedMap = new BitArreintjeFastInnerMap(width, height); List <MazePoint> pointlist = new List <MazePoint>(); //@todo Controleer dit InnerMap visited = new BitArreintjeFastInnerMap(width, height); for (int x = 0; x < width; x++) { //visited[x] = new BitArreintjeFast(height); for (int y = 0; y < height; y++) { if (x == 0 || y == 0 || x == width || y == height) { visited[x, y] = true; } //else //{ // visited[x][y] = false; //} } } //Hier begint het gedoe Stack <MazePoint> stackje = new Stack <MazePoint>(); stackje.Push(start); visited[start.X, start.Y] = true; callBack.Invoke(start.X, start.Y, true); //form.pixelDraw(x, y, Brushes.White); while (stackje.Count != 0) { MazePoint cur = stackje.Peek(); int x = cur.X; int y = cur.Y; if (end.X == x && end.Y == y) { callBack.Invoke(x, y, true); break; } MazePoint target = new MazePoint(-1, -1); if (isValid(x + 1, y, map, visited, width, height)) { target = new MazePoint(x + 1, y); } else if (isValid(x, y + 1, map, visited, width, height)) { target = new MazePoint(x, y + 1); } else if (isValid(x - 1, y, map, visited, width, height)) { target = new MazePoint(x - 1, y); } else if (isValid(x, y - 1, map, visited, width, height)) { target = new MazePoint(x, y - 1); } //Thread.Sleep(1000); if (target.X != -1) { callBack.Invoke(x, y, true); //var target = targets[r.Next(targets.Count)]; stackje.Push(target); visited[target.X, target.Y] = true; //form.pixelDraw(target.X, target.Y, Brushes.Blue); //Thread.Sleep(200); //if (target.X < x) //{ // visited[x - 1][y] = true; // //form.pixelDraw(x - 1, y, Brushes.White); //} //else if (target.X > x) //{ // visited[x + 1][y] = true; // //form.pixelDraw(x + 1, y, Brushes.White); //} //else if (target.Y < y) //{ // visited[x][y - 1] = true; // //form.pixelDraw(x, y - 1, Brushes.White); //} //else if (target.Y > y) //{ // visited[x][y + 1] = true; // //form.pixelDraw(x, y + 1, Brushes.White); //} } else { callBack.Invoke(x, y, false); stackje.Pop(); } } pointlist.AddRange(stackje); pointlist.Reverse(); return(pointlist); }
public Maze(InnerMap customInnerMap) { innerMap = customInnerMap; }
/// <summary> /// <see cref="T:System.Collections.Generic.ICollection`1"/>에서 항목을 모두 제거합니다. /// </summary> /// <exception cref="T:System.NotSupportedException"><see cref="T:System.Collections.Generic.ICollection`1"/>가 읽기 전용인 경우 </exception> public void Clear() { InnerMap.Clear(); }
/// <summary> /// Finds the path between the start and the endpoint in a maze /// </summary> /// <param name="start">The start point</param> /// <param name="end">The end point</param> /// <param name="map">The maze.InnerMap</param> /// <param name="callBack">The callback that can be used to see what the pathfinder is doing (or null), the boolean true = a new path find thingy or false when it determined that path is not correct</param> /// <returns>The shortest path in a list of points</returns> public static List <MazePoint> GoFind(MazePoint start, MazePoint end, InnerMap map, Action <int, int, Boolean> callBack) { if (callBack == null) { callBack = (x, y, z) => { }; } //Callback won't work nice with this since it will find its path from back to front //Swap them so we don't have to reverse at the end ;) //MazePoint temp = start; //start = end; //end = temp; int width = map.Width; int height = map.Height; List <MazePoint> stackje = new List <MazePoint>(); stackje.Add(start); MazePoint cur = new MazePoint(); MazePoint prev = new MazePoint(-1, -1); var lastBackTrackDir = -1; while (stackje.Count != 0) { cur = stackje[stackje.Count - 1]; var x = cur.X; var y = cur.Y; MazePoint target = new MazePoint(-1, -1); //Make sure the point was not the previous point, also make sure that if we backtracked we don't go to a direction we already went to, also make sure that the point is white if ((prev.X != x + 1 || prev.Y != y) && lastBackTrackDir < 0 && x + 1 < width - 1 && map[x + 1, y]) { target = new MazePoint(x + 1, y); } else if ((prev.X != x || prev.Y != y + 1) && lastBackTrackDir < 1 && y + 1 < height - 1 && map[x, y + 1]) { target = new MazePoint(x, y + 1); } else if ((prev.X != x - 1 || prev.Y != y) && lastBackTrackDir < 2 && x - 1 > 0 && map[x - 1, y]) { target = new MazePoint(x - 1, y); } else if ((prev.X != x || prev.Y != y - 1) && lastBackTrackDir < 3 && y - 1 > 0 && map[x, y - 1]) { target = new MazePoint(x, y - 1); } else { var prepoppy = stackje[stackje.Count - 1]; stackje.RemoveAt(stackje.Count - 1); if (stackje.Count == 0) { //No path found break; } var newcur = stackje[stackje.Count - 1]; //Set the new previous point if (stackje.Count == 1) { prev = new MazePoint(-1, -1); } else { prev = stackje.ElementAt(stackje.Count - 2); } //Console.WriteLine("Backtracking to X: " + newcur.X + " Y: " + newcur.Y); //Console.WriteLine("Setting new prev: " + prev.X + " Y: " + prev.Y); callBack.Invoke(prepoppy.X, prepoppy.Y, false); //Set the direction we backtracked from if (prepoppy.X > newcur.X) { lastBackTrackDir = 0; } else if (prepoppy.Y > newcur.Y) { lastBackTrackDir = 1; } else if (prepoppy.X < newcur.X) { lastBackTrackDir = 2; } else if (prepoppy.Y < newcur.Y) { lastBackTrackDir = 3; } //Console.WriteLine("Lastbacktrackdir: " + lastBackTrackDir); continue; } lastBackTrackDir = -1; //Console.WriteLine("Going to X: " + target.X + " Y: " + target.Y); callBack.Invoke(x, y, true); stackje.Add(target); if (target.X == end.X && target.Y == end.Y) { //Path found break; } prev = cur; } return(stackje); }
/// <summary> /// <paramref name="value"/>를 값으로 가지고 있는지 검사합니다. /// </summary> /// <param name="value"></param> /// <returns></returns> public bool ContainsValue(TValue value) { lock (_syncLock) return(InnerMap.SelectMany(item => item.Value).Any(v => Equals(v, value))); }
/// <summary> /// 특정 <see cref="T:System.Array"/> 인덱스부터 시작하여 <see cref="T:System.Collections.Generic.ICollection`1"/>의 요소를 <see cref="T:System.Array"/>에 복사합니다. /// </summary> /// <param name="array"><see cref="T:System.Collections.Generic.ICollection`1"/>에서 복사한 요소의 대상인 일차원 <see cref="T:System.Array"/>입니다. <see cref="T:System.Array"/>의 인덱스는 0부터 시작해야 합니다.</param> /// <param name="arrayIndex"><paramref name="array"/>에서 복사가 시작되는 인덱스(0부터 시작)입니다.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="array"/>가 null인 경우</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="arrayIndex"/>가 0보다 작은 경우</exception> /// <exception cref="T:System.ArgumentException"> /// <paramref name="array"/>가 다차원인 경우-또는-소스 <see cref="T:System.Collections.Generic.ICollection`1"/>의 요소 수가 /// <paramref name="arrayIndex"/>에서 대상 <paramref name="array"/> 끝까지 사용 가능한 공간보다 큰 경우-또는-<paramref name="T"/> 형식을 대상 <paramref name="array"/>의 형식으로 자동 캐스팅할 수 없는 경우 /// </exception> public void CopyTo(KeyValuePair <TKey, ISet <TValue> >[] array, int arrayIndex) { lock (_syncLock) InnerMap.ToArray().CopyTo(array, arrayIndex); }
/// <summary> /// <see cref="T:System.Collections.Generic.IDictionary`2"/>에 지정된 키가 있는 요소가 포함되어 있는지 여부를 확인합니다. /// </summary> /// <returns> /// <see cref="T:System.Collections.Generic.IDictionary`2"/>에 해당 키가 있는 요소가 포함되어 있으면 true이고, 그렇지 않으면 false입니다. /// </returns> /// <param name="key"><see cref="T:System.Collections.Generic.IDictionary`2"/>에서 찾을 수 있는 키입니다.</param><exception cref="T:System.ArgumentNullException"><paramref name="key"/>가 null인 경우</exception> public bool ContainsKey(TKey key) { return(InnerMap.ContainsKey(key)); }
private void GoGenerate(InnerMap map, Maze maze, Random r, Action <int, int, long, long> pixelChangedCallback) { long totSteps = (((long)maze.Width - 1L) / 2L) * (((long)maze.Height - 1L) / 2L); long currentStep = 1; //needs to be optimized for (int x = 0; x < maze.Width; x++) { for (int y = 0; y < maze.Height; y++) { if (x == 0 || x == maze.Width - 1 || x == maze.Width - 2 || y == 0 || y == maze.Height - 1 || y == maze.Height - 2) { map[x, y] = false; } else { map[x, y] = true; } } } Stack <Rectangle> rectangles = new Stack <Rectangle>(); Rectangle curRect = new Rectangle(0, 0, maze.Width - 1, maze.Height - 1); rectangles.Push(curRect); while (rectangles.Count != 0) { curRect = rectangles.Pop(); if (curRect.Width > 3 && curRect.Height > 3) { Boolean horizontalSplit = true; if (curRect.Width > curRect.Height) { horizontalSplit = false; } else if (curRect.Width < curRect.Height) { horizontalSplit = true; } else { if (r.Next(2) == 0) { horizontalSplit = false; } } if (horizontalSplit) { int splitnumber = 2 + r.Next((curRect.Height - 2) / 2) * 2; int opening = 1 + r.Next((curRect.Width) / 2) * 2; Rectangle rect1 = new Rectangle(curRect.X, curRect.Y, curRect.Width, splitnumber + 1); Rectangle rect2 = new Rectangle(curRect.X, curRect.Y + splitnumber, curRect.Width, curRect.Height - splitnumber); for (int i = curRect.X; i < curRect.X + curRect.Width; i++) { if (i - curRect.X != opening) { map[i, curRect.Y + splitnumber] = false; } } //form.drawRectangle(curRect.X, curRect.Y + splitnumber, opening, 1, brushBlack); //form.drawRectangle(curRect.X + opening + 1, curRect.Y + splitnumber, curRect.Width - opening - 1, 1, brushBlack); rectangles.Push(rect1); rectangles.Push(rect2); } else { int splitnumber = 2 + r.Next((curRect.Width - 2) / 2) * 2; int opening = 1 + r.Next((curRect.Height) / 2) * 2; Rectangle rect1 = new Rectangle(curRect.X, curRect.Y, splitnumber + 1, curRect.Height); Rectangle rect2 = new Rectangle(curRect.X + splitnumber, curRect.Y, curRect.Width - splitnumber, curRect.Height); for (int i = curRect.Y; i < curRect.Y + curRect.Height; i++) { if (i - curRect.Y != opening) { map[curRect.X + splitnumber, i] = false; } } //form.drawRectangle(curRect.X + splitnumber, curRect.Y, 1, opening, brushBlack); //form.drawRectangle(curRect.X + splitnumber, curRect.Y + opening + 1, 1, curRect.Height - opening - 1, brushBlack); rectangles.Push(rect1); rectangles.Push(rect2); } } } }
/// <summary> /// <see cref="T:System.Collections.Generic.IDictionary`2"/>에서 지정한 키를 가지는 요소를 제거합니다. /// </summary> /// <returns> /// 요소가 성공적으로 제거되었으면 true이고, 그렇지 않으면 false입니다.이 메서드는 <paramref name="key"/>가 원래 <see cref="T:System.Collections.Generic.IDictionary`2"/>에 없는 경우에도 false를 반환합니다. /// </returns> /// <param name="key">제거할 요소의 키입니다.</param><exception cref="T:System.ArgumentNullException"><paramref name="key"/>가 null인 경우</exception><exception cref="T:System.NotSupportedException"><see cref="T:System.Collections.Generic.IDictionary`2"/>가 읽기 전용인 경우</exception> public bool Remove(TKey key) { ISet <TValue> set; return(InnerMap.TryRemove(key, out set)); }
private void GoGenerate(InnerMap map, Maze maze, Random r, Action <int, int, long, long> pixelChangedCallback) { int x = 1; int y = 1; Stack <MazePoint> stackje = new Stack <MazePoint>(); stackje.Push(new MazePoint(x, y)); map[x, y] = true; //pixelChangedCallback.Invoke(x, y, currentStep, totSteps); MazePoint[] targets = new MazePoint[4]; //form.drawPixel(x, y, brushThisUses); while (stackje.Count != 0) { MazePoint cur = stackje.Peek(); x = cur.X; y = cur.Y; int targetCount = 0; if (isValid(x - 2, y, map, maze)) { targets[targetCount].X = x - 2; targets[targetCount].Y = y; targetCount++; } if (isValid(x + 2, y, map, maze)) { targets[targetCount].X = x + 2; targets[targetCount].Y = y; targetCount++; } if (isValid(x, y - 2, map, maze)) { targets[targetCount].X = x; targets[targetCount].Y = y - 2; targetCount++; } if (isValid(x, y + 2, map, maze)) { targets[targetCount].X = x; targets[targetCount].Y = y + 2; targetCount++; } //Thread.Sleep(1000); if (targetCount > 0) { var target = targets[r.Next(targetCount)]; stackje.Push(target); map[target.X, target.Y] = true; if (target.X < x) { map[x - 1, y] = true; //pixelChangedCallback.Invoke(x - 1, y, currentStep, totSteps); //form.drawPixel(x - 1, y, brushThisUses); } else if (target.X > x) { map[x + 1, y] = true; //pixelChangedCallback.Invoke(x + 1, y, currentStep, totSteps); //form.drawPixel(x + 1, y, brushThisUses); } else if (target.Y < y) { map[x, y - 1] = true; //pixelChangedCallback.Invoke(x, y - 1, currentStep, totSteps); //form.drawPixel(x, y - 1, brushThisUses); } else if (target.Y > y) { map[x, y + 1] = true; //pixelChangedCallback.Invoke(x, y + 1, currentStep, totSteps); //form.drawPixel(x, y + 1, brushThisUses); } //pixelChangedCallback.Invoke(target.X, target.Y, currentStep, totSteps); //form.drawPixel(target.X, target.Y, brushThisUses); } else { stackje.Pop(); } } }
/// <summary> /// 지정된 키와 연결된 값을 가져옵니다. /// </summary> /// <returns> /// <see cref="T:System.Collections.Generic.IDictionary`2"/>를 구현하는 개체에 지정한 키가 있는 요소가 포함되어 있으면 true이고, 그렇지 않으면 false입니다. /// </returns> /// <param name="key">가져올 값이 있는 키입니다.</param><param name="value">이 메서드가 반환될 때 지정된 키가 있으면 해당 키와 연결된 값이고, 그렇지 않으면 <paramref name="value"/> 매개 변수의 형식에 대한 기본값입니다.이 매개 변수는 초기화되지 않은 상태로 전달됩니다.</param><exception cref="T:System.ArgumentNullException"><paramref name="key"/>가 null인 경우</exception> public bool TryGetValue(TKey key, out ISet <TValue> value) { return(InnerMap.TryGetValue(key, out value)); }
void Awake() { if (!playerTransform) { Debug.LogError("You must specify the player transform"); } mapRect = GetComponent<RectTransform>(); innerMap = GetComponentInChildren<InnerMap>(); if (!innerMap) { Debug.LogError("InnerMap component is missing from children"); } mapArrow = GetComponentInChildren<MapArrow>(); if (!mapArrow) { Debug.LogError("MapArrow component is missing from children"); } markerGroup = GetComponentInChildren<MarkerGroup>(); if (!markerGroup) { Debug.LogError("MerkerGroup component is missing. It must be a child of InnerMap"); } innerMapRadius = innerMap.getMapRadius(); }
public static IEnumerable <MazePointPos> DeterminePathFromDirections(QuatroStack directions, InnerMap map) { return(DeterminePathFromDirections(directions, new MazePoint(1, 1), new MazePoint(map.Width - 3, map.Height - 3), map)); }