#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
#include <iostream>
#include <QApplication>
#include <QPushButton>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
using namespace std;
// global variables:
const int WIDTH = 660;
const int HEIGHT = 400;
const int SIZE = 10;
const int NCOL = HEIGHT/SIZE; //SIZE must be a divisor of HEIGHT
const QColor textColor
= Qt
::white;
class Cell {
public:
int x;
int y;
bool alive;
vector<pair<int,int>> neigh;
Cell(int a = 0, int b = 0) {
x = a;
y = b;
alive = false;
vector<pair<int,int>> neigh;
}
if (this->alive) {
cell1
->setBrush
(QBrush(aliveCol
));
}
else {
cell1
->setBrush
(QBrush(deadCol
));
}
scene->addItem(cell1);
}
};
{
Q_OBJECT
public:
MainWindow
(QWidget *parent
= nullptr
);
~MainWindow();
int countAlive(Cell c, Cell mat[NCOL][NCOL]);
void step(Cell mat[NCOL][NCOL], int rep, int under, int over);
private:
Ui::MainWindow *ui;
Cell mat[NCOL][NCOL] = {};
};
#endif // MAINWINDOW_H
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
#include <iostream>
#include <QApplication>
#include <QPushButton>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
using namespace std;
// global variables:
const int WIDTH = 660;
const int HEIGHT = 400;
const int SIZE = 10;
const int NCOL = HEIGHT/SIZE; //SIZE must be a divisor of HEIGHT
const QColor aliveCol = QColor(200,200,200);
const QColor deadCol = QColor(50,50,50);
const QColor textColor = Qt::white;
class Cell {
public:
int x;
int y;
bool alive;
vector<pair<int,int>> neigh;
Cell(int a = 0, int b = 0) {
x = a;
y = b;
alive = false;
vector<pair<int,int>> neigh;
}
void draw(QGraphicsScene *scene){
QGraphicsRectItem *cell1 = new QGraphicsRectItem(this->x*SIZE,this->y*SIZE,SIZE,SIZE);
if (this->alive) {
cell1->setBrush(QBrush(aliveCol));
}
else {
cell1->setBrush(QBrush(deadCol));
}
scene->addItem(cell1);
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene);
int countAlive(Cell c, Cell mat[NCOL][NCOL]);
void step(Cell mat[NCOL][NCOL], int rep, int under, int over);
private:
Ui::MainWindow *ui;
Cell mat[NCOL][NCOL] = {};
};
#endif // MAINWINDOW_H
To copy to clipboard, switch view to plain text mode
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore/QRandomGenerator>
#include <algorithm>
#include <QDebug>
#include <QSlider>
MainWindow
::MainWindow(QWidget *parent
) , ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Rules:
int repRule = 3; //reproduction rule
int underRule = 1; //underpopulation rule
int overRule = 4; //overpopulation rule
//background:
scene->setBackgroundBrush(Qt::gray);
for (int i = 0; i <= NCOL; i++)
{
scene->addLine(SIZE*i,0,SIZE*i,HEIGHT);
scene->addLine(0,SIZE*i,HEIGHT,SIZE*i);
}
//adding the button:
button1
->setGeometry
(QRect(420,
20,
100,
30));
button1->setText("Start / Stop");
scene->addWidget(button1);
//adding sliders:
//reproduction slider
repSlider
= new QSlider(Qt
::Horizontal);
repSlider->setGeometry(20,440,100,20);
repSlider->setRange(0,8);
repSlider->setValue(repRule);
scene->addWidget(repSlider);
sl1Text->setPos(20,420);
sl1Text->setDefaultTextColor(textColor);
scene->addItem(sl1Text);
//underpopulation slider
underPopSlider
= new QSlider(Qt
::Horizontal);
underPopSlider->setGeometry(140,440,100,20);
underPopSlider->setRange(0,8);
underPopSlider->setValue(underRule);
scene->addWidget(underPopSlider);
sl2Text->setPos(140,420);
sl2Text->setDefaultTextColor(textColor);
scene->addItem(sl2Text);
//overpopulation slider
overPopSlider
= new QSlider(Qt
::Horizontal);
overPopSlider->setGeometry(260,440,100,20);
overPopSlider->setRange(0,8);
overPopSlider->setValue(overRule);
scene->addWidget(overPopSlider);
sl3Text->setPos(260,420);
sl3Text->setDefaultTextColor(textColor);
scene->addItem(sl3Text);
//building the cells matrix:
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j] = Cell(i,j);
}
}
//adding the neighbours:
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair(i,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,j));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,j));
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j+1)%NCOL));
mat[i][j].neigh.push_back(make_pair(i,(j+1)%NCOL));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j+1)%NCOL));
}
}
//have an initial layout for debugging
mat[20][19].alive = true;
mat[20][20].alive = true;
mat[20][21].alive = true;
bool play = false;
updateScene(mat, scene);
//make scene
view->setFixedSize(670, 480);
view->show();
//connect the button:
connect(button1, &QPushButton::clicked, this, [&play]()
{
play = !play;
}
);
//connect the sliders:
connect(repSlider, &QSlider::valueChanged, this, [&play, repSlider, &repRule](){
if(!play) {
repRule = repSlider->value();
qDebug() << repRule;
}
});
connect(underPopSlider, &QSlider::valueChanged, this, [&play, underPopSlider, &underRule](){
if(!play) {
underRule = underPopSlider->value();
qDebug() << underRule;
}
});
connect(overPopSlider, &QSlider::valueChanged, scene, [&play, overPopSlider, &overRule](){
if(!play) {
overRule = overPopSlider->value();
qDebug() << overRule;
}
});
connect(_timer, &QTimer::timeout, scene, [this, &play, scene, repRule, underRule, overRule]()
{
if (play) {
step(mat, repRule, underRule, overRule);
updateScene(mat, scene);
}
}
);
_timer->start(200);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow
::updateScene(Cell mat
[NCOL
][NCOL
],
QGraphicsScene *scene
) {
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j].draw(scene);
}
}
}
int MainWindow::countAlive(Cell c, Cell mat[NCOL][NCOL]) //auxiliary function for the step function
{
int r = 0;
for (pair<int,int> p : c.neigh) {
if (mat[get<0>(p)][get<1>(p)].alive) {r++;}
}
return r;
}
void MainWindow::step(Cell mat[NCOL][NCOL], int repN, int underN, int overN) //animation step
{
int aliveCount;
vector<pair<int,int>> living = {};
for (int i = 0; i < NCOL; i++) {
for (int j = 0; j < NCOL; j++) {
aliveCount = countAlive(mat[i][j],mat);
//rules:
if(!mat[i][j].alive){
if(aliveCount == repN) {
living.push_back(make_pair(i,j));
}
}
else if (aliveCount > underN && aliveCount < overN) {
living.push_back(make_pair(i,j));
}
}
}
for (int i = 0; i < NCOL; i++) {
for (int j = 0; j < NCOL; j++) {
mat[i][j].alive = std::find(living.begin(), living.end(), make_pair(i,j)) != living.end();
}
}
qDebug() << repN << underN << overN;
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore/QRandomGenerator>
#include <algorithm>
#include <QDebug>
#include <QSlider>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene *scene = new QGraphicsScene(0, 0, WIDTH, HEIGHT+70);
//Rules:
int repRule = 3; //reproduction rule
int underRule = 1; //underpopulation rule
int overRule = 4; //overpopulation rule
//background:
scene->setBackgroundBrush(Qt::gray);
for (int i = 0; i <= NCOL; i++)
{
scene->addLine(SIZE*i,0,SIZE*i,HEIGHT);
scene->addLine(0,SIZE*i,HEIGHT,SIZE*i);
}
//adding the button:
QPushButton *button1;
button1 = new QPushButton();
button1->setGeometry(QRect(420, 20, 100, 30));
button1->setText("Start / Stop");
scene->addWidget(button1);
//adding sliders:
//reproduction slider
QSlider *repSlider;
repSlider = new QSlider(Qt::Horizontal);
repSlider->setGeometry(20,440,100,20);
repSlider->setRange(0,8);
repSlider->setValue(repRule);
scene->addWidget(repSlider);
QGraphicsTextItem *sl1Text = new QGraphicsTextItem("Reprodution:");
sl1Text->setPos(20,420);
sl1Text->setDefaultTextColor(textColor);
scene->addItem(sl1Text);
//underpopulation slider
QSlider *underPopSlider;
underPopSlider = new QSlider(Qt::Horizontal);
underPopSlider->setGeometry(140,440,100,20);
underPopSlider->setRange(0,8);
underPopSlider->setValue(underRule);
scene->addWidget(underPopSlider);
QGraphicsTextItem *sl2Text = new QGraphicsTextItem("Underpopulation:");
sl2Text->setPos(140,420);
sl2Text->setDefaultTextColor(textColor);
scene->addItem(sl2Text);
//overpopulation slider
QSlider *overPopSlider;
overPopSlider = new QSlider(Qt::Horizontal);
overPopSlider->setGeometry(260,440,100,20);
overPopSlider->setRange(0,8);
overPopSlider->setValue(overRule);
scene->addWidget(overPopSlider);
QGraphicsTextItem *sl3Text = new QGraphicsTextItem("Overpopulation:");
sl3Text->setPos(260,420);
sl3Text->setDefaultTextColor(textColor);
scene->addItem(sl3Text);
//building the cells matrix:
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j] = Cell(i,j);
}
}
//adding the neighbours:
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair(i,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j-1+NCOL)%NCOL));
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,j));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,j));
mat[i][j].neigh.push_back(make_pair((i-1+NCOL)%NCOL,(j+1)%NCOL));
mat[i][j].neigh.push_back(make_pair(i,(j+1)%NCOL));
mat[i][j].neigh.push_back(make_pair((i+1)%NCOL,(j+1)%NCOL));
}
}
//have an initial layout for debugging
mat[20][19].alive = true;
mat[20][20].alive = true;
mat[20][21].alive = true;
bool play = false;
updateScene(mat, scene);
//make scene
QGraphicsView *view = new QGraphicsView(scene);
view->setFixedSize(670, 480);
view->show();
QTimer *_timer = new QTimer; //for the animation
//connect the button:
connect(button1, &QPushButton::clicked, this, [&play]()
{
play = !play;
}
);
//connect the sliders:
connect(repSlider, &QSlider::valueChanged, this, [&play, repSlider, &repRule](){
if(!play) {
repRule = repSlider->value();
qDebug() << repRule;
}
});
connect(underPopSlider, &QSlider::valueChanged, this, [&play, underPopSlider, &underRule](){
if(!play) {
underRule = underPopSlider->value();
qDebug() << underRule;
}
});
connect(overPopSlider, &QSlider::valueChanged, scene, [&play, overPopSlider, &overRule](){
if(!play) {
overRule = overPopSlider->value();
qDebug() << overRule;
}
});
connect(_timer, &QTimer::timeout, scene, [this, &play, scene, repRule, underRule, overRule]()
{
if (play) {
step(mat, repRule, underRule, overRule);
updateScene(mat, scene);
}
}
);
_timer->start(200);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateScene(Cell mat[NCOL][NCOL], QGraphicsScene *scene)
{
for (int i = 0; i<NCOL; i++) {
for (int j = 0; j<NCOL; j++) {
mat[i][j].draw(scene);
}
}
}
int MainWindow::countAlive(Cell c, Cell mat[NCOL][NCOL]) //auxiliary function for the step function
{
int r = 0;
for (pair<int,int> p : c.neigh) {
if (mat[get<0>(p)][get<1>(p)].alive) {r++;}
}
return r;
}
void MainWindow::step(Cell mat[NCOL][NCOL], int repN, int underN, int overN) //animation step
{
int aliveCount;
vector<pair<int,int>> living = {};
for (int i = 0; i < NCOL; i++) {
for (int j = 0; j < NCOL; j++) {
aliveCount = countAlive(mat[i][j],mat);
//rules:
if(!mat[i][j].alive){
if(aliveCount == repN) {
living.push_back(make_pair(i,j));
}
}
else if (aliveCount > underN && aliveCount < overN) {
living.push_back(make_pair(i,j));
}
}
}
for (int i = 0; i < NCOL; i++) {
for (int j = 0; j < NCOL; j++) {
mat[i][j].alive = std::find(living.begin(), living.end(), make_pair(i,j)) != living.end();
}
}
qDebug() << repN << underN << overN;
}
To copy to clipboard, switch view to plain text mode
Bookmarks