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);
    }
Exemple #2
0
 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));
            }
        }
    }