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_totalMines(mines),
|
||||
m_remainingFlags(mines),
|
||||
m_openCells(0),
|
||||
m_exploded(false) {
|
||||
for(int i=0; i< m_cols*m_rows; i++) {
|
||||
std::shared_ptr<Cell> cell = std::make_shared<Cell>();
|
||||
@@ -21,7 +22,7 @@ void MineField::initBombs(int x, int y) {
|
||||
|
||||
while(remainingMines > 0) {
|
||||
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;
|
||||
}
|
||||
m_cells.at(position)->isBomb = true;
|
||||
@@ -29,14 +30,16 @@ void MineField::initBombs(int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
bool MineField::clearCell(int x, int y) {
|
||||
setClearCell(x, y);
|
||||
bool MineField::openCell(int x, int y) {
|
||||
|
||||
if(isBomb(x, y)) {
|
||||
m_exploded = true;
|
||||
gameOverSignal.emit();
|
||||
return false;
|
||||
}
|
||||
|
||||
setOpenCell(x, y);
|
||||
|
||||
if (bombsNearby(x, y) == 0) {
|
||||
openNeighboorhood(x, y);
|
||||
}
|
||||
@@ -63,8 +66,8 @@ void MineField::openNeighboorhood(int x, int y) {
|
||||
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((isCleared(x+i, y+j) == false) && (isBomb(x+i, y+j) == false)){
|
||||
setClearCell((x+i), (y+j));
|
||||
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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -93,22 +96,25 @@ int MineField::bombsNearby(int x, int y) {
|
||||
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;
|
||||
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) {
|
||||
if(m_cells.at(x + y * m_rows)->isFlagged == true) {
|
||||
m_cells.at(x + y * m_rows)->isFlagged = false;
|
||||
++m_remainingFlags;
|
||||
remainingFlagsChangedSignal.emit(m_remainingFlags);
|
||||
remainingFlagsSignal.emit(m_remainingFlags);
|
||||
return true;
|
||||
}
|
||||
else if(m_remainingFlags > 0) {
|
||||
m_cells.at(x + y * m_rows)->isFlagged = true;
|
||||
--m_remainingFlags;
|
||||
remainingFlagsChangedSignal.emit(m_remainingFlags);
|
||||
remainingFlagsSignal.emit(m_remainingFlags);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// #include <emmintrin.h>
|
||||
#include <sigc++/signal.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
@@ -22,18 +23,21 @@ class MineField {
|
||||
int m_cols;
|
||||
int m_totalMines;
|
||||
int m_remainingFlags;
|
||||
int m_openCells;
|
||||
bool m_exploded;
|
||||
void computeBombsNearby(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:
|
||||
MineField(int cols, int rows, int mines);
|
||||
void initBombs(int x, int y);
|
||||
bool isBomb(int x, int y);
|
||||
bool isFlagged(int x, int y);
|
||||
bool isCleared(int x, int y);
|
||||
bool clearCell(int x, int y);
|
||||
bool isOpened(int x, int y);
|
||||
bool openCell(int x, int y);
|
||||
int bombsNearby(int x, int y);
|
||||
bool isGameOver() {return m_exploded; };
|
||||
int getCols() {return m_cols; };
|
||||
@@ -41,6 +45,10 @@ public:
|
||||
bool toggleFlag(int x, int y);
|
||||
int getRemainingFlags() {return m_remainingFlags; };
|
||||
int getTotalMines() {return m_totalMines; };
|
||||
sigc::signal<void(int, int)> clearCellSignal;
|
||||
sigc::signal<void(int)> remainingFlagsChangedSignal;
|
||||
void startNewGame(int cols, int rows, int mines);
|
||||
|
||||
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)n_press, (void)n_x, (void)n_y;
|
||||
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);
|
||||
if(field.isFlagged(x, y)) {
|
||||
auto imgflag = Gtk::make_managed<Gtk::Image>();
|
||||
imgflag->set(m_pixbufFlag);
|
||||
buttons.at(x + y * field.getRows())->set_child(*imgflag);
|
||||
buttons.at(x + y * field.getRows())->set_active(true);
|
||||
buttons.at(pos)->set_child(*imgflag);
|
||||
buttons.at(pos)->set_active(true);
|
||||
}
|
||||
else {
|
||||
buttons.at(x + y * field.getRows())->unset_child();
|
||||
buttons.at(x+ y * field.getRows())->queue_draw();
|
||||
buttons.at(x + y * field.getRows())->set_active(false);
|
||||
buttons.at(pos)->unset_child();
|
||||
buttons.at(pos)->queue_draw();
|
||||
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) {
|
||||
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", flags);
|
||||
flagLabel.set_label(msg);
|
||||
}
|
||||
|
||||
// void MainWindow::OnNewButtonClick() {
|
||||
// newGame = true;
|
||||
// gameOver = false;
|
||||
@@ -47,7 +46,7 @@ void MainWindow::updateFlagsLabel(int flags) {
|
||||
// button->set_label("");
|
||||
// }
|
||||
|
||||
// field->remainingFlags = MINES;
|
||||
// //field->remainingFlags = MINES;
|
||||
// Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field->remainingFlags);
|
||||
// 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) {
|
||||
@@ -107,7 +71,7 @@ void MainWindow::OnCellClick(int x, int y) {
|
||||
openBombs();
|
||||
}
|
||||
else {
|
||||
field.clearCell(x, y);
|
||||
field.openCell(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +79,7 @@ void MainWindow::OnCellClick(int x, int y) {
|
||||
void MainWindow::openBombs() {
|
||||
for(int i=0; i < field.getCols() * field.getRows(); i++) {
|
||||
int x = i % field.getCols();
|
||||
int y = i / field.getRows();
|
||||
int y = i / field.getCols();
|
||||
|
||||
buttons.at(i)->set_sensitive(false);
|
||||
|
||||
@@ -136,38 +100,39 @@ void MainWindow::openBombs() {
|
||||
}
|
||||
|
||||
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) {
|
||||
switch(field.bombsNearby(x, y)) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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(x + y * field.getRows())->set_sensitive(false);
|
||||
buttons.at(pos)->set_active(true);
|
||||
buttons.at(pos)->set_sensitive(false);
|
||||
}
|
||||
}
|
||||
// void MainWindow::ShowGameWonAnimation() {
|
||||
@@ -299,9 +264,8 @@ MainWindow::MainWindow()
|
||||
grid.attach(*button, x, y);
|
||||
}
|
||||
|
||||
field.clearCellSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateCell)));
|
||||
field.remainingFlagsChangedSignal.connect(sigc::bind(sigc::mem_fun(*this, \
|
||||
&MainWindow::updateFlagsLabel)));
|
||||
field.openCellSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateCell)));
|
||||
field.remainingFlagsSignal.connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::updateFlagsLabel)));
|
||||
//newGameButton.set_label("New");
|
||||
//newGameButton.add_css_class("suggested-action");
|
||||
//newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
||||
|
||||
Reference in New Issue
Block a user