Commit 4ea831f3 authored by Yann Boucher's avatar Yann Boucher
Browse files

Implemented tests for the transition rules we have; Implemented a circular transition rule

parent eb413934
Pipeline #78346 passed with stages
in 17 seconds
......@@ -66,16 +66,15 @@ private:
/**
\class PropertySaverVisitor
Cette classe permet de sauvegarder un ensemble de Property dans un fichier JSON donné.
Cette classe permet de sauvegarder un ensemble de Property dans un object JSON donné.
**/
class PropertySaverVisitor : public PropertyVisitor
{
public:
//! Construit le PropertySaverVisitor.
PropertySaverVisitor();
//! Sauvegarde les données des Property visitées au format JSON dans le fichier.
//! \param filename Le nom du fichier.
void save(const std::string& filename);
//! Sauvegarde les données des Property visitées au format JSON dans un QJsonObject.
QJsonObject save();
private:
QVariant& current();
......@@ -96,14 +95,13 @@ private:
/**
\class PropertyLoaderVisitor
Cette classe permet de charger un ensemble de Property depuis un fichier JSON donné.
Cette classe permet de charger un ensemble de Property depuis un pbject JSON donné.
**/
class PropertyLoaderVisitor : public PropertyVisitor
{
public:
//! Construit le PropertyLoaderVisitor à partir des données contenues dans un fichier JSON.
//! \param filename Le nom du fichier.
PropertyLoaderVisitor(const std::string& filename);
//! Construit le PropertyLoaderVisitor à partir d'un QJsonObject.
PropertyLoaderVisitor(const QJsonObject& root);
private:
QJsonValue& current();
......
#ifndef CIRCULARTRANSITION_HPP
#define CIRCULARTRANSITION_HPP
#include "transitionrule.hpp"
#include "property.hpp"
// http://joatdev.fr/CyclicAutomaton
class CircularTransition : public TransitionRule, public HasUserProperties
{
public:
bool acceptFormat(const std::vector<NeighborhoodFormat>&) const override
{ return true; }
unsigned getState(unsigned cell, const Neighborhood& neighborhood) const override
{
unsigned next_state = (cell+1) % states.val;
unsigned next_state_neighbors = neighborhood.getNb(next_state);
if ((int)next_state_neighbors >= thresold.val)
return next_state;
else
return cell;
}
private:
DEFINE_CONFIGURABLE_PROPERTY(IntegerProperty, states, "Nombre d'états", 1);
DEFINE_CONFIGURABLE_PROPERTY(IntegerProperty, thresold, "Seuil");
};
#endif // CIRCULARTRANSITION_HPP
......@@ -183,24 +183,9 @@ PropertySaverVisitor::PropertySaverVisitor()
push_object();
}
void PropertySaverVisitor::save(const std::string &filename)
QJsonObject PropertySaverVisitor::save()
{
//6. Create a QByteArray and fill it with QJsonDocument (json formatted)
QByteArray byteArray;
byteArray = QJsonDocument(current().toJsonObject()).toJson();
//7. Open a QFile and write the byteArray filled with json formatted data
//thanks to the QJsonDocument() Class to the file
QFile file;
file.setFileName(filename.c_str());
if(!file.open(QIODevice::WriteOnly)){
qDebug() << "No write access for json file";
return;
}
//8. finally write the file and close it
file.write(byteArray);
file.close();
return current().toJsonObject();
}
QVariant &PropertySaverVisitor::current()
......@@ -275,31 +260,9 @@ void PropertySaverVisitor::visit(PropertyList &list)
save_value(list, array);
}
PropertyLoaderVisitor::PropertyLoaderVisitor(const std::string &filename)
PropertyLoaderVisitor::PropertyLoaderVisitor(const QJsonObject& root)
{
//1. Open the QFile and write it to a byteArray and close the file
QFile file;
file.setFileName(filename.c_str());
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "Json filef couldn't be opened/found";
return;
}
QByteArray byteArray;
byteArray = file.readAll();
file.close();
//2. Format the content of the byteArray as QJsonDocument
//and check on parse Errors
QJsonParseError parseError;
QJsonDocument jsonDoc;
jsonDoc = QJsonDocument::fromJson(byteArray, &parseError);
if(parseError.error != QJsonParseError::NoError){
qWarning() << "Parse error at " << parseError.offset << ":" << parseError.errorString();
return;
}
m_current_hierarchy.push(jsonDoc.object());
m_current_hierarchy.push(root);
}
QJsonValue &PropertyLoaderVisitor::current()
......
......@@ -56,7 +56,8 @@ HEADERS += \
../include/history.h \
../include/structuresavingdialog.hpp \
../include/structurelibraryview.hpp \
../include/transitionrule.hpp
../include/transitionrule.hpp \
../include/transition_rules/circulartransition.hpp \
FORMS += \
../forms/interface.ui \
......
......@@ -15,7 +15,17 @@ bool LifeGameTransition::acceptFormat(const std::vector<NeighborhoodFormat>& for
return true;
}
unsigned int LifeGameTransition::getState(unsigned int, const Neighborhood & neighborhood) const {
unsigned int nb = neighborhood.getNb(1);
return (nb<=1||nb>=4)?0:1;
unsigned int LifeGameTransition::getState(unsigned int state, const Neighborhood & neighborhood) const {
unsigned int live = neighborhood.getNb(1);
if (state == 0)
{
return live == 3 ? 1 : 0;
}
else
{
if (live == 2 || live == 3)
return 1;
else
return 0;
}
}
......@@ -26,7 +26,8 @@ private slots:
void test_alphabet();
void test_circulartransition();
void test_lifegametransition();
};
#endif // CELLULUT_TESTS_HPP
#include "cellulut_tests.hpp"
#include "circulartransition.hpp"
#include "propertyvisitors.hpp"
void CellulutTests::test_circulartransition()
{
QJsonObject obj;
obj["Nombre d'états"] = 4;
obj["Seuil"] = 3;
CircularTransition rule; // load
{
PropertyLoaderVisitor visit(obj);
for (auto& prop : rule.get_properties())
prop->accept(visit);
}
// En dessous du seuil
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 0);
n.addNeighbor({1, 0}, 0);
n.addNeighbor({-1, 0}, 1);
unsigned next = rule.getState(0, n);
QCOMPARE(next, 0);
}
// >= au seuil
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 1);
n.addNeighbor({1, 0}, 1);
n.addNeighbor({-1, 0}, 0);
unsigned next = rule.getState(0, n);
QCOMPARE(next, 1);
}
// 1 -> 2
{
Neighborhood n;
n.addNeighbor({0, 1}, 2);
n.addNeighbor({0, -1}, 2);
n.addNeighbor({1, 0}, 2);
n.addNeighbor({-1, 0}, 0);
unsigned next = rule.getState(1, n);
QCOMPARE(next, 2);
}
// Vérification du modulo pour le nombre d'états
{
Neighborhood n;
n.addNeighbor({0, 1}, 0);
n.addNeighbor({0, -1}, 0);
n.addNeighbor({1, 0}, 0);
n.addNeighbor({-1, 0}, 0);
unsigned next = rule.getState(3, n);
QCOMPARE(next, 0);
}
}
#include "cellulut_tests.hpp"
#include "lifegametransition.h"
void CellulutTests::test_lifegametransition()
{
LifeGameTransition rule;
// Pas de naissance
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 0);
n.addNeighbor({1, 0}, 0);
n.addNeighbor({-1, 0}, 1);
unsigned next = rule.getState(0, n);
QCOMPARE(next, 0);
}
// Naissance
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 1);
n.addNeighbor({1, 0}, 0);
n.addNeighbor({-1, 0}, 1);
unsigned next = rule.getState(0, n);
QCOMPARE(next, 1);
}
// Survie
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 1);
n.addNeighbor({1, 0}, 0);
n.addNeighbor({-1, 0}, 0);
unsigned next = rule.getState(1, n);
QCOMPARE(next, 1);
}
// Sur-population
{
Neighborhood n;
n.addNeighbor({0, 1}, 1);
n.addNeighbor({0, -1}, 1);
n.addNeighbor({1, 0}, 1);
n.addNeighbor({-1, 0}, 1);
n.addNeighbor({-1, -1}, 1);
unsigned next = rule.getState(1, n);
QCOMPARE(next, 0);
}
// Sous-population
{
Neighborhood n;
n.addNeighbor({0, 1}, 0);
n.addNeighbor({0, -1}, 0);
n.addNeighbor({1, 0}, 1);
n.addNeighbor({-1, 0}, 0);
unsigned next = rule.getState(1, n);
QCOMPARE(next, 0);
}
}
......@@ -30,19 +30,20 @@ void CellulutTests::test_loader_saver_visitor()
prop2.c.x = 0; prop2.c.y = -3;
QJsonObject json;
// save
{
PropertySaverVisitor visit;
for (auto& prop : ex.get_properties())
prop->accept(visit);
visit.save("test.json");
json = visit.save();
}
Example ex_loaded;
// load
{
PropertyLoaderVisitor visit("test.json");
PropertyLoaderVisitor visit(json);
for (auto& prop : ex_loaded.get_properties())
prop->accept(visit);
}
......
......@@ -22,12 +22,15 @@ SOURCES += \
../src/history.cpp \
../src/grid.cpp \
../src/neighborhood_rules/mooreNeighborhoodRule.cpp \
../src/transition_rules/lifegametransition.cpp \
alphabet_test.cpp \
arbitraryneighborhoodrule_test.cpp \
circulartransition_test.cpp \
coord_tests.cpp \
factory_tests.cpp \
grid_test.cpp \
history_test.cpp \
lifegametransition_test.cpp \
mooreNeighborhoodRule_test.cpp \
property_test.cpp \
propertyvisitors_test.cpp \
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment