Ajout de couleurs et renom de Grid

This commit is contained in:
Timothée Leclaire-Fournier 2024-01-19 14:26:55 -05:00
parent 590b8f3125
commit 2125676a72
7 changed files with 121 additions and 92 deletions

View File

@ -59,7 +59,7 @@ GOL::ImplementationInformation GOLTeamH::information() const
{ {
return std::move(ImplementationInformation{ return std::move(ImplementationInformation{
.title{"Laboratoire 1"}, .title{"Laboratoire 1"},
.authors{{"Timothée Leclaire-Fournier"}, {"et Martin Euzenat"} } .authors{{"Timothée Leclaire-Fournier"}, {"Martin Euzenat"} }
// Réponses aux questions... // Réponses aux questions...
}); });
} }
@ -174,10 +174,35 @@ void GOLTeamH::processOneStep()
} }
// TODO
void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
{ {
if (buffer == nullptr)
return;
auto s_ptr = buffer;
auto e_ptr = &buffer[buffer_size];
for (const auto& i : mData.data()) {
if (i == GridTeamH::CellType::alive) {
*s_ptr &= 0; // Clear
*s_ptr |= MAX_ALPHA << 24; // Alpha = 255
*s_ptr |= mAliveColor.red << 16;
*s_ptr |= mAliveColor.green << 8;
*s_ptr |= mAliveColor.blue;
}
else {
*s_ptr &= 0;
*s_ptr |= MAX_ALPHA << 24;
*s_ptr |= mDeadColor.red << 16;
*s_ptr |= mDeadColor.green << 8;
*s_ptr |= mDeadColor.blue;
}
s_ptr++;
// Sanity check
if (s_ptr > e_ptr)
break;
}
} }
std::optional<unsigned char> GOLTeamH::convertCharToNumber(const char c) std::optional<unsigned char> GOLTeamH::convertCharToNumber(const char c)

View File

@ -5,7 +5,9 @@
#include <optional> #include <optional>
#include <bitset> #include <bitset>
#include <GOL.h> #include <GOL.h>
#include "Grid.h" #include "GridTeamH.h"
constexpr unsigned char MAX_ALPHA = 255;
class GOLTeamH : public GOL class GOLTeamH : public GOL
{ {
@ -38,7 +40,7 @@ private:
std::optional<BorderManagement> mBorderManagement; std::optional<BorderManagement> mBorderManagement;
std::optional<IterationType> mIteration; std::optional<IterationType> mIteration;
Grid mData; GridTeamH mData;
std::bitset<9> mParsedRuleRevive, mParsedRuleSurvive; std::bitset<9> mParsedRuleRevive, mParsedRuleSurvive;
Color mDeadColor, mAliveColor; Color mDeadColor, mAliveColor;

View File

@ -111,14 +111,14 @@
<ItemGroup> <ItemGroup>
<QtRcc Include="GPA675Lab1GOL.qrc" /> <QtRcc Include="GPA675Lab1GOL.qrc" />
<ClCompile Include="GOLTeamH.cpp" /> <ClCompile Include="GOLTeamH.cpp" />
<ClCompile Include="Grid.cpp" /> <ClCompile Include="GridTeamH.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\GOLAppLib\header\GOL.h" /> <ClInclude Include="..\GOLAppLib\header\GOL.h" />
<QtMoc Include="..\GOLAppLib\header\GOLApp.h" /> <QtMoc Include="..\GOLAppLib\header\GOLApp.h" />
<ClInclude Include="GOLTeamH.h" /> <ClInclude Include="GOLTeamH.h" />
<ClInclude Include="Grid.h" /> <ClInclude Include="GridTeamH.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')"> <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">

View File

@ -31,7 +31,7 @@
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Grid.cpp"> <ClCompile Include="GridTeamH.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="GOLTeamH.cpp"> <ClCompile Include="GOLTeamH.cpp">
@ -39,7 +39,7 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Grid.h"> <ClInclude Include="GridTeamH.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="GOLTeamH.h"> <ClInclude Include="GOLTeamH.h">

View File

@ -1,61 +0,0 @@
#pragma once
#include <algorithm>
#include <vector>
#include <random>
#include "GOL.h"
class Grid // Classe facilitant la gestion d'un tableau dynamique 2d.
{ //
public: //
// Définition des types //
using CellType = GOL::State; // Correspond au type fondamental de chaque cellule de la grille.
using DataType = std::vector<CellType>; // Correspond à la grille, au conteneur de cellules. À vous de déterminer la structure de données à utiliser.
//
// Définition des constructeurs / destructeur //
Grid(); //
Grid(size_t width, size_t height, CellType initValue = CellType{}); //
Grid(Grid const&) = delete; //
Grid(Grid&&) = delete; //
Grid& operator=(Grid const&) = delete; //
Grid& operator=(Grid&&) = delete; //
~Grid(); //
//
// Accesseurs et mutateurs de la grille //
size_t width() const; // Accesseur retournant la largeur de la grille.
size_t height() const; // Accesseur retournant la hauteur de la grille.
size_t size() const; // Accesseur retournant le nombre de cellule de la grille.
//
void resize(size_t width, size_t height, CellType initValue = CellType{}); // Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée.
//
// Accesseurs et mutateurs des cellules //
CellType value(int column, int row) const; // Accesseur retournant la valeur d'une cellule à une certaine coordonnée. Pour une raison de performance, cette fonction NE VALIDE PAS ses entrées. Autrement dit, c'est la responsabilité du programmeur utilisateur de faire ses validations, au risque de 'crasher' le programme.
void setValue(int column, int row, CellType value); // Mutateur modifiant la valeur d'une cellule à une certaine coordonnée. Pour une raison de performance, cette fonction NE VALIDE PAS ses entrées. Autrement dit, c'est la responsabilité du programmeur utilisateur de faire ses validations, au risque de 'crasher' le programme.
//
std::optional<CellType> at(int column, int row) const; // Accesseur retournant la valeur d'une cellule à une certaine coordonnée. Cette fonction VALIDE ses entrées et retourne un optional nul si la coordonnée est invalide.
void setAt(int column, int row, CellType value); // Mutateur modifiant la valeur d'une cellule à une certaine coordonnée. Cette fonction VALIDE ses entrées et ne fait rien si la coordonnée est invalide.
//
// Accesseurs du "buffer" de la grille. //
DataType const& data() const; // Accesseur en lecture seule sur le "buffer" de la grille.
DataType& data(); // Accesseur en lecture/écriture sur le "buffer" de la grille.
size_t totalDead() const;
float totalDeadRel() const;
size_t totalAlive() const;
float totalAliveRel() const;
void fill(CellType value);
void fillAternately(CellType initValue);
void randomize(double percentAlive);
private: //
DataType mData; // Il y a des attributs essentiels au fonctionnement de cette classe.
size_t mWidth, mHeight; // À vous de les déterminer.
// Random
std::random_device mRandomDevice;
std::mt19937 mEngine;
std::uniform_real_distribution<> mDistribution;
};

View File

@ -1,42 +1,42 @@
#include "Grid.h" #include "GridTeamH.h"
#include "GOL.h" #include "GOL.h"
Grid::Grid() GridTeamH::GridTeamH()
: Grid(100, 100, CellType::alive) : GridTeamH(100, 100, CellType::alive)
{ {
} }
Grid::Grid(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)
{ {
resize(width, height, initValue); resize(width, height, initValue);
} }
// Destructeur Grid // Destructeur Grid
Grid::~Grid() GridTeamH::~GridTeamH()
{ {
} }
// Accesseur retournant la largeur de la grille. // Accesseur retournant la largeur de la grille.
size_t Grid::width() const size_t GridTeamH::width() const
{ {
return mWidth; return mWidth;
} }
// Accesseur retournant la hauteur de la grille. // Accesseur retournant la hauteur de la grille.
size_t Grid::height() const size_t GridTeamH::height() const
{ {
return mHeight; return mHeight;
} }
// Accesseur retournant le nombre de cellule de la grille (la taille de la grille). // Accesseur retournant le nombre de cellule de la grille (la taille de la grille).
size_t Grid::size() const size_t GridTeamH::size() const
{ {
return mWidth * mHeight; return mWidth * mHeight;
} }
// Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée. // Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée.
void Grid::resize(size_t width, size_t height, CellType initValue) void GridTeamH::resize(size_t width, size_t height, CellType initValue)
{ {
// TODO: Performance de resize avec beaucoup d'appel? // TODO: Performance de resize avec beaucoup d'appel?
// Investiguer reserve + resize // Investiguer reserve + resize
@ -48,19 +48,19 @@ void Grid::resize(size_t width, size_t height, CellType initValue)
} }
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée. // Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
Grid::CellType Grid::value(int column, int row) const GridTeamH::CellType GridTeamH::value(int column, int row) const
{ {
return mData[(column - 1) * (row - 1)]; return mData[(column - 1) * (row - 1)];
} }
// Mutateur modifiant la valeur d'une cellule à une certaine coordonnée. // Mutateur modifiant la valeur d'une cellule à une certaine coordonnée.
void Grid::setValue(int column, int row, CellType value) void GridTeamH::setValue(int column, int row, CellType value)
{ {
mData[(column - 1) * (row - 1)] = value; mData[(column - 1) * (row - 1)] = value;
} }
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée. // Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
std::optional<Grid::CellType> Grid::at(int column, int row) const std::optional<GridTeamH::CellType> GridTeamH::at(int column, int row) const
{ {
if (column > mWidth || row > mHeight) if (column > mWidth || row > mHeight)
return std::nullopt; return std::nullopt;
@ -69,7 +69,7 @@ std::optional<Grid::CellType> Grid::at(int column, int row) const
} }
// Mutateur modifiant la valeur d'une cellule à une certaine coordonn<6E>e. // Mutateur modifiant la valeur d'une cellule à une certaine coordonn<6E>e.
void Grid::setAt(int column, int row, CellType value) void GridTeamH::setAt(int column, int row, CellType value)
{ {
if (column > mWidth || row > mHeight) if (column > mWidth || row > mHeight)
return; return;
@ -77,44 +77,44 @@ void Grid::setAt(int column, int row, CellType value)
mData[(column - 1) * (row - 1)] = value; mData[(column - 1) * (row - 1)] = value;
} }
// Accesseur en lecture seule sur le "buffer" de la grille. // Accesseur en lecture seule sur le "buffer" de la grille.
Grid::DataType const& Grid::data() const GridTeamH::DataType const& GridTeamH::data() const
{ {
return mData; return mData;
} }
// Accesseur en lecture/écriture sur le "buffer" de la grille. // Accesseur en lecture/écriture sur le "buffer" de la grille.
Grid::DataType& Grid::data() GridTeamH::DataType& GridTeamH::data()
{ {
return mData; return mData;
} }
// https://en.cppreference.com/w/cpp/algorithm/count // https://en.cppreference.com/w/cpp/algorithm/count
size_t Grid::totalDead() const size_t GridTeamH::totalDead() const
{ {
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::dead; }); return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::dead; });
} }
float Grid::totalDeadRel() const float GridTeamH::totalDeadRel() const
{ {
return static_cast<float>(totalDead()) / static_cast<float>(size()); return static_cast<float>(totalDead()) / static_cast<float>(size());
} }
size_t Grid::totalAlive() const size_t GridTeamH::totalAlive() const
{ {
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::alive; }); return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::alive; });
} }
float Grid::totalAliveRel() const float GridTeamH::totalAliveRel() const
{ {
return static_cast<float>(totalAlive()) / static_cast<float>(size()); return static_cast<float>(totalAlive()) / static_cast<float>(size());
} }
void Grid::fill(CellType value) void GridTeamH::fill(CellType value)
{ {
for (auto& i : mData) for (auto& i : mData)
i = value; i = value;
} }
void Grid::fillAternately(CellType initValue) void GridTeamH::fillAternately(CellType initValue)
{ {
auto otherValue = (initValue == CellType::alive) ? CellType::dead : CellType::alive; auto otherValue = (initValue == CellType::alive) ? CellType::dead : CellType::alive;
@ -122,10 +122,12 @@ void Grid::fillAternately(CellType initValue)
mData[i] = !(i % 2) ? initValue : otherValue; mData[i] = !(i % 2) ? initValue : otherValue;
} }
void Grid::randomize(double percentAlive) void GridTeamH::randomize(double percentAlive)
{ {
for (auto& i : mData) { for (auto& i : mData) {
if (mDistribution(mEngine) < percentAlive) if (mDistribution(mEngine) < percentAlive)
i = CellType::alive; i = CellType::alive;
else
i = CellType::dead;
} }
} }

61
GPA675Lab1GOL/GridTeamH.h Normal file
View File

@ -0,0 +1,61 @@
#pragma once
#include <algorithm>
#include <vector>
#include <random>
#include "GOL.h"
class GridTeamH
{
public:
// Définition des types
using CellType = GOL::State;
using DataType = std::vector<CellType>;
// Définition des constructeurs / destructeur
GridTeamH();
GridTeamH(size_t width, size_t height, CellType initValue = CellType{});
GridTeamH(GridTeamH const&) = delete;
GridTeamH(GridTeamH&&) = delete;
GridTeamH& operator=(GridTeamH const&) = delete;
GridTeamH& operator=(GridTeamH&&) = delete;
~GridTeamH();
// Accesseurs et mutateurs de la grille
size_t width() const;
size_t height() const;
size_t size() const;
void resize(size_t width, size_t height, CellType initValue = CellType{});
// Accesseurs et mutateurs des cellules
CellType value(int column, int row) const;
void setValue(int column, int row, CellType value);
std::optional<CellType> at(int column, int row) const;
void setAt(int column, int row, CellType value);
// Accesseurs du "buffer" de la grille
DataType const& data() const;
DataType& data();
size_t totalDead() const;
float totalDeadRel() const;
size_t totalAlive() const;
float totalAliveRel() const;
void fill(CellType value);
void fillAternately(CellType initValue);
void randomize(double percentAlive);
private:
DataType mData;
size_t mWidth, mHeight;
// Pour la génération de nombres aléatoires
std::random_device mRandomDevice;
std::mt19937 mEngine;
std::uniform_real_distribution<> mDistribution;
};