public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue) { MazeData.CreateEmpty(size); var tree = new KruskalTree(size); var mazeWidth = size; var mazeHeight = size; AppData.AppState = AppData.AppStates.LongTask; var walls = new LinkedList<MazePoint>(); for (var i = 1; i < mazeWidth - 1; i++) { var extra = i % 2 == 0 ? 1 : 0; for (var j = 2 - extra; j < mazeHeight - 2 + extra; j += 2) if (MazeData.MazeMatrix[i, j].State == CellState.Wall) walls.AddLast(new MazePoint(i, j)); } walls.Shuffle(); while (walls.First != null && AppData.AppState == AppData.AppStates.LongTask) { /*if (AnimateCheckBox.Checked) BeginInvoke(fetchKruskalInfoDelegate);*/ var wall = walls.First.Value; var x = 0; var y = 0; if (wall.X % 2 == 0 && wall.Y % 2 == 1) x = 1; else if (wall.X % 2 == 1 && wall.Y % 2 == 0) y = 1; var connected = tree.AreConnected(wall.X - x, wall.Y - y, wall.X + x, wall.Y + y); if (!connected) { MazeData.MazeMatrix[wall.X - x, wall.Y - y].State = CellState.Walkway; MazeData.MazeMatrix[wall.X, wall.Y].State = CellState.Walkway; MazeData.MazeMatrix[wall.X + x, wall.Y + y].State = CellState.Walkway; tree.Connect(wall.X - x, wall.Y - y, wall.X + x, wall.Y + y); if (animationDelay > 0) Utils.Sleep(animationDelay); } walls.RemoveFirst(); } MakeEntranceExit(); AppData.AppState = AppData.AppStates.Idle; /*MakeEntranceExit(AnimateCheckBox.Checked); if (!AnimateCheckBox.Checked) DrawMatrix(true); Invoke(() => EnableButtons()); _debugStopwatch.Toc(true); _debugStopwatch.Reset(true);*/ }
public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue) { MazeData.CreateEmpty(size, true); var mazeWidth = size; var mazeHeight = size; AppData.AppState = AppData.AppStates.LongTask; RecursivelyGenerate(0, 0, mazeWidth, mazeHeight, 1, animationDelay); MakeEntranceExit(); AppData.AppState = AppData.AppStates.Idle; }
public static HeatPoint[,] Generate(int fromX, int fromY, bool draw, int breakOnX, int breakOnY) { var _mazeWidth = MazeData.MazeSize; var _mazeHeight = MazeData.MazeSize; //distMatrix = new int[_mazeWidth, _mazeHeight]; //precMatrix = new MazePoint[_mazeWidth, _mazeHeight]; var heatMatrix = new HeatPoint[_mazeWidth, _mazeHeight]; for (int i = 0; i < _mazeWidth; i++) { for (int j = 0; j < _mazeHeight; j++) { heatMatrix[i, j] = new HeatPoint(); } } var point = new MazePoint(fromX, fromY); var row = new LinkedList <MazePoint>(); row.AddFirst(point); var endPointFound = false; var count = 1; var newCount = -1; var index = -1; for (var curr = row.First; curr != null; curr = curr.Next) { index++; if (AppData.AppState == AppData.AppStates.Idle) { break; } if (index == count) { newCount = row.Count; } if (index == newCount) { for (var i = 0; i < count; i++) { row.RemoveFirst(); } index -= count; count = newCount - count; newCount = row.Count; } var adjPoints = MazeData.GetAdjPoints(curr.Value); foreach (var adjPoint in adjPoints) { MazePoint goToPoint; /*if (MazeData.MazeMatrix[adjPoint.X, adjPoint.Y] == CellState.HorWeave || * MazeData.MazeMatrix[adjPoint.X, adjPoint.Y] == CellState.VertWeave) * { * goToPoint = new MazePoint(adjPoint.X + (adjPoint.X - curr.Value.X), * adjPoint.Y + (adjPoint.Y - curr.Value.Y)); * } * else*/ goToPoint = adjPoint; if (row.Contains(goToPoint)) { continue; } row.AddLast(goToPoint); heatMatrix[goToPoint.X, goToPoint.Y].Preceding = curr.Value; heatMatrix[goToPoint.X, goToPoint.Y].Distance = heatMatrix[curr.Value.X, curr.Value.Y].Distance + 1; if (breakOnX > 0 && breakOnY > 0 && goToPoint.X == breakOnX && goToPoint.Y == breakOnY) { endPointFound = true; break; } } //if (AnimateCheckBox.Checked && Convert.ToInt32(DelayTextBox.Text) > 0) // Thread.Sleep(Convert.ToInt32(DelayTextBox.Text)); if (endPointFound) { break; } } /*for (var i = 0; i < _mazeWidth; i++) * { * for (var j = 0; j < _mazeHeight; j++) * { * switch (_mazeMatrix[i, j]) * { * case CellState.VertWeave: * distMatrix[i, j] = (distMatrix[i + 1, j] + distMatrix[i - 1, j]) / 2; * break; * case CellState.HorWeave: * distMatrix[i, j] = (distMatrix[i, j + 1] + distMatrix[i, j - 1]) / 2; * break; * } * } * }*/ if (!draw) { return(heatMatrix); } var maxDist = 1; for (var i = 0; i < _mazeWidth; i++) { for (var j = 0; j < _mazeHeight; j++) { if (heatMatrix[i, j].Distance > maxDist) { maxDist = heatMatrix[i, j].Distance; } } } for (var i = 0; i < _mazeWidth; i++) { for (var j = 0; j < _mazeHeight; j++) { if (MazeData.MazeMatrix[i, j] == null || MazeData.MazeMatrix[i, j].State == CellState.Wall) { continue; } var red = heatMatrix[i, j].Distance * 255 / maxDist; Color c; if (heatMatrix[i, j].Distance < 1) { c = MazeData.MazeColors[CellState.Entrance]; } else if (heatMatrix[i, j].Distance > maxDist - 1) { c = MazeData.MazeColors[CellState.Furthest]; } else { c = Color.FromRgba(50 * 256 * 256 + 50 * 256 + red); } MazeData.MazeMatrix[i, j].Display = c; } } return(heatMatrix); }
public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue) { MazeData.CreateEmpty(size); var mazeWidth = size; var mazeHeight = size; AppData.AppState = AppData.AppStates.LongTask; var verticalInfluenceValue = 500; var binaryTreeValue = 0; const bool startFromBottom = false; for (var j = startFromBottom ? 1 : mazeHeight - 2; startFromBottom?j < mazeHeight - 1 : j > 0; j += startFromBottom ? 2 : -2) { if (AppData.AppState != AppData.AppStates.LongTask) { break; } var setLength = 1; for (var i = 1; i < mazeWidth - 1; i += 2) { if (AppData.AppState != AppData.AppStates.LongTask) { break; } bool digHorizontal; var useBinaryTree = _rng.Next(0, 1000) >= binaryTreeValue; //var dirX = binaryTreeValue == 0 && (NWBiasRadioButton.Checked || SWBiasRadioButton.Checked) ? -1 : 1; //var dirY = binaryTreeValue == 0 && (SWBiasRadioButton.Checked || SEBiasRadioButton.Checked) ? 1 : -1; var dirX = 1; var dirY = 1; var canGoHorizontal = dirX > 0 ? i < MazeData.MazeSize - 2 : i > 2; var canGoVertical = dirY > 0 ? j < MazeData.MazeSize - 2 : j > 2; //var canGoHorizontal = i > 2 && i < MazeData.MazeSize - 2; //var canGoVertical = j > 2 && j < MazeData.MazeSize - 2; //var canGoHorizontal = _mazeRectangle.Contains(i + dirX * 2, j); //var canGoVertical = _mazeRectangle.Contains(i, j + dirY * 2); if (!canGoHorizontal && !canGoVertical) { continue; } if (canGoHorizontal && canGoVertical) { digHorizontal = _rng.Next(0, 1000) >= verticalInfluenceValue; } else if (canGoHorizontal) { digHorizontal = true; } else { digHorizontal = false; } if (digHorizontal) { setLength++; MazeData.MazeMatrix[i + dirX, j].State = CellState.Walkway; MazeData.MazeMatrix[i + dirX * 2, j].State = CellState.Walkway; } else { //var rand = useBinaryTree ? 0 : _rng.Next(0, setLength) * 2; var rand = _rng.Next(0, setLength) * 2; setLength = 1; MazeData.MazeMatrix[i - rand, j + dirY].State = CellState.Walkway; } MazeData.MazeMatrix[i, j].State = CellState.Walkway; if (animationDelay > 0) { Utils.Sleep(animationDelay); } } } MakeEntranceExit(); AppData.AppState = AppData.AppStates.Idle; }
public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue) { MazeData.CreateEmpty(size); //var loopValue = 0; //var weaveValue = 0; var useInfluences = false; var leftInfluence = 0; var rightInfluence = 0; var upInfluence = 0; var downInfluence = 0; var _mazeWidth = size; var _mazeHeight = size; var row = _rng.Next(0, _mazeWidth / 2 - 1) * 2 + 1; var col = _rng.Next(0, _mazeHeight / 2 - 1) * 2 + 1; var path = new List <MazePoint> { new MazePoint(row, col) }; MazeData.MazeMatrix[row, col].State = CellState.Walkway; AppData.AppState = AppData.AppStates.LongTask; //var permitloop = false; var success = true; var moveVect = MazeData.Directions[-1]; while (path.Count > 0 && AppData.AppState == AppData.AppStates.LongTask) { int currIndex; if (_rng.Next(1, 1001) < behaviorValue) { currIndex = _rng.Next(0, path.Count); } else { currIndex = path.Count - 1; } row = path[currIndex].X; col = path[currIndex].Y; //var origRow = row; //var origCol = col; //success = TryDig(ref row, ref col, out moveVect, _rng.Next(0, 1001) < weaveValue, false, useInfluences ? new List<int> { leftInfluence, rightInfluence, upInfluence, downInfluence } : null); var rand = 0; //var val = 0; var probabilities = useInfluences ? new List <int> { leftInfluence, rightInfluence, upInfluence, downInfluence } : null; if (probabilities == null) { probabilities = new List <int> { 1, 1, 1, 1 } } ; var dirCopy = new List <MazePoint>(MazeData.Directions.Values); for (var i = 0; i < 4; i++) { if (probabilities.All(x => x == 0)) { rand = _rng.Next(0, probabilities.Count); } else { for (var j = 0; j < probabilities.Count; j++) { var leftProb = 0; for (var k = j; k < probabilities.Count; k++) { leftProb += probabilities[k]; } var currProb = (1000000 * probabilities[j]) / leftProb; if (_rng.Next(1, 1000001) < currProb) { rand = j; break; } } } var direction = dirCopy[rand]; if (MazeData.IsPointInMaze(row + direction.X * 2, col + direction.Y * 2)) { // Looping //if (allowLoop) //{ // if (MazeData.MazeMatrix[row + direction.X, col + direction.Y] != CellState.Wall) continue; // MazeData.MazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway; // moveVector = new MyPoint(direction.X * 2, direction.Y * 2); // row += moveVector.X; // col += moveVector.Y; // return true; //} // Simple generation if (MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State == CellState.Wall) { MazeData.MazeMatrix[row + direction.X, col + direction.Y].State = CellState.Walkway; MazeData.MazeMatrix[row + direction.X, col + direction.Y].Display = MazeData.MazeColors[CellState.Generating]; MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State = CellState.Walkway; MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].Display = MazeData.MazeColors[CellState.Generating]; moveVect = new MazePoint(direction.X * 2, direction.Y * 2); row += moveVect.X; col += moveVect.Y; success = true; break; } // Weaving //if (allowWeave && _mazeRectangle.Contains(row + direction.X * 4, col + direction.Y * 4) // && _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] == CellState.Walkway // && _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] == CellState.Wall // && _mazeMatrix[row + direction.X, col + direction.Y] == CellState.Wall) //{ // _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] = // direction.Y == 0 ? CellState.HorWeave : CellState.VertWeave; // _mazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway; // _mazeMatrix[row + direction.X * 3, col + direction.Y * 3] = CellState.Walkway; // _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] = CellState.Walkway; // moveVector = new MyPoint(direction.X * 4, direction.Y * 4); // row += moveVector.X; // col += moveVector.Y; // return true; //} } dirCopy.RemoveAt(rand); try { probabilities.RemoveAt(rand); } catch { } if (i == 3) { //moveVect = MazeData.Directions[-1]; success = false; } } // Failed to generate if (success) { //permitloop = true; path.Add(new MazePoint(row, col)); } else { //if (permitloop && _rng.Next(0, 101) < loopValue) //{ // TryDig(ref row, ref col, out moveVect, false, true, null); // if (AnimateCheckBox.Checked) // { // var rowDiff = row - origRow; // var colDiff = col - origCol; // if (rowDiff != 0) // DrawCell(origRow + (rowDiff > 0 ? 1 : -1), origCol, MazeColors.Walkway.Brush); // else if (colDiff != 0) // DrawCell(origRow, origCol + (colDiff > 0 ? 1 : -1), MazeColors.Walkway.Brush); // RefreshPictureBox(row, col, 1); // } //} //permitloop = false; for (var i = -1; i < 4; i++) { for (var j = 1; j < 2; j++) { var x = row + MazeData.Directions[i].X * j; var y = col + MazeData.Directions[i].Y * j; if (MazeData.MazeMatrix[x, y] != null && MazeData.MazeMatrix[x, y].State != CellState.Wall) { MazeData.MazeMatrix[x, y].Display = MazeData.MazeColors[CellState.Walkway]; } } } path.RemoveAt(currIndex); } if (animationDelay > 0) { Utils.Sleep(animationDelay); } } //GC.Collect(); MakeEntranceExit(); AppData.AppState = AppData.AppStates.Idle; } /*private bool TryDig(ref int row, ref int col, out MazePoint moveVector, bool allowWeave, bool allowLoop, List<int> probabilities) * { * var rand = 0; * //var val = 0; * if (probabilities == null) * probabilities = new List<int> { 1, 1, 1, 1 }; * var dirCopy = new List<MazePoint>(MazeData.Directions.Values); * * for (var i = 0; i < 4; i++) * { * if (probabilities.All(x => x == 0)) * rand = _rng.Next(0, probabilities.Count); * else * for (var j = 0; j < probabilities.Count; j++) * { * var leftProb = 0; * for (var k = j; k < probabilities.Count; k++) * leftProb += probabilities[k]; * var currProb = (1000000 * probabilities[j]) / leftProb; * if (_rng.Next(1, 1000001) < currProb) * { * rand = j; * break; * } * } * * var direction = dirCopy[rand]; * * if (MazeData.IsPointInMaze(row + direction.X*2, col + direction.Y*2)) * { * // Looping * //if (allowLoop) * //{ * // if (MazeData.MazeMatrix[row + direction.X, col + direction.Y] != CellState.Wall) continue; * // MazeData.MazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway; * // moveVector = new MyPoint(direction.X * 2, direction.Y * 2); * // row += moveVector.X; * // col += moveVector.Y; * // return true; * //} * * // Simple generation * if (MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State == CellState.Wall) * { * MazeData.MazeMatrix[row + direction.X, col + direction.Y].State = CellState.Walkway; * MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State = CellState.Walkway; * moveVector = new MazePoint(direction.X * 2, direction.Y * 2); * row += moveVector.X; * col += moveVector.Y; * return true; * } * * // Weaving * //if (allowWeave && _mazeRectangle.Contains(row + direction.X * 4, col + direction.Y * 4) * // && _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] == CellState.Walkway * // && _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] == CellState.Wall * // && _mazeMatrix[row + direction.X, col + direction.Y] == CellState.Wall) * //{ * // _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] = * // direction.Y == 0 ? CellState.HorWeave : CellState.VertWeave; * // _mazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway; * // _mazeMatrix[row + direction.X * 3, col + direction.Y * 3] = CellState.Walkway; * // _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] = CellState.Walkway; * // moveVector = new MyPoint(direction.X * 4, direction.Y * 4); * // row += moveVector.X; * // col += moveVector.Y; * // return true; * //} * } * dirCopy.RemoveAt(rand); * try { probabilities.RemoveAt(rand); } * catch { } * // TODO: fix random error * } * // Failed to generate * moveVector = MazeData.Directions[-1]; * return false; * }*/ }