diff --git a/.gitignore b/.gitignore index 0a84410..c2b806e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ lib .vscode bin -build \ No newline at end of file +build +Makefile \ No newline at end of file diff --git a/README.md b/README.md index 2bb3c4f..9da6f38 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,16 @@ Marking all mines with flags isn't necessary, but helps. ### Clear all non-mine cells to win! +## Controls + +Arrows to move. +Z to reveal. +X to flag. +C to chord. +R to restart. +P to pause. +Q to quit. + ## Compilation By default, the Makefile compiles in debug mode, so to compile both, use `make both`. @@ -56,12 +66,3 @@ sudo dnf install ncurses-devel Search engines are your best friend. Then rename `Makefile.unix`, press the make button, and a moment later, you got it. - -## Controls - -Arrows to move. -Z to reveal. -X to flag. -R to restart. -P to pause. -Q to quit. diff --git a/include/Board.h b/include/Board.h index 5bd664e..06e157b 100644 --- a/include/Board.h +++ b/include/Board.h @@ -20,6 +20,7 @@ public: int getMineCount() const; void regenerateBoard(); bool isGameWon() const; + std::vector getNeighborsOf(int x, int y); private: Vector2 size; diff --git a/include/Cell.h b/include/Cell.h index dc12ebb..c601b14 100644 --- a/include/Cell.h +++ b/include/Cell.h @@ -38,6 +38,7 @@ public: void toggleFlag(); Content getContent() const; void setContent(Content newContent); + Vector2 getPosition() const; private: State state = State::Hidden; diff --git a/src/Board.cpp b/src/Board.cpp index 0ee8ba7..2617077 100644 --- a/src/Board.cpp +++ b/src/Board.cpp @@ -40,21 +40,12 @@ Board::Board(int w, int h, short mines) : size(w, h), mines(mines), isFirstClick if (cell.getContent() != Cell::Content::Mine) { int count = 0; - for (int dx = -1; dx <= 1; dx++) + std::vector neighbors = getNeighborsOf(x, y); + for (const Cell &neighbor : neighbors) { - for (int dy = -1; dy <= 1; dy++) + if (neighbor.getContent() == Cell::Content::Mine) { - if (dx == 0 && dy == 0) - continue; - int nx = x + dx; - int ny = y + dy; - if (nx >= 0 && nx < w && ny >= 0 && ny < h) - { - if (cells[ny][nx].getContent() == Cell::Content::Mine) - { - count++; - } - } + count++; } } cell.setContent(static_cast(count)); @@ -63,6 +54,24 @@ Board::Board(int w, int h, short mines) : size(w, h), mines(mines), isFirstClick } } +std::vector Board::getNeighborsOf(int x, int y) +{ + std::vector neighbors; + for (int dx = -1; dx <= 1; dx++) + { + for (int dy = -1; dy <= 1; dy++) + { + if (dx == 0 && dy == 0) + continue; + int nx = x + dx; + int ny = y + dy; + if (nx >= 0 && nx < size.x && ny >= 0 && ny < size.y) + neighbors.push_back(cells[ny][nx]); + } + } + return neighbors; +} + bool Board::isGameOver() { return b_gameOver; @@ -130,22 +139,30 @@ void Board::revealEmptyCells(int x, int y) if (current.getContent() == Cell::Content::Empty) { - for (int dx = -1; dx <= 1; dx++) + // for (int dx = -1; dx <= 1; dx++) + // { + // for (int dy = -1; dy <= 1; dy++) + // { + // if (dx == 0 && dy == 0) + // continue; + // int nx = pos.x + dx; + // int ny = pos.y + dy; + // if (nx >= 0 && nx < size.x && ny >= 0 && ny < size.y) + // { + // Cell &neighbor = cells[ny][nx]; + // if (neighbor.getState() == Cell::State::Hidden) + // { + // q.push(Vector2(nx, ny)); + // } + // } + // } + // } + std::vector neighbors = getNeighborsOf(pos.x, pos.y); + for (const Cell &neighbor : neighbors) { - for (int dy = -1; dy <= 1; dy++) + if (neighbor.getState() == Cell::State::Hidden) { - if (dx == 0 && dy == 0) - continue; - int nx = pos.x + dx; - int ny = pos.y + dy; - if (nx >= 0 && nx < size.x && ny >= 0 && ny < size.y) - { - Cell &neighbor = cells[ny][nx]; - if (neighbor.getState() == Cell::State::Hidden) - { - q.push(Vector2(nx, ny)); - } - } + q.push(Vector2(neighbor.position.x, neighbor.position.y)); } } } @@ -229,21 +246,12 @@ void Board::regenerateBoard() if (cell.getContent() != Cell::Content::Mine) { int count = 0; - for (int dx = -1; dx <= 1; dx++) + std::vector neighbors = getNeighborsOf(x, y); + for (const Cell &neighbor : neighbors) { - for (int dy = -1; dy <= 1; dy++) + if (neighbor.getContent() == Cell::Content::Mine) { - if (dx == 0 && dy == 0) - continue; - int nx = x + dx; - int ny = y + dy; - if (nx >= 0 && nx < size.x && ny >= 0 && ny < size.y) - { - if (cells[ny][nx].getContent() == Cell::Content::Mine) - { - count++; - } - } + count++; } } cell.setContent(static_cast(count)); diff --git a/src/Cell.cpp b/src/Cell.cpp index 7fd0298..26a3695 100644 --- a/src/Cell.cpp +++ b/src/Cell.cpp @@ -35,4 +35,9 @@ Cell::Content Cell::getContent() const void Cell::setContent(Content newContent) { content = newContent; +} + +Vector2 Cell::getPosition() const +{ + return position; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index da2d77f..4b25f64 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -183,6 +183,16 @@ void startGame(Board &board) startPauseTime = time(NULL); } isPaused = !isPaused; + break; + case 'c': + auto neighbors = board.getNeighborsOf(cursorX, cursorY); + for (const Cell &neighbor : neighbors) + { + if (neighbor.getState() == Cell::State::Flagged) + continue; + board.revealCellAt(neighbor.getPosition().x, neighbor.getPosition().y); + } + break; } if (isPaused)