PairRowCol GetRandomNonBlockedCell(int nRandom = 1) { PairRowCol pos = PairRowCol.Create(0, 0); int iterCnt = 0; do { pos.Row = Random.Range(0, MazeRows); pos.Col = Random.Range(0, MazeColumns); } while (iterCnt++ < nRandom && _mg.GetCell(pos).WallState.HasFlag(MazeGenerator.MazeCell.WallStates.All)); return(pos); }
private void CleanWalls() { for (int row = 1; row < Height; ++row) { for (int col = 1; col < Width; ++col) { var current = GetCell(PairRowCol.Create(row, col)); var left = GetCell(PairRowCol.Create(row, col - 1)); var above = GetCell(PairRowCol.Create(row - 1, col)); if (left.WallState.HasFlag(MazeCell.WallStates.Right) && current.WallState.HasFlag(MazeCell.WallStates.Left)) { left.WallState ^= MazeCell.WallStates.Right; } if (above.WallState.HasFlag(MazeCell.WallStates.Bottom) && current.WallState.HasFlag(MazeCell.WallStates.Top)) { above.WallState ^= MazeCell.WallStates.Bottom; } } } }
// Start is called before the first frame update void Start() { Cursor.lockState = CursorLockMode.Confined; _mg.Height = MazeRows; _mg.Width = MazeColumns; _mg.InvertY = true; _mg.Generate(); var halfHeight = MazeRows / 2f; var halfWidth = MazeColumns / 2f; for (int row = 0; row < MazeRows; ++row) { for (int col = 0; col < MazeColumns; ++col) { Vector3 cellPos = new Vector3(col - halfWidth + 0.5f, 0, row - halfHeight + 0.5f); var cell = _mg.GetCell(row, col); if (cell.WallState.HasFlag(MazeGenerator.MazeCell.WallStates.Top)) { GameObject g = Instantiate(_horizontalWallPrefab, _wallParent is null ? this.transform : _wallParent.transform); g.name = $"Wall (N) ({row}, {col})"; g.transform.position = cellPos + new Vector3(0, g.transform.localScale.y / 2, +0.5f); } if (cell.WallState.HasFlag(MazeGenerator.MazeCell.WallStates.Bottom)) { GameObject g = Instantiate(_horizontalWallPrefab, _wallParent is null ? this.transform : _wallParent.transform); g.name = $"Wall (S) ({row}, {col})"; g.transform.position = cellPos + new Vector3(0, g.transform.localScale.y / 2, -0.5f); } if (cell.WallState.HasFlag(MazeGenerator.MazeCell.WallStates.Left)) { GameObject g = Instantiate(_verticalWallPrefab, _wallParent is null ? this.transform : _wallParent.transform); g.name = $"Wall (W) ({row}, {col})"; g.transform.position = cellPos + new Vector3(-0.5f, g.transform.localScale.y / 2, 0); } if (cell.WallState.HasFlag(MazeGenerator.MazeCell.WallStates.Right)) { GameObject g = Instantiate(_verticalWallPrefab, _wallParent is null ? this.transform : _wallParent.transform); g.name = $"Wall (E) ({row}, {col})"; g.transform.position = cellPos + new Vector3(+0.5f, g.transform.localScale.y / 2, 0); } } } { var ballPos = GetRandomNonBlockedCell(); var ballLocalPos = CellToLocal(ballPos); SpawnBall(CellToLocal(ballPos) + new Vector3(0, InitialBallHeight, 0)); PairRowCol winPos = PairRowCol.Create(0, 0); var dist = (CellToLocal(winPos) - ballLocalPos).sqrMagnitude; for (int row = 0; row < MazeRows; ++row) { for (int col = 0; col < MazeColumns; ++col) { PairRowCol pos = PairRowCol.Create(row, col); if (_mg.GetCell(pos).WallState.HasFlag(MazeGenerator.MazeCell.WallStates.All)) { continue; } var d = (CellToLocal(pos) - ballLocalPos).sqrMagnitude; if (d > dist) { dist = d; winPos = pos; } } } if (_debug) { SpawnWinningSpot(CellToLocal(PairRowCol.Create(ballPos.Row, ballPos.Col - 1)) + new Vector3(0, _winningSpotPrefab.transform.localScale.y / 2, 0)); } else { SpawnWinningSpot(CellToLocal(winPos) + new Vector3(0, _winningSpotPrefab.transform.localScale.y / 2, 0)); } } }