#include "World.h"
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include "GL/glut.h"
World::World( int w, int h )
{
srand( time( 0 ) );
best_rule = new Rule();
active_rule = new Rule();
active_rule->InitBasic();
active_rule->Mutate();
garden = new Garden();
garden->Grow( active_rule );
tendcount = 0;
waitcount = 0;
stagnation = 0;
width = w;
height = h;
}
World::~World(void)
{
}
void World::Render()
{
glLoadIdentity();
glViewport( 0, 0, width, height );
glOrtho( 0, 1, 0, 1, -0.01, 0.01 );
garden->Render();
}
void World::Step()
{
if ( waitcount > 1 )
{
waitcount--;
return;
}
if ( waitcount == 1 )
{
RotateRules();
}
if ( garden->Depth() < 6 )
{
garden->Grow( active_rule );
}
else
{
CheckFitness();
}
}
void World::CheckFitness()
{
garden->ClearScratch();
Fitness f;
Fitness a;
a.clumpsize = 0;
a.perimeter = 0;
int fcount = 0;
while ( ( f = garden->GetFitness( (0.1 * rand())/RAND_MAX, (0.1 * rand())/RAND_MAX, (0.1 * rand())/RAND_MAX) ).clumpsize )
{
if ( f.clumpsize == 1 ) continue;
a.clumpsize += f.clumpsize;
a.perimeter += f.perimeter;
fcount++;
}
if ( fcount )
{
a.clumpsize /= fcount;
a.perimeter /= fcount;
}
a.numclumps = fcount;
active_rule->fit = a;
SetValue();
waitcount = 10;
}
void World::RotateRules()
{
waitcount = 0;
if ( stagnation > 25 ) stagnation = 0;
if ( active_rule->fit.value > best_rule->fit.value )
{
best_rule->Copy( active_rule );
stagnation = 0;
}
else stagnation++;
delete garden;
garden = new Garden();
delete active_rule;
active_rule = new Rule();
active_rule->Copy( best_rule );
active_rule->Mutate();
for ( int m = 0 ; m < stagnation ; m++ )
active_rule->Mutate();
}
void World::SetValue()
{
float total = garden->TotalCount();
float clump = active_rule->fit.clumpsize;
float perim = active_rule->fit.perimeter;
float num = active_rule->fit.numclumps;
float size = pow( 4, garden->Depth() );
if ( total == 0 || clump == 0 || size == 0 )
{
active_rule->fit.value = 0;
return;
}
//aim for filling about a third of the screen
double adj;
if ( total / size < 0.3 )
{
adj = ( 0.3 - total/size ) / 0.3;
}
else
{
adj = ( total/size - 0.3 ) / 0.7;
}
adj = 1.0 - adj;
//with shapes as complex as possible, and as many as possible
active_rule->fit.value = adj * adj * perim * num * num;
}
# |
Change |
User |
Description |
Committed |
|
#1
|
4772 |
Sam Stafford |
Something I've been doodling with. |
|
|