scottwmaxwell / minesweeper

C# III Milestone
1 stars 0 forks source link

Create Gameboard & Cell Classes #13

Closed scottwmaxwell closed 2 months ago

scottwmaxwell commented 2 months ago

The Gameboard class should hold the main logic of the game that contains a list or array of Button objects.

We could probably steal most of the code for this from CST-250 below.

 public class Cell
    {
        // Used to locate Cell on Board
        private int Row;
        // Used to locate Cell on Board
        private int Column;
        // Used to indicate if checked
        private bool Visited;
        // Used to indicate if mine exists
        private bool Live;
        // Used to indicate cells with mines around this cell
        private int LiveNeighbors;
        // Used to indicate if user has placed flag on cell
        private bool isFlagged;

        public Cell(int row, int column) 
        {
            this.Row = row;
            this.Column = column;
            this.Visited = false;
            this.Live = false;
            this.LiveNeighbors = 0;
        }

        public int getRow()
        {
            return this.Row;
        }

        public void setRow(int row)
        {
            this.Row = row;
        }  

        public int getColumn()
        {
            return this.Column;
        }

        public void setColumn(int column)
        {
            this.Column = column;
        }

        public bool isVisited()
        {
            return this.Visited;
        }

        public void setVisited(bool visited)
        {
            this.Visited = visited;
        }

        public bool isLive()
        {
            return this.Live;
        }

        public void setFlagged(bool flagged)
        {
            this.isFlagged = flagged;
        }

        public bool getFlagged()
        {
            return this.isFlagged;
        }

        public void setLive(bool live)
        {
            this.Live = live;
        }

        public int getLiveNeighbors()
        {
            return this.LiveNeighbors;
        }

        public void setLiveNeighbors(int liveNeighbors)
        {
            this.LiveNeighbors = liveNeighbors;
        }

    }
public class Board
    {
        private int Size;
        private Cell[,] Grid;
        private double Difficulty;

        public Board(int size)
        {
            this.Size = size;

            // Initialize Grid
            Grid = new Cell[Size, Size];

            // Instantiate cells in each index of the multi-demonstional array
            for(int index = 0; index < Size; index++)
            {
                for(int index2 =0; index2 < Size; index2++)
                {
                    Cell cell = new Cell(index, index2);
                    Grid[index, index2] = cell;
                    // double x = .25;
                    // int y = (int)(x * 100);
                }
            }

            // Set default difficulty
            this.Difficulty = .40;
        }

        public void setupLiveNeighbors()
        {

            // Reset Grid
            for (int index = 0; index < Size; index++)
            {
                for (int index2 = 0; index2 < Size; index2++)
                {
                    Cell cell = new Cell(index, index2);
                    Grid[index, index2] = cell;
                }
            }

            // Determine # of mines based upon difficulty
            int numOfMines = (int)((Difficulty / 2) * (Size * Size));

            // Place mines randomly across board
            Random random = new Random();
            for(int index = 0; index < numOfMines; index++)
            {

                // Generate new random numbers until mine is placed
                bool placed = false;
                while (placed == false)
                {
                    int row = random.Next(0, Size);
                    int column = random.Next(0, Size);

                    // Check if cell already has a mine
                    if (Grid[row, column].isLive() != true)
                    {
                        Grid[row, column].setLive(true);
                        placed = true;
                    }
                }
            }
        }

        // returns true if there are unvisited cells without a bomb
        public bool checkUnivisted()
        {
            for(int i = 0; i < Size; i++)
            {
                for (int j = 0; j < Size; j++)
                {
                    if (Grid[i, j].isVisited() == false && Grid[i, j].isLive() == false)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public void calculateLiveNeighbors()
        {

            foreach (Cell cell in Grid)
            {

                int currentRow = cell.getRow();
                int currentColumn = cell.getColumn();
                int liveNeighbors = 0;

                // check if column exists right to this cell
                if (currentColumn < Size - 1)
                {
                    // check right (current column position +1)
                    if (Grid[currentRow, currentColumn + 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // check if column exists right to this cell
                if (currentColumn > 0)
                {
                    // check right (current column position +1)
                    if (Grid[currentRow, currentColumn - 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // check if row exists above this cell
                if (currentRow > 0)
                {
                    // check top (current row position -1)
                    if (Grid[currentRow - 1, currentColumn].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // chekc if row exists below this cell
                if(currentRow < Size - 1)
                {
                    // check bottom (current row position +1)
                    if (Grid[currentRow + 1, currentColumn].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // Check if cell exists top left
                if(currentRow > 0 && currentColumn > 0)
                {
                    // check top-left (current row -1 & current column -1)
                    if (Grid[currentRow - 1, currentColumn - 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // Check if cell exists top right
                if(currentRow > 0 && currentColumn < Size - 1)
                {
                    // check top-right (current row -1 & current column +1)
                    if (Grid[currentRow - 1, currentColumn + 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                // Check if cell bottom left exists
                if(currentRow < Size -1 && currentColumn > 0)
                {
                    // check bottom-left (current row +1 & current column -1)
                    if (Grid[currentRow + 1, currentColumn - 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                }

                if(currentRow < Size - 1 && currentColumn < Size - 1)
                {
                    // check bottom-right (current row +1 & current column +1)
                    if (Grid[currentRow + 1, currentColumn + 1].isLive() == true)
                    {
                        liveNeighbors++;
                    }
                } 

                // check if this cell is live
                if (cell.isLive() == true)
                {
                    liveNeighbors = 9;
                }

                // set LiveNeighbors property value
                cell.setLiveNeighbors(liveNeighbors);

            }
        }

        public int getSize()
        {
            return this.Size;
        }

        public void setSize(int size)
        {
            this.Size = size;
        }

        public Cell[,] getGrid()
        {
            return this.Grid;
        }

        public void setGrid(Cell[,] grid)
        {
            this.Grid = grid;
        }

        public double getDifficulty()
        {
            return this.Difficulty;
        }

        public void setDifficulty(double difficulty)
        {
            this.Difficulty = difficulty;
        }

        public void floodFill(int col, int row)
        {
            // Base case : cell Has live neighbors
            if (Grid[col, row].getLiveNeighbors() != 0)
            {

                Grid[col, row].setVisited(true);

                return;
            } 
            else
            {
                // check if cell is flagged
                if (!Grid[col, row].getFlagged())
                {
                    // If not flagged, set as visited
                    Grid[col, row].setVisited(true);
                }

                // Recursively visit all neighbors (up down left right)
                int[] xCell = { 0,  0, -1, 1, -1, 1, -1,  1 };
                int[] yCell = { 1, -1,  0, 0, -1, 1,  1, -1 };
                int i, next_x, next_y;

                for (i = 0; i < 8; i++)
                {

                    next_x = col + xCell[i];
                    next_y = row + yCell[i];

                    if( next_x < Size 
                        && next_y < Size 
                        && next_x >= 0 
                        && next_y >= 0
                        && Grid[next_x, next_y].isVisited() == false)
                    {
                        floodFill(next_x, next_y);
                    }

                }
            }
        }
    }
MoBBsKiLLz commented 2 months ago

Added classes in commit: https://github.com/scottwmaxwell/minesweeper/commit/d40e8284b3078f50274a986216715f47e667cdc6