Gros round de résolution de bogues.
This commit is contained in:
parent
3451a57bcf
commit
8d3f741fcc
@ -1,7 +1,7 @@
|
|||||||
#include "GOLTeamH.h"
|
#include "GOLTeamH.h"
|
||||||
|
|
||||||
GOLTeamH::GOLTeamH()
|
GOLTeamH::GOLTeamH()
|
||||||
: mParsedRule{}
|
: mParsedRule{}, mDeadColorEncoded{}, mAliveColorEncoded{}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//! \brief Accesseurs retournant des informations générales sur la
|
//! \brief Accesseurs retournant des informations générales sur la
|
||||||
@ -39,11 +39,11 @@ GOL::Statistics GOLTeamH::statistics() const
|
|||||||
.width = width(),
|
.width = width(),
|
||||||
.height = height(),
|
.height = height(),
|
||||||
.totalCells = size(),
|
.totalCells = size(),
|
||||||
.iteration = mIteration
|
.iteration = mIteration,
|
||||||
//.totalDeadAbs = mData.totalDead(),
|
.totalDeadAbs = mData.totalDead(),
|
||||||
//.totalAliveAbs = mData.totalAlive(),
|
.totalAliveAbs = mData.totalAlive(),
|
||||||
//.totalDeadRel = mData.totalDeadRel(),
|
.totalDeadRel = mData.totalDeadRel(),
|
||||||
//.totalAliveRel = mData.totalAliveRel()
|
.totalAliveRel = mData.totalAliveRel()
|
||||||
// .tendencyAbs = ...,
|
// .tendencyAbs = ...,
|
||||||
// .tendencyRel = ...
|
// .tendencyRel = ...
|
||||||
});
|
});
|
||||||
@ -71,7 +71,8 @@ GOL::ImplementationInformation GOLTeamH::information() const
|
|||||||
{
|
{
|
||||||
return std::move(ImplementationInformation{
|
return std::move(ImplementationInformation{
|
||||||
.title{"Laboratoire 1"},
|
.title{"Laboratoire 1"},
|
||||||
.authors{{"Timothée Leclaire-Fournier"}, {"Martin Euzenat martin.euzenat.1@ens.etsmtl.ca"}},
|
.authors{{"Timothée Leclaire-Fournier timothee.leclaire-fournier.1@ens.etsmtl.ca"},
|
||||||
|
{"Martin Euzenat martin.euzenat.1@ens.etsmtl.ca"}},
|
||||||
.answers{},
|
.answers{},
|
||||||
.optionnalComments{}
|
.optionnalComments{}
|
||||||
// Réponses aux questions...
|
// Réponses aux questions...
|
||||||
@ -210,7 +211,6 @@ bool GOLTeamH::setRule(std::string const& rule)
|
|||||||
//! **grille**.
|
//! **grille**.
|
||||||
|
|
||||||
|
|
||||||
// TODO: Changer le tableau intermédiaire aussi.
|
|
||||||
void GOLTeamH::setBorderManagement(BorderManagement borderManagement)
|
void GOLTeamH::setBorderManagement(BorderManagement borderManagement)
|
||||||
{
|
{
|
||||||
mBorderManagement = borderManagement;
|
mBorderManagement = borderManagement;
|
||||||
@ -351,10 +351,18 @@ bool GOLTeamH::setFromPattern(std::string const& pattern)
|
|||||||
//! \param color La nouvelle couleur de l'état.
|
//! \param color La nouvelle couleur de l'état.
|
||||||
void GOLTeamH::setSolidColor(State state, Color const& color)
|
void GOLTeamH::setSolidColor(State state, Color const& color)
|
||||||
{
|
{
|
||||||
if (state == State::alive)
|
if (state == State::alive) {
|
||||||
mAliveColor = color;
|
mAliveColor = color;
|
||||||
else
|
mAliveColorEncoded |= mAliveColor.red << 16;
|
||||||
|
mAliveColorEncoded |= mAliveColor.green << 8;
|
||||||
|
mAliveColorEncoded |= mAliveColor.blue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
mDeadColor = color;
|
mDeadColor = color;
|
||||||
|
mDeadColorEncoded |= mDeadColor.red << 16;
|
||||||
|
mDeadColorEncoded |= mDeadColor.green << 8;
|
||||||
|
mDeadColorEncoded |= mDeadColor.blue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -381,38 +389,41 @@ void GOLTeamH::processOneStep()
|
|||||||
auto const widthNoBorder{ mData.width() - 2 }, heightNoBorder{ mData.height() - 2 };
|
auto const widthNoBorder{ mData.width() - 2 }, heightNoBorder{ mData.height() - 2 };
|
||||||
auto const offset{ mData.width() };
|
auto const offset{ mData.width() };
|
||||||
|
|
||||||
size_t aliveCount{};
|
size_t neighbourAliveCount{}, aliveCount{};
|
||||||
|
|
||||||
// On commence à la première case qui n'est pas dans le border
|
// On commence à la première case qui n'est pas dans le border
|
||||||
auto* ptrGridInt{ (&(mData.intData()[0])) + (offset + 1) }; // Pointeur du tableau intermédiaire.
|
// Pointeur du tableau intermédiaire.
|
||||||
auto* ptrGrid{ &(mData.data()[0]) }; // Pointeur qui se promène en mémoire.
|
auto* ptrGridInt{ reinterpret_cast<uint8_t*>(&(mData.intData()[0])) + (offset + 1) };
|
||||||
|
|
||||||
for (size_t j{}; j < heightNoBorder; ++j) {
|
// Pointeur qui se promène en mémoire.
|
||||||
for (size_t i{}; i < widthNoBorder; ++i) {
|
auto* ptrGrid{ reinterpret_cast<uint8_t*>(&(mData.data()[0])) };
|
||||||
|
|
||||||
aliveCount = 0;
|
for (size_t j{ 1 }; j < heightNoBorder + 1; ++j) {
|
||||||
|
for (size_t i{ 1 }; i < widthNoBorder + 1; ++i) {
|
||||||
|
|
||||||
|
neighbourAliveCount = 0;
|
||||||
|
|
||||||
// Top
|
// Top
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
ptrGrid++;
|
ptrGrid++;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
ptrGrid++;
|
ptrGrid++;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
|
|
||||||
// Milieu
|
// Milieu
|
||||||
ptrGrid += offset - 2;
|
ptrGrid += offset - 2;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
ptrGrid += 2;
|
ptrGrid += 2;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
|
|
||||||
|
|
||||||
// Dessous
|
// Dessous
|
||||||
ptrGrid += offset - 2;
|
ptrGrid += offset - 2;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
ptrGrid++;
|
ptrGrid++;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
ptrGrid++;
|
ptrGrid++;
|
||||||
aliveCount += static_cast<uint8_t> (*ptrGrid);
|
neighbourAliveCount += *ptrGrid;
|
||||||
|
|
||||||
// On retourne à une place plus loin qu'à l'origine.
|
// On retourne à une place plus loin qu'à l'origine.
|
||||||
ptrGrid -= (2 * offset) + 1;
|
ptrGrid -= (2 * offset) + 1;
|
||||||
@ -425,11 +436,12 @@ void GOLTeamH::processOneStep()
|
|||||||
//
|
//
|
||||||
// On accède à la bonne partie des bits et on compare si le bit de survie/réanimation est
|
// On accède à la bonne partie des bits et on compare si le bit de survie/réanimation est
|
||||||
// présent. Voir GOLTeamH.cpp pour plus de détails.
|
// présent. Voir GOLTeamH.cpp pour plus de détails.
|
||||||
*(ptrGridInt - 1) = static_cast<GOL::State>(
|
*(ptrGridInt - 1) = static_cast<bool>(
|
||||||
static_cast<bool>(
|
(mParsedRule >> static_cast<bool>(*(ptrGrid + offset)) * 16) & (1u << neighbourAliveCount)
|
||||||
(mParsedRule >> static_cast<bool>(*(ptrGrid + offset)) * 16) & (1u << aliveCount)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (*(ptrGridInt - 1))
|
||||||
|
aliveCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On saute le border
|
// On saute le border
|
||||||
@ -441,6 +453,7 @@ void GOLTeamH::processOneStep()
|
|||||||
|
|
||||||
mData.switchToIntermediate();
|
mData.switchToIntermediate();
|
||||||
mIteration.value()++;
|
mIteration.value()++;
|
||||||
|
mData.setAliveCount(aliveCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -483,26 +496,27 @@ void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
|
|||||||
if (buffer == nullptr)
|
if (buffer == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* s_ptr = buffer;
|
auto* s_ptr{ buffer }, * e_ptr{ buffer + buffer_size };
|
||||||
|
|
||||||
auto width{ mData.width() }, height{ mData.height() };
|
// Pointeur qui se promène en mémoire.
|
||||||
auto* ptrGrid{ &mData.data()[0] }; // Pointeur qui se promène en mémoire.
|
auto* ptrGrid{ reinterpret_cast<const uint8_t*>(&mData.data()[0]) };
|
||||||
auto var = static_cast<uint8_t>(*ptrGrid); // Variable qui va décoder l'état d'une cellule.
|
|
||||||
|
// Variable qui va décoder l'état d'une cellule.
|
||||||
|
auto var{ *ptrGrid };
|
||||||
|
|
||||||
// On itère sur chaque éléments du tableau et on associe la couleur.
|
// On itère sur chaque éléments du tableau et on associe la couleur.
|
||||||
for (size_t j{}; j < height * width; ++j) {
|
while (s_ptr < e_ptr) {
|
||||||
var = static_cast<uint8_t>(*ptrGrid);
|
var = *ptrGrid;
|
||||||
|
|
||||||
*s_ptr &= 0; // Clear
|
*s_ptr &= 0; // Clear
|
||||||
*s_ptr |= MAX_ALPHA << 24; // Alpha = 255
|
*s_ptr |= MAX_ALPHA << 24; // Alpha = 255
|
||||||
|
|
||||||
*s_ptr |= mAliveColor.red * var << 16;
|
if (var) {
|
||||||
*s_ptr |= mAliveColor.green * var << 8;
|
*s_ptr |= mAliveColorEncoded;
|
||||||
*s_ptr |= mAliveColor.blue * var;
|
}
|
||||||
|
else {
|
||||||
*s_ptr |= mDeadColor.red * (1 - var) << 16;
|
*s_ptr |= mDeadColorEncoded;
|
||||||
*s_ptr |= mDeadColor.green * (1 - var) << 8;
|
}
|
||||||
*s_ptr |= mDeadColor.blue * (1 - var);
|
|
||||||
|
|
||||||
s_ptr++;
|
s_ptr++;
|
||||||
ptrGrid++;
|
ptrGrid++;
|
||||||
|
@ -47,6 +47,9 @@ private:
|
|||||||
//
|
//
|
||||||
// Le premier 16 bits (à gauche) est celui de la règle de survie alors
|
// Le premier 16 bits (à gauche) est celui de la règle de survie alors
|
||||||
// qu'à droite nous avons la règle de réanimation.
|
// qu'à droite nous avons la règle de réanimation.
|
||||||
|
//
|
||||||
|
// Exemple:
|
||||||
|
//
|
||||||
// 0000000111000111 0000000110011001
|
// 0000000111000111 0000000110011001
|
||||||
// ^^^^^^^ ^^^^^^^
|
// ^^^^^^^ ^^^^^^^
|
||||||
// Bits non utilisés
|
// Bits non utilisés
|
||||||
@ -55,6 +58,7 @@ private:
|
|||||||
|
|
||||||
GridTeamH mData;
|
GridTeamH mData;
|
||||||
Color mDeadColor, mAliveColor;
|
Color mDeadColor, mAliveColor;
|
||||||
|
uint32_t mDeadColorEncoded, mAliveColorEncoded;
|
||||||
|
|
||||||
// Fonctions utilisées à l'interne.
|
// Fonctions utilisées à l'interne.
|
||||||
std::optional<unsigned char> convertCharToNumber(const char c);
|
std::optional<unsigned char> convertCharToNumber(const char c);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "GridTeamH.h"
|
#include "GridTeamH.h"
|
||||||
#include "GOL.h"
|
#include "GOL.h"
|
||||||
#include <algorithm>
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
// Constructeur Grid par défaut
|
// Constructeur Grid par défaut
|
||||||
GridTeamH::GridTeamH()
|
GridTeamH::GridTeamH()
|
||||||
@ -9,7 +10,7 @@ GridTeamH::GridTeamH()
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridTeamH::GridTeamH(size_t width, size_t height, CellType initValue)
|
GridTeamH::GridTeamH(size_t width, size_t height, CellType initValue)
|
||||||
:mWidth{ width }, mHeight{ height }, mEngine(mRandomDevice()), mDistribution(0.0, 1.0)
|
:mWidth{ width }, mHeight{ height }, mEngine(mRandomDevice()), mDistribution(0.0, 1.0), mAliveCount{}
|
||||||
{
|
{
|
||||||
resize(width, height, initValue);
|
resize(width, height, initValue);
|
||||||
}
|
}
|
||||||
@ -28,7 +29,7 @@ void GridTeamH::resize(size_t width, size_t height, CellType initValue)
|
|||||||
mData.resize(width * height);
|
mData.resize(width * height);
|
||||||
mIntermediateData.resize(width * height);
|
mIntermediateData.resize(width * height);
|
||||||
|
|
||||||
fill(initValue, false);
|
fill(initValue, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
|
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
|
||||||
@ -62,6 +63,11 @@ void GridTeamH::setAt(int column, int row, CellType value)
|
|||||||
mData[(row - 1) * mWidth + (column - 1)] = value;
|
mData[(row - 1) * mWidth + (column - 1)] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GridTeamH::setAliveCount(size_t aliveCount)
|
||||||
|
{
|
||||||
|
mAliveCount = aliveCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Accesseur en lecture seule sur le "buffer" de la grille.
|
// Accesseur en lecture seule sur le "buffer" de la grille.
|
||||||
GridTeamH::DataType const& GridTeamH::data() const
|
GridTeamH::DataType const& GridTeamH::data() const
|
||||||
@ -85,11 +91,9 @@ GridTeamH::DataType& GridTeamH::intData()
|
|||||||
return mIntermediateData;
|
return mIntermediateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: FIX performance
|
|
||||||
// https://en.cppreference.com/w/cpp/algorithm/count
|
|
||||||
size_t GridTeamH::totalDead() const
|
size_t GridTeamH::totalDead() const
|
||||||
{
|
{
|
||||||
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::dead; });
|
return mAliveCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GridTeamH::totalDeadRel() const
|
float GridTeamH::totalDeadRel() const
|
||||||
@ -97,10 +101,9 @@ float GridTeamH::totalDeadRel() const
|
|||||||
return static_cast<float>(totalDead()) / static_cast<float>(size());
|
return static_cast<float>(totalDead()) / static_cast<float>(size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: FIX
|
|
||||||
size_t GridTeamH::totalAlive() const
|
size_t GridTeamH::totalAlive() const
|
||||||
{
|
{
|
||||||
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::alive; });
|
return (mWidth * mHeight) - mAliveCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GridTeamH::totalAliveRel() const
|
float GridTeamH::totalAliveRel() const
|
||||||
@ -160,8 +163,13 @@ void GridTeamH::randomize(double percentAlive, bool fillBorder)
|
|||||||
|
|
||||||
void GridTeamH::fillBorder(CellType value)
|
void GridTeamH::fillBorder(CellType value)
|
||||||
{
|
{
|
||||||
auto* ptr = &mData.front();
|
fillBorderManipulations(&mData.front(), value);
|
||||||
auto* e_ptr = &mData.front() + mWidth;
|
fillBorderManipulations(&mIntermediateData.front(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridTeamH::fillBorderManipulations(CellType* ptr, CellType value) const
|
||||||
|
{
|
||||||
|
auto* e_ptr = ptr + (mWidth - 1);
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
while (ptr < e_ptr) {
|
while (ptr < e_ptr) {
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
size_t width() const { return mWidth; }
|
size_t width() const { return mWidth; }
|
||||||
size_t height() const { return mHeight; }
|
size_t height() const { return mHeight; }
|
||||||
size_t size() const { return mHeight * mWidth; }
|
size_t size() const { return mHeight * mWidth; }
|
||||||
|
size_t aliveCount() const { return mAliveCount; }
|
||||||
|
|
||||||
void resize(size_t width, size_t height, CellType initValue = CellType{});
|
void resize(size_t width, size_t height, CellType initValue = CellType{});
|
||||||
|
|
||||||
@ -41,6 +42,8 @@ public:
|
|||||||
std::optional<CellType> at(int column, int row) const;
|
std::optional<CellType> at(int column, int row) const;
|
||||||
void setAt(int column, int row, CellType value);
|
void setAt(int column, int row, CellType value);
|
||||||
|
|
||||||
|
void setAliveCount(size_t aliveCount);
|
||||||
|
|
||||||
// Accesseurs du "buffer" de la grille
|
// Accesseurs du "buffer" de la grille
|
||||||
DataType const& data() const;
|
DataType const& data() const;
|
||||||
DataType& data();
|
DataType& data();
|
||||||
@ -66,10 +69,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DataType mData, mIntermediateData;
|
DataType mData, mIntermediateData;
|
||||||
size_t mWidth, mHeight;
|
size_t mWidth, mHeight, mAliveCount;
|
||||||
|
|
||||||
// Pour la génération de nombres aléatoires
|
// Pour la génération de nombres aléatoires
|
||||||
std::random_device mRandomDevice;
|
std::random_device mRandomDevice;
|
||||||
std::mt19937 mEngine;
|
std::mt19937 mEngine;
|
||||||
std::uniform_real_distribution<> mDistribution;
|
std::uniform_real_distribution<> mDistribution;
|
||||||
|
|
||||||
|
void fillBorderManipulations(CellType* ptr, CellType value) const;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user