internal override IEnumerable <MazeTransformationStep> InternalGenerateMazeFullSize() { InitializeMaze(); entrance = new MazeCoordinate(upperleft.X + 1 + Random.Next(this.CurrentMaze.GetWidth() - 2), upperleft.Y); pointStack.Push(entrance); Nullable <MazeCoordinate> newCorridor; while (pointStack.Count() != 0) { newCorridor = FindWay(); if (newCorridor == null) { newCorridor = pointStack.Pop(); // One step back if (newCorridor != null && CurrentMaze.WouldChangeMazeFieldType(newCorridor.Value, MazeFieldType.Corridor)) { yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor)); } } else { pointStack.Push(newCorridor.Value); yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor)); } } yield return(TryPlaceEntrance()); yield return(TryPlaceExit()); }
private bool IsValidWay(MazeCoordinate point, MazeCoordinate comeFrom) { if (!this.CurrentMaze.IsPointInMaze(point)) { return(false); } // Already something other than a wall? if (this.CurrentMaze.GetMazeTypeOnPos(point) != MazeFieldType.Wall) { return(false); } // Make sure we do not create a way through a wall. MazeCoordinate up = new MazeCoordinate(point.X, point.Y - 1); MazeCoordinate right = new MazeCoordinate(point.X + 1, point.Y); MazeCoordinate down = new MazeCoordinate(point.X, point.Y + 1); MazeCoordinate left = new MazeCoordinate(point.X - 1, point.Y); MazeCoordinate[] pointsToCheck = { up, right, down, left }; for (int i = 0; i < pointsToCheck.Length; i++) { if (!pointsToCheck[i].Equals(comeFrom)) { if (CurrentMaze.GetMazeTypeOnPos(pointsToCheck[i]) == MazeFieldType.Corridor) { return(false); } } } return(true); }
/// <summary> /// Tries to find a place for the wall in the specified rectangle. /// </summary> /// <returns>An integer which describes the x coordinate where the wall should be placed</returns> private int TryPlaceWallVertical(MazeCoordinate recUpperleft, MazeCoordinate recDownright, Strategy strategy) { // first collect all possible coordinates int from = recUpperleft.X + 2; int to = recDownright.X - 2; int count = to - from; if (count <= 0) { return(-1); } var possibleVerticalCoordinates = Enumerable.Range(from, to - from).ToList(); while (possibleVerticalCoordinates.Count() > 0) { //try them one by one int coordinateToTest = ChooseCoordinateBasedOnStrategy(strategy, possibleVerticalCoordinates); // will it cover a corridor? if (!(CurrentMaze.IsCorridor(new MazeCoordinate(coordinateToTest, recUpperleft.Y)) || CurrentMaze.IsCorridor(new MazeCoordinate(coordinateToTest, recDownright.Y)))) { // found valid coordinate return(coordinateToTest); } possibleVerticalCoordinates.Remove(coordinateToTest); } // Failed to find a good coordinate. return(-1); }
private Nullable <MazeCoordinate> FindWay() { MazeCoordinate akt = pointStack.Peek(); possibleWays.Clear(); // four possible directions possibleWays.Add(new MazeCoordinate(akt.X, akt.Y - 1)); possibleWays.Add(new MazeCoordinate(akt.X + 1, akt.Y)); possibleWays.Add(new MazeCoordinate(akt.X - 1, akt.Y)); possibleWays.Add(new MazeCoordinate(akt.X, akt.Y + 1)); int i = Random.Next(possibleWays.Count); while (possibleWays.Count != 0) { if (IsValidWay(possibleWays[i], akt)) { return(possibleWays[i]); } else { possibleWays.Remove(possibleWays[i]); if (possibleWays.Count != 0) { i = Random.Next(possibleWays.Count); } } } return(null); }
public void MazeCoordinate_EqualsReturnsFalse_WhenComparedWithDiffObject() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1336, 42); Assert.False(foo.Equals(bar)); Assert.False(bar.Equals(foo)); }
public void MazeCoordinate_IsAdjacentReturnsTrue_ifDirectlyAdjacent() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1337, 41); Assert.True(foo.IsAdjacentTo(bar)); Assert.True(bar.IsAdjacentTo(foo)); }
public void MazeCoordinate_IsAdjacentReturnsFalse_ifTheSameCoordinate() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1337, 42); Assert.False(foo.IsAdjacentTo(bar)); Assert.False(bar.IsAdjacentTo(foo)); }
public void MazeCoordinate_IsAdjacentReturnsFalse_ifNotAdjacentVerticalOrHorizontal() { var foo = new MazeCoordinate(1336, 41); var bar = new MazeCoordinate(1337, 42); Assert.False(foo.IsAdjacentTo(bar)); Assert.False(bar.IsAdjacentTo(foo)); }
public void MazeCoordinate_EqualsReturnsTrue_WhenComparedWithEqualObject() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1337, 42); Assert.True(foo.Equals(bar)); Assert.True(bar.Equals(foo)); }
public override IEnumerable <MazeTransformationStep> InitializeMaze() { downright = new MazeCoordinate(CurrentMaze.GetWidth() - 1, 0); upperleft = new MazeCoordinate(0, CurrentMaze.GetHeight() - 1); CurrentMaze.OverrideAllMazeFields(MazeFieldType.Wall); return(null); }
public override IEnumerable <MazeTransformationStep> InitializeMaze() { this.CurrentMaze.OverrideAllMazeFields(); downright = new MazeCoordinate(this.CurrentMaze.GetWidth() - 1, 0); upperleft = new MazeCoordinate(0, this.CurrentMaze.GetHeight() - 1); foreach (var step in this.CurrentMaze.MakeRectangle(upperleft, downright)) { yield return(step); } }
public void MazeCoordinate_ListContainsWorks_WhenLookingForDiffObj() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1337, 41); var list = new List <MazeCoordinate>(); list.Add(foo); Assert.DoesNotContain(bar, list); }
public void MazeCoordinate_ListContainsWorks_WhenLookingForIdenticalObj() { var foo = new MazeCoordinate(1337, 42); var bar = new MazeCoordinate(1337, 42); var list = new List <MazeCoordinate>(); list.Add(foo); Assert.Contains(bar, list); }
private int FindVerticalCorridor(ref MazeCoordinate recUpperleft, ref MazeCoordinate recDownright) { int type = Random.Next(2); switch (type) { case 1: // top return(recUpperleft.Y - 1); default: // bottom return(recDownright.Y + 1); } }
private int FindHorizontalCorridor(ref MazeCoordinate recUpperleft, ref MazeCoordinate recDownright) { int type = Random.Next(2); switch (type) { case 1: // right return(recDownright.X - 1); default: // left return(recUpperleft.X + 1); } }
internal override IEnumerable <MazeTransformationStep> InternalGenerateMazeFullSize() { InitializeMaze(); VisitedList = new HashSet <MazeCoordinate>(); WallsList = new HashSet <MazeCoordinate>(); // Pick a cell and mark it as part of the maze entrance = new MazeCoordinate(Random.Next(1, this.CurrentMaze.GetWidth() - 2), this.CurrentMaze.GetHeight() - 2); VisitedList.Add(entrance); yield return(this.CurrentMaze.SetMazeTypeOnPos(entrance, MazeFieldType.Corridor)); //add the walls to the wall list AddToWallList(entrance); int rand; MazeCoordinate temp; while (WallsList.Count > 0) // while there are walls { // Pick random wall rand = Random.Next(WallsList.Count); temp = WallsList.ElementAt(rand); // If the wall does not divide two cells if (!checkIfWallDividesTwoCorridors(temp)) { VisitedList.Add(temp); // make the wall a passage yield return(this.CurrentMaze.SetMazeTypeOnPos(temp, MazeFieldType.Corridor)); WallsList.Remove(temp); addSourroundingWallsToWallList(temp); } else { WallsList.Remove(temp); } } yield return(TryPlaceExit()); yield return(TryPlaceEntrance()); }
private void addSourroundingWallsToWallList(MazeCoordinate target) { MazeCoordinate[] temp = MazeCoordinate.GetHorizontalVerticalAdjacentCoordinates(target); for (int i = 0; i < temp.Length; i++) { if (this.CurrentMaze.IsPointInMaze(temp[i])) { if (!VisitedList.Contains(temp[i])) { if (!WallsList.Contains(temp[i])) { WallsList.Add(temp[i]); } } } } }
private IEnumerable <MazeTransformationStep> RekursiveDiv(MazeCoordinate recUpperleft, MazeCoordinate recDownright, bool horizontal) { int width = recDownright.X - recUpperleft.X; int height = recUpperleft.Y - recDownright.Y; int minSize = 0; Strategy currentStrategy = CheckWhichStrategyToUse(width, height); if (!(width < minSize && height < minSize)) { // Override the random decision for horizontal/vertical wall placement, this reduces long stretched corridors if (width > height) { horizontal = false; } else { horizontal = true; } if (horizontal) {// Horizontal int newWallY = TryPlaceWallHorizontal(recUpperleft, recDownright, currentStrategy); if (newWallY > 0) { for (int i = 1; i < width; i++) { // Create wall yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(recUpperleft.X + i, newWallY), MazeFieldType.Wall)); } // Place corridor int randX = FindHorizontalCorridor(ref recUpperleft, ref recDownright); yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(randX, newWallY), MazeFieldType.Corridor)); // up MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y); MazeCoordinate downrightNew = new MazeCoordinate(recDownright.X, newWallY); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } // down upperleftNew = new MazeCoordinate(recUpperleft.X, newWallY); downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } } } else {// Vertical int newWallX = TryPlaceWallVertical(recUpperleft, recDownright, currentStrategy); if (newWallX > 0) { for (int i = 1; i < height; i++) { // Create Wall yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, recDownright.Y + i), MazeFieldType.Wall)); } // Place corridor int randY = FindVerticalCorridor(ref recUpperleft, ref recDownright); yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, randY), MazeFieldType.Corridor)); //left MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y); MazeCoordinate downrightNew = new MazeCoordinate(newWallX, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } //right upperleftNew = new MazeCoordinate(newWallX, recUpperleft.Y); downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } } } } }
private bool checkIfWallDividesTwoCorridors(MazeCoordinate target) { MazeCoordinate[] temp = MazeCoordinate.GetHorizontalVerticalAdjacentCoordinates(target); int TargetWallAlignsWithCorridors = 0; foreach (MazeCoordinate c in temp) { if (this.CurrentMaze.GetMazeTypeOnPos(c) == MazeFieldType.Corridor) { if (target.X == c.X || target.Y == c.Y) { TargetWallAlignsWithCorridors++; } } } // direct connection if (TargetWallAlignsWithCorridors > 2) { return(true); } temp = MazeCoordinate.GetAllAdjacentCoordinates(target); int CorridorFieldsInCloseProximity = 0; HashSet <MazeCoordinate> inProximity = new HashSet <MazeCoordinate>(); foreach (MazeCoordinate c in temp) { if (CurrentMaze.GetMazeTypeOnPos(c) != MazeFieldType.Wall) { CorridorFieldsInCloseProximity++; inProximity.Add(c); } } // This value can be reduced to create more narrow sideways, maybe make it configurable ? if (CorridorFieldsInCloseProximity >= 3) { return(true); } if (CorridorFieldsInCloseProximity == 2) { // check if the corridors are adjacent each other then its OK. foreach (MazeCoordinate c in inProximity) { var subset = inProximity.Where(x => x != c).AsEnumerable(); bool allAdjacent = subset.All(x => x.IsAdjacentTo(c)); if (allAdjacent) { return(false); } } return(true); } if (TargetWallAlignsWithCorridors > 1 && CorridorFieldsInCloseProximity >= 2) { return(true); } else { return(false); } }