Bernardo Magri 10 месяцев назад
Родитель
Сommit
052690fede
6 измененных файлов с 67 добавлено и 89 удалено
  1. 1 1
      src/.minefield.cpp.~undo-tree~
  2. 1 1
      src/.minefield.hpp.~undo-tree~
  3. 2 2
      src/.window.cpp.~undo-tree~
  4. 18 12
      src/minefield.cpp
  5. 18 10
      src/minefield.hpp
  6. 27 63
      src/window.cpp

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
src/.minefield.cpp.~undo-tree~


Разница между файлами не показана из-за своего большого размера
+ 1 - 1
src/.minefield.hpp.~undo-tree~


Разница между файлами не показана из-за своего большого размера
+ 2 - 2
src/.window.cpp.~undo-tree~


+ 18 - 12
src/minefield.cpp

@@ -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;
-     return false;
+    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;

+ 18 - 10
src/minefield.hpp

@@ -2,6 +2,7 @@
 
 // #include <emmintrin.h>
 #include <sigc++/signal.h>
+#include <utility>
 #include <vector>
 #include <cstdlib>     
 #include <ctime>
@@ -18,22 +19,25 @@ struct Cell {
 class MineField {
 
   std::vector<std::shared_ptr<Cell>> m_cells;
-  int m_rows;
-  int m_cols;
-  int m_totalMines;
-  int m_remainingFlags;
+  int  m_rows;
+  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;
 };

+ 27 - 63
src/window.cpp

@@ -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));

Некоторые файлы не были показаны из-за большого количества измененных файлов