Initial commit
This commit is contained in:
115
src/MineField.cpp
Normal file
115
src/MineField.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include "MineField.hpp"
|
||||
|
||||
MineField::MineField(int cols, int rows, int mines): m_rows(rows),
|
||||
m_cols(cols),
|
||||
m_totalMines(mines),
|
||||
m_remainingFlags(mines),
|
||||
m_exploded(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MineField::initBombs(int x, int y) {
|
||||
|
||||
int remainingMines = m_totalMines;
|
||||
int startPos = x + y * m_rows;
|
||||
|
||||
srand(time(NULL)); //initialize rand()
|
||||
|
||||
while(remainingMines > 0) {
|
||||
int position = rand() % (m_cols * m_rows);
|
||||
if(isBomb(position % m_cols, position / m_rows) || position == startPos) {
|
||||
continue;
|
||||
}
|
||||
m_cells.at(position)->isBomb = true;
|
||||
--remainingMines;
|
||||
}
|
||||
}
|
||||
|
||||
bool MineField::clearCell(int x, int y) {
|
||||
setClearCell(x, y);
|
||||
|
||||
if(isBomb(x, y)) {
|
||||
m_exploded = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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((isCleared(x+i, y+j) == false) && (isBomb(x+i, y+j) == false)){
|
||||
setClearCell((x+i), (y+j));
|
||||
if(bombsNearby(x+i, y+j) == 0) {
|
||||
openNeighboorhood(x+i, y+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MineField::isCleared(int x, int y) {
|
||||
return m_cells.at(x + y * m_rows)->isCleared;
|
||||
}
|
||||
|
||||
bool MineField::isFlagged(int x, int y) {
|
||||
return m_cells.at(x + y * m_rows)->isFlagged;
|
||||
}
|
||||
|
||||
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) {
|
||||
computeBombsNearby(x, y);
|
||||
}
|
||||
return m_cells.at(x + y * m_rows)->bombsNearby;
|
||||
}
|
||||
|
||||
void MineField::setClearCell(int x, int y) {
|
||||
m_cells.at(x + y * m_rows)->isCleared = true;
|
||||
clearCellSignal.emit(x, y);
|
||||
}
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
else if(m_remainingFlags > 0) {
|
||||
m_cells.at(x + y * m_rows)->isFlagged = true;
|
||||
--m_remainingFlags;
|
||||
remainingFlagsChangedSignal.emit(m_remainingFlags);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
46
src/MineField.hpp
Normal file
46
src/MineField.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
//#include <emmintrin.h>
|
||||
#include <sigc++/signal.h>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
|
||||
struct Cell {
|
||||
bool isFlagged;
|
||||
bool isCleared;
|
||||
bool isBomb;
|
||||
int bombsNearby;
|
||||
Cell(): isFlagged(false), isCleared(false), isBomb(false), bombsNearby(-1) {};
|
||||
};
|
||||
|
||||
class MineField {
|
||||
|
||||
std::vector<std::shared_ptr<Cell>> m_cells;
|
||||
int m_rows;
|
||||
int m_cols;
|
||||
int m_totalMines;
|
||||
int m_remainingFlags;
|
||||
bool m_exploded;
|
||||
void computeBombsNearby(int x, int y);
|
||||
void openNeighboorhood(int x, int y);
|
||||
void setClearCell(int x, int y);
|
||||
|
||||
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);
|
||||
int bombsNearby(int x, int y);
|
||||
bool isGameOver() {return m_exploded; };
|
||||
int getCols() {return m_cols; };
|
||||
int getRows() {return m_rows; };
|
||||
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;
|
||||
};
|
||||
339
src/Window.cpp
Normal file
339
src/Window.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
#include "window.hpp"
|
||||
#include "gdkmm/pixbuf.h"
|
||||
#include "gtkmm/cssprovider.h"
|
||||
#include "gtkmm/image.h"
|
||||
#include "sigc++/adaptors/bind.h"
|
||||
#include "sigc++/functors/mem_fun.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
//}
|
||||
// void MainWindow::ApplyStyles() {
|
||||
// // Load and apply the CSS file
|
||||
// auto css_provider = Gtk::CssProvider::create();
|
||||
// css_provider->load_from_path("style.css");
|
||||
// Gtk::StyleContext::add_provider_for_display(Gdk::Display::get_default(), css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
// }
|
||||
|
||||
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();
|
||||
|
||||
if(field.isCleared(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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// for (auto &button : buttons) {
|
||||
// button->set_active(false);
|
||||
// button->set_sensitive(true);
|
||||
// button->set_label("");
|
||||
// }
|
||||
|
||||
// field->remainingFlags = MINES;
|
||||
// Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field->remainingFlags);
|
||||
// flagLabel.set_label(msg);
|
||||
|
||||
// if (clockConn.connected()) clockConn.disconnect();
|
||||
// elapsedTime = 0;
|
||||
// clockConn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &MainWindow::UpdateClockLabel), 100);
|
||||
// }
|
||||
|
||||
|
||||
// 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) {
|
||||
if (newGame) {
|
||||
field.initBombs(x, y);
|
||||
newGame = false;
|
||||
}
|
||||
|
||||
if(field.isFlagged(x, y)) {
|
||||
buttons.at(x + y * field.getRows())->set_active(true);
|
||||
}
|
||||
else if(field.isBomb(x, y)) {
|
||||
openBombs();
|
||||
}
|
||||
else {
|
||||
field.clearCell(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::openBombs() {
|
||||
for(int i=0; i < field.getCols() * field.getRows(); i++) {
|
||||
int x = i % field.getCols();
|
||||
int y = i / field.getRows();
|
||||
|
||||
buttons.at(i)->set_sensitive(false);
|
||||
|
||||
if(field.isBomb(x, y)) {
|
||||
if(field.isFlagged(x, y)) {
|
||||
auto imgFlagBomb = std::make_shared<Gtk::Image>();
|
||||
imgFlagBomb->set(m_pixbufFlagBomb);
|
||||
buttons.at(i)->set_child(*imgFlagBomb);
|
||||
}
|
||||
else {
|
||||
auto imgBomb = std::make_shared<Gtk::Image>();
|
||||
imgBomb->set(m_pixbufBomb);
|
||||
buttons.at(i)->set_child(*imgBomb);
|
||||
}
|
||||
buttons.at(i)->set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateCell(int x, int y) {
|
||||
if(field.isCleared(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");
|
||||
break;
|
||||
case 2:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-2");
|
||||
break;
|
||||
case 3:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-3");
|
||||
break;
|
||||
case 4:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-4");
|
||||
break;
|
||||
case 5:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-5");
|
||||
break;
|
||||
case 6:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-6");
|
||||
break;
|
||||
case 7:
|
||||
buttons.at(x + y * field.getRows())->get_style_context()->add_class("label-7");
|
||||
break;
|
||||
case 8:
|
||||
buttons.at(x + y * field.getRows())->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(x + y * field.getRows())->set_active(true);
|
||||
buttons.at(x + y * field.getRows())->set_sensitive(false);
|
||||
}
|
||||
}
|
||||
// void MainWindow::ShowGameWonAnimation() {
|
||||
// // Limit the number of confetti images to 10
|
||||
// int confettiCount = 10;
|
||||
// for (int i = 0; i < confettiCount; ++i) {
|
||||
// Glib::signal_timeout().connect_once([this]() {
|
||||
// auto confetti = Gtk::make_managed<Gtk::Image>();
|
||||
// confetti->set_from_resource("/mineSweeper/confetti");
|
||||
// // Randomize position on the grid or overlay.
|
||||
// grid->attach(*confetti, rand() % COLS, rand() % COLS);
|
||||
// grid->queue_draw();
|
||||
// }, i * 100); // Add confetti with a delay of 100ms each
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// bool MainWindow::AllCellsOpened()
|
||||
// {
|
||||
// for(int i=0; i<COLS * COLS; i++) {
|
||||
// if (!buttons[i]->get_active())
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
// bool MainWindow::UpdateClockLabel()
|
||||
// {
|
||||
// if(gameOver) return false;
|
||||
|
||||
// elapsedTime++;
|
||||
|
||||
// int deciseconds = elapsedTime % 10;
|
||||
// int seconds = (elapsedTime / 10) % 60;
|
||||
// int minutes = (elapsedTime /600) % 60;
|
||||
|
||||
// Glib::ustring msg = Glib::ustring::compose("Elapsed time: %1:%2.%3", \
|
||||
// Glib::ustring::format(std::setfill(L'0'), std::setw(2), minutes), \
|
||||
// Glib::ustring::format(std::setfill(L'0'), std::setw(2), seconds), \
|
||||
// Glib::ustring::format(std::setfill(L'0'), std::setw(1), deciseconds));
|
||||
// clockLabel.set_label(msg);
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
// ApplyStyles(); // Load the CSS file
|
||||
elapsedTime = 0;
|
||||
newGame = true;
|
||||
set_title("MineSweeper");
|
||||
set_default_size(400, 400);
|
||||
set_resizable(false);
|
||||
|
||||
boxV = Gtk::Box(Gtk::Orientation::VERTICAL);
|
||||
boxH = Gtk::Box(Gtk::Orientation::HORIZONTAL);
|
||||
|
||||
boxH.set_hexpand(true);
|
||||
|
||||
boxV.append(boxH);
|
||||
boxH.set_expand(true);
|
||||
|
||||
Gtk::Label labelMines;
|
||||
labelMines.set_margin_top(12);
|
||||
labelMines.set_margin_start(12);
|
||||
labelMines.set_label(Glib::ustring::compose("Total mines: %1", field.getTotalMines()));
|
||||
//labelMines.set_hexpand(true);
|
||||
|
||||
Glib::ustring msg = Glib::ustring::compose("Remaining flags: %1", field.getRemainingFlags());
|
||||
flagLabel = Gtk::Label(msg);
|
||||
flagLabel.set_margin_top(12);
|
||||
flagLabel.set_margin_start(12);
|
||||
flagLabel.set_margin_end(12);
|
||||
//flagLabel.set_hexpand(true);
|
||||
|
||||
clockLabel.set_margin_top(12);
|
||||
clockLabel.set_margin_start(12);
|
||||
clockLabel.set_margin_end(12);
|
||||
clockLabel.set_hexpand(true);
|
||||
Glib::ustring clockmsg = Glib::ustring::compose("Elapsed time: 00:00.0");
|
||||
clockLabel.set_label(clockmsg);
|
||||
|
||||
boxH.append(labelMines);
|
||||
boxH.append(clockLabel);
|
||||
boxH.append(flagLabel);
|
||||
|
||||
|
||||
//TODO check if it's okay to mix std::shared_ptr with Gdk::ptr
|
||||
m_pixbufBomb = Gdk::Pixbuf::create_from_resource("/minesweeper/bomb-solid");
|
||||
m_pixbufFlag = Gdk::Pixbuf::create_from_resource("/minesweeper/flag-solid");
|
||||
m_pixbufFlagBomb = Gdk::Pixbuf::create_from_resource("/minesweeper/flag-bomb");
|
||||
|
||||
// bombPix.set_from_resource("/minesweeper/bomb-solid");
|
||||
|
||||
auto css_provider = Gtk::CssProvider::create();
|
||||
css_provider->load_from_data(
|
||||
".label-1 { font-weight: bold; font-size: 1.5em; color: Blue; }\
|
||||
.label-2 { font-weight: bold; font-size: 1.5em; color: Green; }\
|
||||
.label-3 { font-weight: bold; font-size: 1.5em; color: Darkorange; }\
|
||||
.label-4 { font-weight: bold; font-size: 1.5em; color: Purple; }\
|
||||
.label-5 { font-weight: bold; font-size: 1.5em; color: Red; }\
|
||||
.label-6 { font-weight: bold; font-size: 1.5em; color: Salmon; }\
|
||||
.label-7 { font-weight: bold; font-size: 1.5em; color: Turquoise; }\
|
||||
.label-8 { font-weight: bold; font-size: 1.5em; color: Magenta; }");
|
||||
|
||||
auto display = Gdk::Display::get_default();
|
||||
Gtk::StyleContext::add_provider_for_display(display, css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
for (int i = 0; i < field.getCols() * field.getRows(); i++) {
|
||||
auto button = std::make_shared<Gtk::ToggleButton>();
|
||||
button->set_size_request(50, 40);
|
||||
button->set_sensitive(true);
|
||||
button->set_active(false);
|
||||
int x = i % field.getCols();
|
||||
int y = i / field.getRows();
|
||||
button->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::OnCellClick), x, y));
|
||||
|
||||
//button->get_style_context()->add_class("fixed-button");
|
||||
|
||||
auto gesture = Gtk::GestureClick::create();
|
||||
gesture->set_button(3);
|
||||
gesture->signal_released().connect(sigc::bind(sigc::mem_fun(*this, \
|
||||
&MainWindow::OnCellRightClick), i));
|
||||
button->add_controller(gesture);
|
||||
|
||||
buttons.push_back(button);
|
||||
|
||||
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)));
|
||||
//newGameButton.set_label("New");
|
||||
//newGameButton.add_css_class("suggested-action");
|
||||
//newGameButton.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::OnNewButtonClick));
|
||||
|
||||
//optionButton.set_icon_name("open-menu");
|
||||
|
||||
//create the minefield
|
||||
//field = new MineField(COLS, MINES);
|
||||
|
||||
//bar.pack_start(newGameButton);
|
||||
//bar.pack_end(optionButton);
|
||||
|
||||
//grid.set_row_homogeneous(false);
|
||||
//grid.set_column_homogeneous(false);
|
||||
grid.set_margin(10);
|
||||
//grid.set_vexpand(true);
|
||||
//grid.set_hexpand(true);
|
||||
// grid.set_fill(false);
|
||||
|
||||
boxV.append(grid);
|
||||
|
||||
this->set_titlebar(bar);
|
||||
this->set_child(boxV);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
auto app = Gtk::Application::create("eu.minesweeper");
|
||||
return app->make_window_and_run<MainWindow>(argc, argv);
|
||||
}
|
||||
30
src/main.cpp
Normal file
30
src/main.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "MineField.hpp"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
|
||||
MineField field(160,160, 100);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
int x = rand() % 160;
|
||||
int y = rand() % 160;
|
||||
|
||||
field.initBombs(x, y);
|
||||
|
||||
printf("Opened cell: %i %i\n", x, y);
|
||||
printf("Neighboor bombs: %i\n", field.bombsNearby(x,y));
|
||||
|
||||
while(!field.isGameOver()) {
|
||||
x = rand() % 160;
|
||||
y = rand() % 160;
|
||||
|
||||
if(field.clearCell(x, y)) {
|
||||
printf("Opened cell: %i %i\n", x, y);
|
||||
printf("Neighboor bombs: %i\n", field.bombsNearby(x,y));
|
||||
}
|
||||
else {
|
||||
printf("Bomb found in cell: %i %i\n", x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/window.hpp
Normal file
62
src/window.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "MineField.hpp"
|
||||
#include "gdkmm/pixbuf.h"
|
||||
#include <memory>
|
||||
//#include <gtkmm-4.0/gtkmm/window.h>
|
||||
#include <gtkmm.h>
|
||||
#include <glibmm.h>
|
||||
#include <gdkmm.h>
|
||||
#include <sigc++/sigc++.h>
|
||||
//#include <gtkmm-4.0/gtkmm/togglebutton.h>
|
||||
//#include <gtkmm-4.0/gtkmm/grid.h>
|
||||
#include <gtkmm-4.0/gtkmm/gestureclick.h>
|
||||
//#include <gtkmm-4.0/gtkmm/headerbar.h>
|
||||
// #include <gdk-pixbuf-2.0/gdk-pixbuf/gdk-pixbuf.h>
|
||||
// #include <gtkmm-4.0/gtkmm/image.h>
|
||||
//#include <gtkmm-4.0/gtkmm/box.h>
|
||||
//#include <gtkmm-4.0/gtkmm/label.h>
|
||||
// #include <glibmm-2.68/glibmm/ustring.h>
|
||||
// #include <glibmm-2.68/glibmm/main.h>
|
||||
// #include <gtkmm-4.0/gtkmm/cssprovider.h>
|
||||
// #include <gtkmm-4.0/gtkmm.h>
|
||||
// #include <gtkmm-4.0/gtkmm/application.h>
|
||||
|
||||
#define PROJECT_NAME "minesweeper"
|
||||
|
||||
|
||||
class MainWindow : public Gtk::Window
|
||||
{
|
||||
Gtk::Box boxV{Gtk::Orientation::VERTICAL};
|
||||
Gtk::Box boxH{Gtk::Orientation::HORIZONTAL};
|
||||
std::vector<std::shared_ptr<Gtk::ToggleButton>> buttons;
|
||||
Gtk::Grid grid;
|
||||
Gtk::HeaderBar bar;
|
||||
Gtk::Button newGameButton;
|
||||
Gtk::Button optionButton;
|
||||
Gtk::Label flagLabel;
|
||||
Gtk::Label clockLabel;
|
||||
MineField field {16, 16, 40};
|
||||
int elapsedTime;
|
||||
bool newGame;
|
||||
std::shared_ptr<Gdk::Pixbuf> m_pixbufBomb;
|
||||
std::shared_ptr<Gdk::Pixbuf> m_pixbufFlag;
|
||||
std::shared_ptr<Gdk::Pixbuf> m_pixbufFlagBomb;
|
||||
void updateCell(int x, int y);
|
||||
void openBombs();
|
||||
void updateFlagsLabel(int flags);
|
||||
|
||||
// sigc::connection clockConn;
|
||||
// void OpenNearCells(int index);
|
||||
// void Explode();
|
||||
// bool AllCellsOpened();
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
// void OnNewButtonClick();
|
||||
void OnCellClick(int x, int y);
|
||||
void OnCellRightClick(int n_press, double n_x, double n_y, int index);
|
||||
// void ShowGameWonAnimation();
|
||||
// void ApplyStyles();
|
||||
// bool UpdateClockLabel();
|
||||
};
|
||||
Reference in New Issue
Block a user