// Genesaver: copyright 2003 Sam Stafford. #include <math.h> #include <GL/glut.h> #include "globals.h" #include "DNA.h" #include "Brain.h" #include "Thing.h" #include "Animal.h" Animal::Animal( DNA* d ) :brain( d, &step, &turn ) { prev = NULL; next = NULL; dead = tagged = false; pchewing = A_C; achewing = A_C; fighting = A_C; mating = A_C; step = 0.0; turn = 0.0; energy = A_E; dna = d; short i; short rd = 0; short gr = 0; short bl = 0; char cs[10]; for ( i = 0 ; i < 4 ; i++ ) cs[i] = dna->hchr.colr[i]; for ( i = 4 ; i < 10 ; i++ ) cs[i] = dna->ichr[i - 4].colr; for ( i = 0 ; i < 10 ; i++ ) { switch( abs( cs[i] % 3 ) ) { case 0: rd++; break; case 1: gr++; break; case 2: bl++; break; } } i = rd; color = Red; if ( gr > i || ( gr == i && RandFloat() < 0.5 ) ) { color = Green; i = gr; } if ( bl > i || ( bl == i && RandFloat() < 0.5 ) ) { color = Blue; } // Diet is a weighted sum of 10 genes, with those in the // H-chromosome being most significant. diet = 0.5; float fd = 0.0; for ( i = 0 ; i < 4 ; i++ ) fd += float( dna->hchr.diet[i] * 0.9 * pow( 10.0, -i ) / 255.0 ); for ( i = 4 ; i < 9 ; i++ ) fd += float( dna->ichr[i - 4].diet * 0.9 * pow( 10.0, -i ) / 255.0 ); fd += float( dna->ichr[9 - 4].diet * pow( 10.0, -i ) / 255.0 ); fd *= 1.01; //correct for floating-point errors, lean toward extremities diet += fd; if ( diet > 1 ) diet = 1; if ( diet < 0 ) diet = 0; brain.input[9].axon = diet; //tell the brain what it eats brain.color = this->color; } Animal::~Animal(void) { delete dna; } void Animal::Render() { glBegin( GL_POLYGON ); //Now the head. SetColor( color ); glVertex2f( x + A_R * cos( angle + 1.0 ), y + A_R * sin( angle + 1.0 ) ); glVertex2f( x + A_R * cos( angle - 1.0 ), y + A_R * sin( angle - 1.0 ) ); //Tail indicates diet. White = carnivore, black = herbivore. // We can also give it a flash of color during significant events. if ( settings.shade ) { if ( fighting && mating && mating > A_C - 5 ) SetColor( Cyan ); //birth else if ( fighting && fighting > A_C - 5 ) SetColor( Magenta ); //overcrowding else if ( mating && mating > A_C - 5 ) SetColor( Yellow ); //just married else glColor4f( diet, diet, diet, fsettings.alpha ); } glVertex2f( x - A_R * cos( angle ), y - A_R * sin( angle ) ); glEnd(); if ( tagged && settings.wake ) { glBegin( GL_LINES ); glColor3f( 1, 1, 1 ); glVertex2f( x-A_R*1.5*cos(angle) + A_R*0.5, y-A_R*1.5*sin(angle) ); if ( settings.shade ) glColor3f( 0, 0, 0 ); glVertex2f( x-A_R*2.0*step*cos(angle)-A_R*1.5*cos(angle) + A_R*0.5, y-A_R*2.0*step*sin(angle)-A_R*1.5*sin(angle) ); glColor3f( 1, 1, 1 ); glVertex2f( x-A_R*1.5*cos(angle) - A_R*0.5, y-A_R*1.5*sin(angle) ); if ( settings.shade ) glColor3f( 0, 0, 0 ); glVertex2f( x-A_R*2.0*step*cos(angle)-A_R*1.5*cos(angle) - A_R*0.5, y-A_R*2.0*step*sin(angle)-A_R*1.5*sin(angle) ); glColor3f( 1, 1, 1 ); glVertex2f( x-A_R*1.5*cos(angle), y-A_R*1.5*sin(angle) + A_R*0.5 ); if ( settings.shade ) glColor3f( 0, 0, 0 ); glVertex2f( x-A_R*2.0*step*cos(angle)-A_R*1.5*cos(angle), y-A_R*2.0*step*sin(angle)-A_R*1.5*sin(angle) + A_R*0.5 ); glColor3f( 1, 1, 1 ); glVertex2f( x-A_R*1.5*cos(angle), y-A_R*1.5*sin(angle) - A_R*0.5 ); if ( settings.shade ) glColor3f( 0, 0, 0 ); glVertex2f( x-A_R*2.0*step*cos(angle)-A_R*1.5*cos(angle), y-A_R*2.0*step*sin(angle)-A_R*1.5*sin(angle) - A_R*0.5 ); glEnd(); } } void Animal::RenderEnergy() { float e1, e2; e1 = energy / A_E; if ( e1 > 1.0 ) { e2 = e1 - 1.0; e1 = 1.0; } else e2 = 0.0; glBegin( GL_POLYGON ); glColor3f( 1.0 - e1, e1, 0 ); glVertex2f( -0.76, 0.5 - e1 / 2.1 ); glVertex2f( -0.74, 0.5 - e1 / 2.1 ); if ( settings.shade ) glColor3f( e1, 0, 1.0 - e1 ); glVertex2f( -0.74, 0.5 + e1 / 2.1 ); glVertex2f( -0.76, 0.5 + e1 / 2.1 ); glEnd(); if ( e2 == 0.0 ) return; glBegin( GL_POLYGON ); glColor3f( 1.0 - e2, 0, e2 ); glVertex2f( 0.76, 0.5 - e2 / 2.1 ); glVertex2f( 0.74, 0.5 - e2 / 2.1 ); if ( settings.shade ) glColor3f( e2, 1.0 - e2, 0 ); glVertex2f( 0.74, 0.5 + e2 / 2.1 ); glVertex2f( 0.76, 0.5 + e2 / 2.1 ); glEnd(); } void Animal::See( float d2, Color c, float d, float a ) { float f = 1.0 - ( d2 - A_R * A_R ) / ( A_V * A_V - A_R * A_R ); float da = a - angle; if ( cos( da ) <= 0 ) return; //behind you int i; //Send input to appropriate neuron. // input[0] = plant // input[2] = same // input[4] = prey // input[6] = predator switch( c ) { case P_C: i = 0; break; case Red: switch( color ) { case Red: i = 2; break; case Blue: i = 4; break; case Green: i = 6; break; } break; case Green: switch( color ) { case Green: i = 2; break; case Red: i = 4; break; case Blue: i = 6; break; } break; case Blue: switch( color ) { case Blue: i = 2; break; case Green: i = 4; break; case Red: i = 6; break; } break; } if ( sin( da ) <= sin( A_A ) && sin( da ) >= sin( -A_L ) )//left { brain.input[i].axon += f; } if ( sin( da ) < sin( A_L ) && sin( da ) > sin( -A_A ) )//right { brain.input[i+1].axon += f; } } void Animal::Step() { brain.Think(); x += float( step * A_S * cos( angle ) ); y += float( step * A_S * sin( angle ) ); angle += float( turn * A_T ); if ( x > 1.0 ) x -= 2.0; if ( x < -1.0 ) x += 2.0; if ( y > 1.0 ) y -= 2.0; if ( y < -1.0 ) y += 2.0; float p = step < 0 ? A_B : 1.0; energy -= step * A_M * A_S * p; energy -= A_Z; if ( pchewing ) pchewing--; if ( achewing ) achewing--; if ( fighting ) fighting--; if ( mating ) mating--; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 8465 | Sam Stafford | Finally building for Windows 7, by popular demand. | ||
#5 | 5393 | Sam Stafford |
Integrate in Marc's porting changes, and merge my own relevant winmain.cpp changes into main.cpp. (Thanks Marc!!!) |
||
#4 | 5384 | Sam Stafford |
Increase maximum allowable creature speed, fix a couple of bugs (some of them balance-related) with the alternate ecology ruleset. |
||
#3 | 5366 | Sam Stafford |
A bit of infrastructure tidying and a minor performance enhancement - the genome is now not saved when running in "demo mode" in Windows, which eliminates that little pause when you close the Windows display dialog after modifying Genesaver settings. |
||
#2 | 3348 | Sam Stafford | Decrease length of tail-color-flashes to 5 timesteps. | ||
#1 | 3052 | Sam Stafford |
Add Genesaver to the Public Depot. It's not in any way Perforce-related, but it does share a bit of code with Jamgraph, and it feels strange to have an open-source project that's not in the PD. |