Add generation screen
Finished the UI for the presentation. Probably last commit to this project, unless I decide to add rectangle squares.
This commit is contained in:
parent
5369805616
commit
62e6848dee
7 changed files with 255 additions and 62 deletions
|
|
@ -27,7 +27,8 @@ float Control::barMargin = 4;
|
||||||
|
|
||||||
|
|
||||||
Control::Control(float winW, float winH, std::string name) :
|
Control::Control(float winW, float winH, std::string name) :
|
||||||
screenSetup(this)
|
screenSetup(this),
|
||||||
|
screenGenerations(this)
|
||||||
{
|
{
|
||||||
this->window.create(sf::VideoMode(winW, winH), name);
|
this->window.create(sf::VideoMode(winW, winH), name);
|
||||||
|
|
||||||
|
|
@ -54,6 +55,14 @@ Control::~Control()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sf::Vector2f Control::getSizeWithBar()
|
||||||
|
{
|
||||||
|
sf::Vector2f size = sf::Vector2f(this->window.getSize());
|
||||||
|
size -= sf::Vector2f(0, this->leftText.getCharacterSize() + 2*Control::barMargin);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Control::interactive()
|
void Control::interactive()
|
||||||
{
|
{
|
||||||
this->currentScreen = nullptr;
|
this->currentScreen = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,10 @@ public:
|
||||||
static float barMargin;
|
static float barMargin;
|
||||||
|
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
|
sf::Vector2f getSizeWithBar();
|
||||||
|
|
||||||
ScreenSetup screenSetup;
|
ScreenSetup screenSetup;
|
||||||
|
ScreenGenerations screenGenerations;
|
||||||
|
|
||||||
Control(float winW, float winH, std::string name); // creates a window
|
Control(float winW, float winH, std::string name); // creates a window
|
||||||
~Control();
|
~Control();
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,12 @@ bool Fitness::loadTarget(std::string filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Fitness::saveChromosome(std::string filename)
|
||||||
|
{
|
||||||
|
return this->chromosome.getTexture().copyToImage().saveToFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Fitness::render(const Chromosome& chr)
|
void Fitness::render(const Chromosome& chr)
|
||||||
{
|
{
|
||||||
this->chromosome.clear(Fitness::backgroundColor);
|
this->chromosome.clear(Fitness::backgroundColor);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ public:
|
||||||
Fitness();
|
Fitness();
|
||||||
bool loadShader(std::string filename);
|
bool loadShader(std::string filename);
|
||||||
bool loadTarget(std::string filename);
|
bool loadTarget(std::string filename);
|
||||||
|
bool saveChromosome(std::string filename);
|
||||||
|
|
||||||
void render(const Chromosome& chr);
|
void render(const Chromosome& chr);
|
||||||
unsigned long long compute();
|
unsigned long long compute();
|
||||||
|
|
|
||||||
203
src/Screens.cpp
203
src/Screens.cpp
|
|
@ -17,11 +17,7 @@ Screen::~Screen()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ScreenSetup setup screen
|
// ScreenSetup screen
|
||||||
// const sf::Vector2f ScreenSetup::offset(20, 20);
|
|
||||||
// const float ScreenSetup::distance = 50;
|
|
||||||
// const int ScreenSetup::items = 3;
|
|
||||||
|
|
||||||
|
|
||||||
ScreenSetup::ScreenSetup(Control* controlptr) :
|
ScreenSetup::ScreenSetup(Control* controlptr) :
|
||||||
Screen(controlptr),
|
Screen(controlptr),
|
||||||
|
|
@ -40,7 +36,6 @@ ScreenSetup::ScreenSetup(Control* controlptr) :
|
||||||
|
|
||||||
void ScreenSetup::enter()
|
void ScreenSetup::enter()
|
||||||
{
|
{
|
||||||
std::cout << "ENTERED!" << std::endl;
|
|
||||||
this->rect.setSize(
|
this->rect.setSize(
|
||||||
sf::Vector2f(
|
sf::Vector2f(
|
||||||
this->control->window.getSize().x,
|
this->control->window.getSize().x,
|
||||||
|
|
@ -139,7 +134,7 @@ void ScreenSetup::executeItem(int position)
|
||||||
case 2: break; // spacing placeholder
|
case 2: break; // spacing placeholder
|
||||||
case 3:
|
case 3:
|
||||||
if (Chromosome::isAnyGeneTypeAllowed()) {
|
if (Chromosome::isAnyGeneTypeAllowed()) {
|
||||||
// this->control->switchScreen(Control::screenGenerations);
|
this->control->switchScreen(this->control->screenGenerations);
|
||||||
} else {
|
} else {
|
||||||
this->control->setText("Allow at least one gene type to continue.");
|
this->control->setText("Allow at least one gene type to continue.");
|
||||||
this->warnTimer = sf::seconds(3);
|
this->warnTimer = sf::seconds(3);
|
||||||
|
|
@ -186,3 +181,197 @@ void ScreenSetup::drawMenuItem(sf::RenderTarget& target, sf::RenderStates states
|
||||||
this->text.setPosition(position);
|
this->text.setPosition(position);
|
||||||
target.draw(text, states);
|
target.draw(text, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ScreenGenerations screen
|
||||||
|
|
||||||
|
ScreenGenerations::ScreenGenerations(Control* controlptr) :
|
||||||
|
Screen(controlptr)
|
||||||
|
{
|
||||||
|
this->targetSprite.setTexture(Control::fitness->target.getTexture());
|
||||||
|
this->chromoSprite.setTexture(Control::fitness->chromosome.getTexture());
|
||||||
|
|
||||||
|
this->currentGeneration = 0;
|
||||||
|
|
||||||
|
this->snapshotMode = true; // fullscreen
|
||||||
|
this->automaticSnapshots = false;
|
||||||
|
this->manualSnapshotCount = 0;
|
||||||
|
this->automaticSnapshotCount = 0;
|
||||||
|
|
||||||
|
this->lastBestFitness = -1;
|
||||||
|
std::cout << std::to_string(lastBestFitness) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::enter()
|
||||||
|
{
|
||||||
|
this->paused = true;
|
||||||
|
this->updateStatus();
|
||||||
|
this->updateSpriteSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::event(sf::Event& event)
|
||||||
|
{
|
||||||
|
if (event.type == sf::Event::KeyPressed) {
|
||||||
|
this->keyPressed(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::update(sf::Time dt)
|
||||||
|
{
|
||||||
|
if (!this->paused) {
|
||||||
|
Control::generation->advance();
|
||||||
|
++this->currentGeneration;
|
||||||
|
this->updateStatus();
|
||||||
|
|
||||||
|
if (this->automaticSnapshots && Control::generation->individuals[0].fitnessEvaluated) {
|
||||||
|
unsigned long long fitness = Control::generation->individuals[0].fitness;
|
||||||
|
if (fitness < this->lastBestFitness) {
|
||||||
|
std::cout << "Fitness decreased to " << std::to_string(fitness)
|
||||||
|
<< " -> taking snapshot!" << std::endl;
|
||||||
|
this->takeSnapshot(false);
|
||||||
|
this->lastBestFitness = fitness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
|
{
|
||||||
|
Control::fitness->render(Control::generation->individuals[0].chromosome);
|
||||||
|
target.draw(this->targetSprite, states);
|
||||||
|
target.draw(this->chromoSprite, states);
|
||||||
|
this->control->drawBar(target, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::exit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::keyPressed(sf::Event& event)
|
||||||
|
{
|
||||||
|
switch (event.key.code) {
|
||||||
|
// close window, stop program
|
||||||
|
case sf::Keyboard::Q:
|
||||||
|
this->control->close();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case sf::Keyboard::P:
|
||||||
|
this->paused = !this->paused;
|
||||||
|
this->updateStatus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::M:
|
||||||
|
this->snapshotMode = !this->snapshotMode;
|
||||||
|
this->updateStatus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::S:
|
||||||
|
this->takeSnapshot(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::A:
|
||||||
|
this->automaticSnapshots = !this->automaticSnapshots;
|
||||||
|
this->updateStatus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::updateSpriteSize()
|
||||||
|
{
|
||||||
|
sf::Vector2f size = sf::Vector2f(Control::fitness->target.getSize());
|
||||||
|
sf::Vector2f windowSize = this->control->getSizeWithBar();
|
||||||
|
|
||||||
|
float scale;
|
||||||
|
sf::Vector2f spritePos;
|
||||||
|
if (2*size.x/size.y > windowSize.x/windowSize.y) {
|
||||||
|
std::cout << "wider" << std::endl;
|
||||||
|
// the images are wider than the window
|
||||||
|
// display is calculated based on width
|
||||||
|
scale = windowSize.x/(2*size.x);
|
||||||
|
spritePos.x = 0;
|
||||||
|
spritePos.y = (windowSize.y - scale*size.y)/2;
|
||||||
|
} else {
|
||||||
|
std::cout << "higher" << std::endl;
|
||||||
|
// the images are higher than the window
|
||||||
|
// display is calculated based on height
|
||||||
|
scale = windowSize.y/size.y;
|
||||||
|
spritePos.x = (windowSize.x - (2*scale*size.x))/2;
|
||||||
|
spritePos.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->targetSprite.setScale(sf::Vector2f(scale, scale));
|
||||||
|
this->chromoSprite.setScale(sf::Vector2f(scale, scale));
|
||||||
|
|
||||||
|
this->targetSprite.setPosition(spritePos);
|
||||||
|
spritePos.x += scale*size.x;
|
||||||
|
this->chromoSprite.setPosition(spritePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::updateStatus()
|
||||||
|
{
|
||||||
|
std::string text = "Generation: ";
|
||||||
|
text += std::to_string(this->currentGeneration);
|
||||||
|
text += " (Genes: ";
|
||||||
|
text += std::to_string(Control::generation->individuals[0].chromosome.length());
|
||||||
|
text += ")";
|
||||||
|
this->control->setLeftText(text);
|
||||||
|
|
||||||
|
text = "[";
|
||||||
|
text += (this->paused)?"P":"-";
|
||||||
|
text += (this->automaticSnapshots)?"A":"-";
|
||||||
|
text += (this->snapshotMode)?"f":"c";
|
||||||
|
text += "]";
|
||||||
|
this->control->setRightText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScreenGenerations::takeSnapshot(bool manual)
|
||||||
|
{
|
||||||
|
// name for image file - count
|
||||||
|
std::string filename;
|
||||||
|
std::string count;
|
||||||
|
if (manual) {
|
||||||
|
filename = "manual_";
|
||||||
|
count = std::to_string(this->manualSnapshotCount);
|
||||||
|
++this->manualSnapshotCount;
|
||||||
|
} else {
|
||||||
|
filename = "automatic_";
|
||||||
|
count = std::to_string(this->automaticSnapshotCount);
|
||||||
|
++this->automaticSnapshotCount;
|
||||||
|
}
|
||||||
|
if (count.length() < 5) {
|
||||||
|
filename += std::string(5 - count.length(), '0');
|
||||||
|
}
|
||||||
|
filename += count;
|
||||||
|
|
||||||
|
// name for image file - generation and chromosome size
|
||||||
|
filename += "_gen_";
|
||||||
|
filename += std::to_string(this->currentGeneration);
|
||||||
|
filename += "_chr_";
|
||||||
|
filename += std::to_string(Control::generation->individuals[0].chromosome.length());
|
||||||
|
filename += ".png";
|
||||||
|
|
||||||
|
// actually save snapshot
|
||||||
|
if (this->snapshotMode) {
|
||||||
|
// fullscreen
|
||||||
|
sf::Texture tex;
|
||||||
|
sf::Vector2u size = this->control->window.getSize();
|
||||||
|
tex.create(size.x, size.y);
|
||||||
|
tex.update(this->control->window);
|
||||||
|
tex.copyToImage().saveToFile(filename);
|
||||||
|
} else {
|
||||||
|
// chromosome only
|
||||||
|
Control::fitness->saveChromosome(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,33 @@ private:
|
||||||
|
|
||||||
class ScreenGenerations : public Screen
|
class ScreenGenerations : public Screen
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
ScreenGenerations(Control* controlptr);
|
||||||
|
|
||||||
|
virtual void enter();
|
||||||
|
virtual void event(sf::Event& event);
|
||||||
|
virtual void update(sf::Time dt);
|
||||||
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
virtual void exit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool paused;
|
||||||
|
unsigned int currentGeneration;
|
||||||
|
|
||||||
|
bool snapshotMode;
|
||||||
|
bool automaticSnapshots;
|
||||||
|
unsigned long long lastBestFitness;
|
||||||
|
unsigned int manualSnapshotCount;
|
||||||
|
unsigned int automaticSnapshotCount;
|
||||||
|
|
||||||
|
sf::Sprite targetSprite;
|
||||||
|
sf::Sprite chromoSprite;
|
||||||
|
|
||||||
|
void keyPressed(sf::Event& event);
|
||||||
|
void updateSpriteSize();
|
||||||
|
void updateStatus();
|
||||||
|
|
||||||
|
void takeSnapshot(bool manual);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
67
src/main.cpp
67
src/main.cpp
|
|
@ -8,8 +8,17 @@
|
||||||
#include "Generation.hpp"
|
#include "Generation.hpp"
|
||||||
#include "Control.hpp"
|
#include "Control.hpp"
|
||||||
|
|
||||||
int main()
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
std::string filename;
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cout << "u dun goofed" << std::endl;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
filename = argv[1];
|
||||||
|
std::cout << "Using image: " << filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
std::minstd_rand randomEngine;
|
std::minstd_rand randomEngine;
|
||||||
randomEngine.seed(time(nullptr));
|
randomEngine.seed(time(nullptr));
|
||||||
|
|
||||||
|
|
@ -18,16 +27,15 @@ int main()
|
||||||
Generation::re = &randomEngine;
|
Generation::re = &randomEngine;
|
||||||
|
|
||||||
// Chromosome::allowGeneType(Gene::Circle);
|
// Chromosome::allowGeneType(Gene::Circle);
|
||||||
Chromosome::allowGeneType(Gene::Triangle);
|
// Chromosome::allowGeneType(Gene::Triangle);
|
||||||
|
|
||||||
Generation::size = 100;
|
Generation::size = 100;
|
||||||
Generation::living = 10;
|
Generation::living = 10;
|
||||||
Generation::crossover = 0.0;
|
Generation::crossover = 0.0;
|
||||||
|
|
||||||
Fitness fitn;
|
Fitness fitn;
|
||||||
fitn.loadTarget("firefox.png");
|
// fitn.loadTarget("firefox.png");
|
||||||
// fitn.loadTarget("tom-face.png");
|
fitn.loadTarget(filename);
|
||||||
// fitn.loadTarget("goldman_sachs.jpg");
|
|
||||||
fitn.loadShader("compare.glsl");
|
fitn.loadShader("compare.glsl");
|
||||||
|
|
||||||
Gene::size = sf::Vector2f(fitn.target.getSize());
|
Gene::size = sf::Vector2f(fitn.target.getSize());
|
||||||
|
|
@ -44,52 +52,3 @@ int main()
|
||||||
|
|
||||||
con.interactive();
|
con.interactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Chromosome a;
|
|
||||||
// for (int i=0; i<1000; ++i) a.mutate();
|
|
||||||
// Chromosome b(a);
|
|
||||||
// for (int i=0; i<10; ++i) b.mutate();
|
|
||||||
// Chromosome c(a);
|
|
||||||
// Chromosome d(a, b);
|
|
||||||
|
|
||||||
// std::cout << a.length() << " | " << b.length() << " | " << c.length() << " | " << d.length() << std::endl;
|
|
||||||
|
|
||||||
sf::Sprite ts(fitn.target.getTexture());
|
|
||||||
sf::Sprite cs(fitn.chromosome.getTexture());
|
|
||||||
|
|
||||||
sf::RenderWindow window(sf::VideoMode(winW, winH), "gross");
|
|
||||||
// window.setMouseCursorVisible(false);
|
|
||||||
|
|
||||||
int gencnt = 0;
|
|
||||||
|
|
||||||
while (window.isOpen()) {
|
|
||||||
sf::Event event;
|
|
||||||
while (window.pollEvent(event)) {
|
|
||||||
// if (event.type == sf::Event::KeyPressed) {
|
|
||||||
// std::cout << "Trying to advance generation" << std::endl;
|
|
||||||
// gen.advance();
|
|
||||||
// std::cout << "Advanced generation" << std::endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
gen.advance();
|
|
||||||
std::cout << "Generation: " << ++gencnt << " (length: " << gen.individuals[0].chromosome.length() << ")" << std::endl;
|
|
||||||
|
|
||||||
// display results
|
|
||||||
window.clear();
|
|
||||||
ts.setPosition( 0, 0); window.draw(ts);
|
|
||||||
fitn.render(gen.individuals[0].chromosome); cs.setPosition(240, 0); window.draw(cs);
|
|
||||||
fitn.render(gen.individuals[9].chromosome); cs.setPosition(240, 240); window.draw(cs);
|
|
||||||
// fitn.render(a); cs.setPosition( 0, 0); window.draw(cs);
|
|
||||||
// fitn.render(b); cs.setPosition(240, 0); window.draw(cs);
|
|
||||||
// fitn.render(c); cs.setPosition( 0, 240); window.draw(cs);
|
|
||||||
// fitn.render(d); cs.setPosition(240, 240); window.draw(cs);
|
|
||||||
window.display();
|
|
||||||
|
|
||||||
// std::cout << "Generation finished: " << ++gencnt << " (winner's length: "
|
|
||||||
// std::cout << genr.individuals[0].chromosome.length() << ")" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue