cleaning up
This commit is contained in:
+82
-90
@@ -1,166 +1,158 @@
|
||||
#include "minefield.hpp"
|
||||
#include <iostream>
|
||||
|
||||
MineField::MineField(int cols, int rows, int mines): m_rows(rows),
|
||||
m_cols(cols),
|
||||
m_totalMines(mines),
|
||||
m_remainingFlags(mines),
|
||||
m_openCells(0),
|
||||
m_exploded(false) {
|
||||
for(int i=0; i< m_cols*m_rows; i++) {
|
||||
MineField::MineField(int cols, int rows, int mines) : m_rows(rows),
|
||||
m_cols(cols),
|
||||
m_totalMines(mines),
|
||||
m_remainingFlags(mines),
|
||||
m_openCells(0),
|
||||
m_gameOver(false)
|
||||
{
|
||||
for (int i = 0; i < m_cols * m_rows; i++)
|
||||
{
|
||||
std::shared_ptr<Cell> cell = std::make_shared<Cell>();
|
||||
m_cells.push_back(cell);
|
||||
}
|
||||
}
|
||||
|
||||
MineField::~MineField() {
|
||||
if(m_timerRunning) {
|
||||
stopTimer();
|
||||
}
|
||||
MineField::~MineField()
|
||||
{
|
||||
m_cells.clear();
|
||||
}
|
||||
|
||||
void MineField::timerTick() {
|
||||
|
||||
auto start = std::chrono::system_clock::now();
|
||||
|
||||
while(m_timerRunning) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
auto now = std::chrono::system_clock::now();
|
||||
const auto duration = now - start;
|
||||
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
|
||||
m_time += ms.count();
|
||||
timerSignal.emit(m_time);
|
||||
start = std::chrono::system_clock::now();
|
||||
}
|
||||
}
|
||||
|
||||
void MineField::startTimer() {
|
||||
m_time = 0;
|
||||
m_timerRunning = true;
|
||||
m_timerThread = std::thread(&MineField::timerTick, this);
|
||||
}
|
||||
|
||||
void MineField::stopTimer() {
|
||||
m_timerRunning = false;
|
||||
|
||||
if(m_timerThread.joinable()) {
|
||||
m_timerThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
void MineField::initBombs(int x, int y) {
|
||||
void MineField::initBombs(int x, int y)
|
||||
{
|
||||
|
||||
int remainingMines = m_totalMines;
|
||||
int startPos = x + y * m_rows;
|
||||
|
||||
srand(time(NULL)); //initialize rand()
|
||||
srand(time(NULL)); // initialize rand()
|
||||
|
||||
while(remainingMines > 0) {
|
||||
while (remainingMines > 0)
|
||||
{
|
||||
int position = rand() % (m_cols * m_rows);
|
||||
if(isBomb(position % m_cols, position / m_cols) || position == startPos) {
|
||||
if (isBomb(position % m_cols, position / m_cols) || position == startPos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
m_cells.at(position)->isBomb = true;
|
||||
--remainingMines;
|
||||
}
|
||||
|
||||
startTimer();
|
||||
|
||||
//init the timer to zero and start the timer thread
|
||||
//timerThread.detach(); //not sure if this is okay (better to call join() when I set the condition to stop the thread)
|
||||
}
|
||||
|
||||
bool MineField::openCell(int x, int y) {
|
||||
if(isBomb(x, y)) {
|
||||
m_exploded = true;
|
||||
bool MineField::openCell(int x, int y)
|
||||
{
|
||||
if (isBomb(x, y))
|
||||
{
|
||||
m_gameOver = true;
|
||||
gameOverSignal.emit();
|
||||
stopTimer();
|
||||
// stopTimer();
|
||||
return false;
|
||||
}
|
||||
|
||||
setOpenCell(x, y);
|
||||
|
||||
if (bombsNearby(x, y) == 0) {
|
||||
if (bombsNearby(x, y) == 0)
|
||||
{
|
||||
openNeighboorhood(x, y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MineField::computeBombsNearby(int x, int y) {
|
||||
int total = 0;
|
||||
//compute bombs in neighboorhood
|
||||
for(int i=-1; i<2; i++) {
|
||||
for(int j=-1; j<2; j++) {
|
||||
if(x+i >= 0 && x+i < m_cols && y+j >= 0 && y+j < m_rows) {
|
||||
if(isBomb(x+i, y+j)){
|
||||
++total;
|
||||
}
|
||||
void MineField::computeBombsNearby(int x, int y)
|
||||
{
|
||||
int total = 0;
|
||||
// compute bombs in neighboorhood
|
||||
for (int i = -1; i < 2; i++)
|
||||
{
|
||||
for (int j = -1; j < 2; j++)
|
||||
{
|
||||
if (x + i >= 0 && x + i < m_cols && y + j >= 0 && y + j < m_rows)
|
||||
{
|
||||
if (isBomb(x + i, y + j))
|
||||
{
|
||||
++total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cells.at(x + y * m_rows)->bombsNearby = total;
|
||||
}
|
||||
|
||||
void MineField::openNeighboorhood(int x, int y) {
|
||||
//compute bombs in neighboorhood
|
||||
for(int i=-1; i<2; i++) {
|
||||
for(int j=-1; j<2; j++) {
|
||||
if(x+i >= 0 && x+i < m_cols && y+j >= 0 && y+j < m_rows) {
|
||||
if((isOpened(x+i, y+j) == false) && (isBomb(x+i, y+j) == false)){
|
||||
setOpenCell((x+i), (y+j));
|
||||
if(bombsNearby(x+i, y+j) == 0) {
|
||||
openNeighboorhood(x+i, y+j);
|
||||
}
|
||||
}
|
||||
void MineField::openNeighboorhood(int x, int y)
|
||||
{
|
||||
// compute bombs in neighboorhood
|
||||
for (int i = -1; i < 2; i++)
|
||||
{
|
||||
for (int j = -1; j < 2; j++)
|
||||
{
|
||||
if (x + i >= 0 && x + i < m_cols && y + j >= 0 && y + j < m_rows)
|
||||
{
|
||||
if ((isOpened(x + i, y + j) == false) && (isBomb(x + i, y + j) == false))
|
||||
{
|
||||
setOpenCell((x + i), (y + j));
|
||||
if (bombsNearby(x + i, y + j) == 0)
|
||||
{
|
||||
openNeighboorhood(x + i, y + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MineField::isOpened(int x, int y) {
|
||||
|
||||
bool MineField::isOpened(int x, int y)
|
||||
{
|
||||
return m_cells.at(x + y * m_rows)->isCleared;
|
||||
}
|
||||
|
||||
bool MineField::isFlagged(int x, int y) {
|
||||
bool MineField::isFlagged(int x, int y)
|
||||
{
|
||||
return m_cells.at(x + y * m_rows)->isFlagged;
|
||||
}
|
||||
|
||||
bool MineField::isBomb(int x, int y) {
|
||||
bool MineField::isBomb(int x, int y)
|
||||
{
|
||||
return m_cells.at(x + y * m_rows)->isBomb;
|
||||
}
|
||||
|
||||
int MineField::bombsNearby(int x, int y) {
|
||||
if(m_cells.at(x + y * m_rows)->bombsNearby == -1) {
|
||||
int MineField::bombsNearby(int x, int y)
|
||||
{
|
||||
if (m_cells.at(x + y * m_rows)->bombsNearby == -1)
|
||||
{
|
||||
computeBombsNearby(x, y);
|
||||
}
|
||||
}
|
||||
return m_cells.at(x + y * m_rows)->bombsNearby;
|
||||
}
|
||||
|
||||
void MineField::setOpenCell(int x, int y) {
|
||||
void MineField::setOpenCell(int x, int y)
|
||||
{
|
||||
m_cells.at(x + y * m_rows)->isCleared = true;
|
||||
openCellSignal.emit(x, y);
|
||||
++m_openCells;
|
||||
checkGameWon();
|
||||
}
|
||||
|
||||
void MineField::checkGameWon() {
|
||||
if((m_openCells == (m_cols * m_rows - m_totalMines)) && (m_exploded == false) && (m_remainingFlags == 0)) {
|
||||
void MineField::checkGameWon()
|
||||
{
|
||||
if ((m_openCells == (m_cols * m_rows - m_totalMines)) && (m_gameOver == false) && (m_remainingFlags == 0))
|
||||
{
|
||||
m_gameWon = true;
|
||||
stopTimer();
|
||||
gameWonSignal.emit();
|
||||
}
|
||||
std::cout << "Open cells: " << m_openCells << "\n" << "Remaining Flags: " << m_remainingFlags << "\n";
|
||||
|
||||
}
|
||||
|
||||
bool MineField::toggleFlag(int x, int y) {
|
||||
if(m_cells.at(x + y * m_rows)->isFlagged == true) {
|
||||
bool MineField::toggleFlag(int x, int y)
|
||||
{
|
||||
if (m_cells.at(x + y * m_rows)->isFlagged == true)
|
||||
{
|
||||
m_cells.at(x + y * m_rows)->isFlagged = false;
|
||||
++m_remainingFlags;
|
||||
remainingFlagsSignal.emit(m_remainingFlags);
|
||||
return true;
|
||||
}
|
||||
else if(m_remainingFlags > 0) {
|
||||
else if (m_remainingFlags > 0)
|
||||
{
|
||||
m_cells.at(x + y * m_rows)->isFlagged = true;
|
||||
--m_remainingFlags;
|
||||
remainingFlagsSignal.emit(m_remainingFlags);
|
||||
|
||||
Reference in New Issue
Block a user