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
+136
-3
File diff suppressed because one or more lines are too long
+18
-12
@@ -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;
|
||||||
|
|||||||
+18
-10
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
+27
-63
@@ -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