[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/R-Besson/minesweeper/main/src/sweeper.cpp [Back]  [Original]

#include "sweeper.h"

const int xDir[8] {0,  1,  0, -1,  1,  1, -1, -1};
const int yDir[8] {1,  0, -1,  0,  1, -1,  1, -1};

// Initializes/Resets the Grid
void Game::initialize(int GRID_WIDTH, int GRID_HEIGHT, int NB_MINES) {
    grid->clear();

    this->GRID_WIDTH = GRID_WIDTH;
    this->GRID_HEIGHT = GRID_HEIGHT;
    this->NB_MINES = NB_MINES;
    
    for (int x = 0; x < GRID_WIDTH; x++)
    {
        grid->push_back(new CellList);

        for (int y = 0; y < GRID_HEIGHT; y++)
        {
            Cell* cell = new Cell;

            cell->x = x;
            cell->y = y;

            grid->at(x)->push_back(cell);
        }
    }

    state = GameState::Initiated;
}

// Add Mines + Calulcate Numbers adjacent to Mines, to the Grid
void Game::populateGrid(Cell* &exception)
{
	// Generate mines
	int generated = 0;
	while (generated != NB_MINES)
	{
		int x = rand() % GRID_WIDTH;
		int y = rand() % GRID_HEIGHT;

        Cell* cell = grid->at(x)->at(y);

		if (cell->isMine) continue;

        if (
            abs(exception->x - cell->x) y - cell->y) isMine = true;
		generated++;
	}
    FLAGS_LEFT = generated;

	// Generate adjacent numbered cells
	// NSWE + Diagonals
	for (int x = 0; x < GRID_WIDTH; x++)
	{
		for (int y = 0; y < GRID_HEIGHT; y++)
		{
            Cell* cell = grid->at(x)->at(y);

			if (!(cell->isMine)) continue;

            CellList* adjs = getAdjacentCells(cell);

            for(auto it = adjs->begin(); it != adjs->end(); it++)
                if (!(*it)->isMine) (*it)->num++;
		}
	}
}

// Gets 8 cells surrounding the root cell
CellList* Game::getAdjacentCells(Cell* &root)
{
    CellList* adjs = new CellList;

    // Up, Down, Left, Right, + Diagonals -> 8 Squares total
    for (int d = 0; d < 8; d++)
    {
        int nX = root->x + xDir[d];
        int nY = root->y + yDir[d];

        if (
            nX >= GRID_WIDTH ||
            nX < 0 ||
            nY >= GRID_HEIGHT ||
            nY < 0
        ) continue;

        adjs->push_back(grid->at(nX)->at(nY));
    }

    return adjs;
}

// Flags a cell (False flag is cell isnt a Mine, else is it Valid (Not known to user))
void Game::flagCell(Cell* &cell)
{
    if (cell->isRevealed) return;

    cell->isFlagged = !(cell->isFlagged);
    
    if (cell->isFlagged) FLAGS_LEFT--;
    else FLAGS_LEFT++;
}

// Recursively reveals an area that is purely mine-free
void Game::revealCell(Cell* &cell)
{
    if (!cell->isRevealed && !cell->isFlagged && state == GameState::Initiated) {
        cell->isRevealed = true;

        // End the game if the Cell is a mine
        if (cell->isMine) {
            state = GameState::Lost;
        } else if (cell->num == 0) {
            // If the cell has 0 adjacent mines, we need to recurse to clear out all adjacent 0 cells
            CellList* adjs = getAdjacentCells(cell);

            for(auto it = adjs->begin(); it != adjs->end(); it++)
                if (!(*it)->isMine) revealCell(*it);
        }
    }
}

// Reveals all cells (End game)
void Game::revealAll()
{
    for (int x = 0; x < GRID_WIDTH; x++)
	{
		for (int y = 0; y < GRID_HEIGHT; y++)
		{
            grid->at(x)->at(y)->isRevealed = true;
        }
    }
}

// Checks if user has successfully guessed all Mines
bool Game::checkWin()
{
    if (FLAGS_LEFT != 0) return false;

    for (int x = 0; x < GRID_WIDTH; x++)
	{
		for (int y = 0; y < GRID_HEIGHT; y++)
		{
            Cell* cell = grid->at(x)->at(y);

            if (cell->isMine && !cell->isFlagged) return false;
            if (!cell->isRevealed && !cell->isMine) return false;
        }
    }
    return true;
}

// ...
void Game::printGrid()
{
    for (int y = 0; y < GRID_WIDTH; y++)
	{
        std::cout at(x)->at(y);

            if (cell->isMine) std::cout 

Web Proxy Viewer  |  New URL  |  Original Page