refactoring
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ MineField::MineField(int cols, int rows, int mines): m_rows(rows),
|
|||||||
m_cols(cols),
|
m_cols(cols),
|
||||||
m_totalMines(mines),
|
m_totalMines(mines),
|
||||||
m_remainingFlags(mines),
|
m_remainingFlags(mines),
|
||||||
|
m_openCells(0),
|
||||||
m_exploded(false) {
|
m_exploded(false) {
|
||||||
for(int i=0; i< m_cols*m_rows; i++) {
|
for(int i=0; i< m_cols*m_rows; i++) {
|
||||||
std::shared_ptr<Cell> cell = std::make_shared<Cell>();
|
std::shared_ptr<Cell> cell = std::make_shared<Cell>();
|
||||||
@@ -21,7 +22,7 @@ void MineField::initBombs(int x, int y) {
|
|||||||
|
|
||||||
while(remainingMines > 0) {
|
while(remainingMines > 0) {
|
||||||
int position = rand() % (m_cols * m_rows);
|
int position = rand() % (m_cols * m_rows);
|
||||||
if(isBomb(position % m_cols, position / m_rows) || position == startPos) {
|
if(isBomb(position % m_cols, position / m_cols) || position == startPos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_cells.at(position)->isBomb = true;
|
m_cells.at(position)->isBomb = true;
|
||||||
@@ -29,14 +30,16 @@ void MineField::initBombs(int x, int y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MineField::clearCell(int x, int y) {
|
bool MineField::openCell(int x, int y) {
|
||||||
setClearCell(x, y);
|
|
||||||
|
|
||||||
if(isBomb(x, y)) {
|
if(isBomb(x, y)) {
|
||||||
m_exploded = true;
|
m_exploded = true;
|
||||||
return false;
|
gameOverSignal.emit();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOpenCell(x, y);
|
||||||
|
|
||||||
if (bombsNearby(x, y) == 0) {
|
if (bombsNearby(x, y) == 0) {
|
||||||
openNeighboorhood(x, y);
|
openNeighboorhood(x, y);
|
||||||
}
|
}
|
||||||
@@ -63,8 +66,8 @@ void MineField::openNeighboorhood(int x, int y) {
|
|||||||
for(int i=-1; i<2; i++) {
|
for(int i=-1; i<2; i++) {
|
||||||
for(int j=-1; j<2; j++) {
|
for(int j=-1; j<2; j++) {
|
||||||
if(x+i >= 0 && x+i < m_cols && y+j >= 0 && y+j < m_rows) {
|
if(x+i >= 0 && x+i < m_cols && y+j >= 0 && y+j < m_rows) {
|
||||||
if((isCleared(x+i, y+j) == false) && (isBomb(x+i, y+j) == false)){
|
if((isOpened(x+i, y+j) == false) && (isBomb(x+i, y+j) == false)){
|
||||||
setClearCell((x+i), (y+j));
|
setOpenCell((x+i), (y+j));
|
||||||
if(bombsNearby(x+i, y+j) == 0) {
|
if(bombsNearby(x+i, y+j) == 0) {
|
||||||
openNeighboorhood(x+i, y+j);
|
openNeighboorhood(x+i, y+j);
|
||||||
}
|
}
|
||||||
@@ -74,7 +77,7 @@ void MineField::openNeighboorhood(int x, int y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MineField::isCleared(int x, int y) {
|
bool MineField::isOpened(int x, int y) {
|
||||||
return m_cells.at(x + y * m_rows)->isCleared;
|
return m_cells.at(x + y * m_rows)->isCleared;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,22 +96,25 @@ int MineField::bombsNearby(int x, int y) {
|
|||||||
return m_cells.at(x + y * m_rows)->bombsNearby;
|
return m_cells.at(x + y * m_rows)->bombsNearby;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MineField::setClearCell(int x, int y) {
|
void MineField::setOpenCell(int x, int y) {
|
||||||
m_cells.at(x + y * m_rows)->isCleared = true;
|
m_cells.at(x + y * m_rows)->isCleared = true;
|
||||||
clearCellSignal.emit(x, y);
|
openCellSignal.emit(x, y);
|
||||||
|
if((++m_openCells == (m_cols * m_rows - m_totalMines)) && (m_exploded == false)) {
|
||||||
|
gameWonSignal.emit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MineField::toggleFlag(int x, int y) {
|
bool MineField::toggleFlag(int x, int y) {
|
||||||
if(m_cells.at(x + y * m_rows)->isFlagged == true) {
|
if(m_cells.at(x + y * m_rows)->isFlagged == true) {
|
||||||
m_cells.at(x + y * m_rows)->isFlagged = false;
|
m_cells.at(x + y * m_rows)->isFlagged = false;
|
||||||
++m_remainingFlags;
|
++m_remainingFlags;
|
||||||
remainingFlagsChangedSignal.emit(m_remainingFlags);
|
remainingFlagsSignal.emit(m_remainingFlags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(m_remainingFlags > 0) {
|
else if(m_remainingFlags > 0) {
|
||||||
m_cells.at(x + y * m_rows)->isFlagged = true;
|
m_cells.at(x + y * m_rows)->isFlagged = true;
|
||||||
--m_remainingFlags;
|
--m_remainingFlags;
|
||||||
remainingFlagsChangedSignal.emit(m_remainingFlags);
|
remainingFlagsSignal.emit(m_remainingFlags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
// #include <emmintrin.h>
|
// #include <emmintrin.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
@@ -18,22 +19,25 @@ struct Cell {
|
|||||||
class MineField {
|
class MineField {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Cell>> m_cells;
|
std::vector<std::shared_ptr<Cell>> m_cells;
|
||||||
int m_rows;
|
int m_rows;
|
||||||
int m_cols;
|
int m_cols;
|
||||||
int m_totalMines;
|
int m_totalMines;
|
||||||
int m_remainingFlags;
|
int m_remainingFlags;
|
||||||
|
int m_openCells;
|
||||||
bool m_exploded;
|
bool m_exploded;
|
||||||
void computeBombsNearby(int x, int y);
|
void computeBombsNearby(int x, int y);
|
||||||
void openNeighboorhood(int x, int y);
|
void openNeighboorhood(int x, int y);
|
||||||
void setClearCell(int x, int y);
|
void setOpenCell(int x, int y);
|
||||||
|
//bint vecToPosition(int x, int y) {return (x + y * m_rows); };
|
||||||
|
//std::pair<int, int> positionToVec(int pos) {return std::make_pair(pos % m_cols, pos / m_cols); };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MineField(int cols, int rows, int mines);
|
MineField(int cols, int rows, int mines);
|
||||||
void initBombs(int x, int y);
|
void initBombs(int x, int y);
|
||||||
bool isBomb(int x, int y);
|
bool isBomb(int x, int y);
|
||||||
bool isFlagged(int x, int y);
|
bool isFlagged(int x, int y);
|
||||||
bool isCleared(int x, int y);
|
bool isOpened(int x, int y);
|
||||||
bool clearCell(int x, int y);
|
bool openCell(int x, int y);
|
||||||
int bombsNearby(int x, int y);
|
int bombsNearby(int x, int y);
|
||||||
bool isGameOver() {return m_exploded; };
|
bool isGameOver() {return m_exploded; };
|
||||||
int getCols() {return m_cols; };
|
int getCols() {return m_cols; };
|
||||||
@@ -41,6 +45,10 @@ public:
|
|||||||
bool toggleFlag(int x, int y);
|
bool toggleFlag(int x, int y);
|
||||||
int getRemainingFlags() {return m_remainingFlags; };
|
int getRemainingFlags() {return m_remainingFlags; };
|
||||||
int getTotalMines() {return m_totalMines; };
|
int getTotalMines() {return m_totalMines; };
|
||||||
sigc::signal<void(int, int)> clearCellSignal;
|
void startNewGame(int cols, int rows, int mines);
|
||||||
sigc::signal<void(int)> remainingFlagsChangedSignal;
|
|
||||||
|
sigc::signal<void(int, int)> openCellSignal;
|
||||||
|
sigc::signal<void(int)> remainingFlagsSignal;
|
||||||
|
sigc::signal<void(void)> gameWonSignal;
|
||||||
|
sigc::signal<void(void)> gameOverSignal;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,31 +12,30 @@
|
|||||||
void MainWindow::OnCellRightClick(int n_press, double n_x, double n_y, int index) {
|
void MainWindow::OnCellRightClick(int n_press, double n_x, double n_y, int index) {
|
||||||
(void)n_press, (void)n_x, (void)n_y;
|
(void)n_press, (void)n_x, (void)n_y;
|
||||||
int x = index % field.getCols();
|
int x = index % field.getCols();
|
||||||
int y = index / field.getRows();
|
int y = index / field.getCols();
|
||||||
|
int pos = x + y * field.getRows();
|
||||||
|
|
||||||
if(field.isCleared(x, y) == false) {
|
if(field.isOpened(x, y) == false) {
|
||||||
field.toggleFlag(x, y);
|
field.toggleFlag(x, y);
|
||||||
if(field.isFlagged(x, y)) {
|
if(field.isFlagged(x, y)) {
|
||||||
auto imgflag = Gtk::make_managed<Gtk::Image>();
|
auto imgflag = Gtk::make_managed<Gtk::Image>();
|
||||||
imgflag->set(m_pixbufFlag);
|
imgflag->set(m_pixbufFlag);
|
||||||
buttons.at(x + y * field.getRows())->set_child(*imgflag);
|
buttons.at(pos)->set_child(*imgflag);
|
||||||
buttons.at(x + y * field.getRows())->set_active(true);
|
buttons.at(pos)->set_active(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buttons.at(x + y * field.getRows())->unset_child();
|
buttons.at(pos)->unset_child();
|
||||||
buttons.at(x+ y * field.getRows())->queue_draw();
|
buttons.at(pos)->queue_draw();
|
||||||
buttons.at(x + y * field.getRows())->set_active(false);
|
buttons.at(pos)->set_active(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field.getRemainingFlags());
|
|
||||||
// flagLabel.set_label(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateFlagsLabel(int flags) {
|
void MainWindow::updateFlagsLabel(int flags) {
|
||||||
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", flags);
|
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", flags);
|
||||||
flagLabel.set_label(msg);
|
flagLabel.set_label(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void MainWindow::OnNewButtonClick() {
|
// void MainWindow::OnNewButtonClick() {
|
||||||
// newGame = true;
|
// newGame = true;
|
||||||
// gameOver = false;
|
// gameOver = false;
|
||||||
@@ -47,7 +46,7 @@ void MainWindow::updateFlagsLabel(int flags) {
|
|||||||
// button->set_label("");
|
// button->set_label("");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// field->remainingFlags = MINES;
|
// //field->remainingFlags = MINES;
|
||||||
// Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field->remainingFlags);
|
// Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field->remainingFlags);
|
||||||
// flagLabel.set_label(msg);
|
// flagLabel.set_label(msg);
|
||||||
|
|
||||||
@@ -57,41 +56,6 @@ void MainWindow::updateFlagsLabel(int flags) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// void MainWindow::OpenNearCells(int index, std::set<int> &visited) {
|
|
||||||
// int cols = field->Cols();
|
|
||||||
// int x = index % cols;
|
|
||||||
// int y = index / cols;
|
|
||||||
|
|
||||||
// if (visited.count(index)) return;
|
|
||||||
|
|
||||||
// Cell* cell = field->GetCell(x, y);
|
|
||||||
// if (!cell || cell->bombsNearby > 0 || cell->type == CellType::Bomb) return;
|
|
||||||
|
|
||||||
// visited.insert(index);
|
|
||||||
// buttons[index]->set_active(true);
|
|
||||||
|
|
||||||
// for (int i = -1; i <= 1; i++) {
|
|
||||||
// for (int j = -1; j <= 1; j++) {
|
|
||||||
// if (i == 0 && j == 0) continue; // Skip the current cell
|
|
||||||
|
|
||||||
// int nx = x + i;
|
|
||||||
// int ny = y + j;
|
|
||||||
// int newIndex = ny * cols + nx;
|
|
||||||
// Cell* neighborCell = field->GetCell(nx, ny);
|
|
||||||
|
|
||||||
// // Bounds check before recursive call
|
|
||||||
// if (nx >= 0 && nx < cols && ny >= 0 && ny < cols) {
|
|
||||||
// if (visited.count(newIndex) == 0) {
|
|
||||||
// OpenNearCells(newIndex, visited);
|
|
||||||
// }
|
|
||||||
// if (neighborCell && !buttons[newIndex]->get_active() && !neighborCell->isFlag) {
|
|
||||||
// OpenNearCells(newIndex, visited);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::OnCellClick(int x, int y) {
|
void MainWindow::OnCellClick(int x, int y) {
|
||||||
@@ -107,7 +71,7 @@ void MainWindow::OnCellClick(int x, int y) {
|
|||||||
openBombs();
|
openBombs();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
field.clearCell(x, y);
|
field.openCell(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +79,7 @@ void MainWindow::OnCellClick(int x, int y) {
|
|||||||
void MainWindow::openBombs() {
|
void MainWindow::openBombs() {
|
||||||
for(int i=0; i < field.getCols() * field.getRows(); i++) {
|
for(int i=0; i < field.getCols() * field.getRows(); i++) {
|
||||||
int x = i % field.getCols();
|
int x = i % field.getCols();
|
||||||
int y = i / field.getRows();
|
int y = i / field.getCols();
|
||||||
|
|
||||||
buttons.at(i)->set_sensitive(false);
|
buttons.at(i)->set_sensitive(false);
|
||||||
|
|
||||||
@@ -136,38 +100,39 @@ void MainWindow::openBombs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateCell(int x, int y) {
|
void MainWindow::updateCell(int x, int y) {
|
||||||
if(field.isCleared(x, y)) {
|
int pos = x + y * field.getRows();
|
||||||
|
if(field.isOpened(x, y)) {
|
||||||
if (field.bombsNearby(x, y) > 0) {
|
if (field.bombsNearby(x, y) > 0) {
|
||||||
switch(field.bombsNearby(x, y)) {
|
switch(field.bombsNearby(x, y)) {
|
||||||
case 1:
|
case 1:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-1");
|
buttons.at(pos)->get_style_context()->add_class("label-1");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-2");
|
buttons.at(pos)->get_style_context()->add_class("label-2");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-3");
|
buttons.at(pos)->get_style_context()->add_class("label-3");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-4");
|
buttons.at(pos)->get_style_context()->add_class("label-4");
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-5");
|
buttons.at(pos)->get_style_context()->add_class("label-5");
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-6");
|
buttons.at(pos)->get_style_context()->add_class("label-6");
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-7");
|
buttons.at(pos)->get_style_context()->add_class("label-7");
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-8");
|
buttons.at(pos)->get_style_context()->add_class("label-8");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buttons.at(x + y * field.getRows())->set_label(Glib::ustring::format(field.bombsNearby(x, y)));
|
buttons.at(pos)->set_label(Glib::ustring::format(field.bombsNearby(x, y)));
|
||||||
}
|
}
|
||||||
buttons.at(x + y * field.getRows())->set_active(true);
|
buttons.at(pos)->set_active(true);
|
||||||
buttons.at(x + y * field.getRows())->set_sensitive(false);
|
buttons.at(pos)->set_sensitive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// void MainWindow::ShowGameWonAnimation() {
|
// void MainWindow::ShowGameWonAnimation() {
|
||||||
@@ -299,9 +264,8 @@ MainWindow::MainWindow()
|
|||||||
grid.attach(*button, x, y);
|
grid.attach(*button, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
field.clearCellSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateCell)));
|
field.openCellSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateCell)));
|
||||||
field.remainingFlagsChangedSignal.connect(sigc::bind(sigc::mem_fun(*this, \
|
field.remainingFlagsSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateFlagsLabel)));
|
||||||
&MainWindow::updateFlagsLabel)));
|
|
||||||
//newGameButton.set_label("New");
|
//newGameButton.set_label("New");
|
||||||
//newGameButton.add_css_class("suggested-action");
|
//newGameButton.add_css_class("suggested-action");
|
||||||
//newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
//newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
||||||
|
|||||||
Reference in New Issue
Block a user