#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;
}