// Huvudfil: darwin.cpp #include "allan.cpp" #include "darwin.h" #define MAX 100 #define NEW 0 #define NORMAL 1 #define MUTATION 2 int Side; // Max 100 means max 10 000 positions struct Space { int grid[ MAX ][ MAX ], soil[ 6 ][ MAX ][ MAX ]; void prepare_soil() { int layer, x, y; for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) { for( layer = 0; layer < 6; layer++ ) soil[ layer ][ x ][ y ] = 0; // Make it ready to receive seeds } } } World; struct Type { float fitness; int type; TColor col; } Species[ 3 ]; // Three species, NEW, NORMAL and MUTATION int One_generation(); void Draw(), Mutation(), Spread_seeds( int x, int y ); void Catastrophy() { int x, x_survive, y, y_survive; // All individual outside a sub square will be perish // Side of sub square is 25 % of total world square // Decide position in x direction of surviving square x_survive = 0.75 * Side * Random_float(); y_survive = 0.75 * Side * Random_float(); for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) if( x >= x_survive && x < x_survive + 0.25 * Side && y >= y_survive && y < y_survive + 0.25 * Side ) World.grid[ x ][ y ] = World.grid[ x ][ y ]; // Protected else World.grid[ x ][ y ] = 0; // Dead Draw(); } void Draw() { int space, x, y; Clear_area(); for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) if( World.grid[ x ][ y ] > 0 ) { if( World.grid[ x ][ y ] == MUTATION ) Filled_circle_2d( x + 0.1, y + 0.1, x + 0.9, y + 0.9, Species[ World.grid[ x ][ y ] ].col, Species[ World.grid[ x ][ y ] ].col ); else Filled_circle_2d( x + 0.1, y + 0.1, x + 0.9, y + 0.9, Species[ World.grid[ x ][ y ] ].col, Species[ World.grid[ x ][ y ] ].col ); } } int Evolve() { int n = 0; // Generation needed for extinction while( One_generation() > 0 ) n++; return( n ); } int Fight( int x, int y ) { float sum1 = 0, // Sum of fitness parameters for all seeds in the position sum2 = 0; // Sum to decide wich seed to choose int position; // First make a sum of all fitness parameters of seeds in the position for( position = 1; position <= 5; position++ ) { sum1 += Species[ World.soil[ position ][ x ][ y ] ].fitness; } if( sum1 > 0 ) //Are there any seeds at all? { sum1 *= Random_float(); // Decide where to break the chain for( position = 1; position <= 5; position++ ) { //Take one seed at a time sum2 += Species[ World.soil[ position ][ x ][ y ] ].fitness; // Check if the present seed is chosen // If so, the random sum should be in the interval covered by the seed if( sum2 > sum1 ) break; } // Let the chosen seed grow to a full size plant World.grid[ x ][ y ] = World.soil[ position ][ x ][ y ]; } return( World.grid[ x ][ y ] ); } void Find_swap() { long generations = 0; int type; Clear_area(); type = Species[ NEW ].type; while( Species[ NEW ].type == type ) { Mutation(); generations += Evolve(); Form1 -> Edit1 -> Text = generations; } Draw(); Form1 -> Edit1 -> Text = generations; } void Generations() { int i, n; n = StrToInt( Form1 -> Edit1 -> Text ); for( i = 0; i < n; i++ ) // Let n generations pass { One_generation(); Draw(); } } void Mutation() { int found = false, // Nothing found before the search begins x, y; do { // Choose a random position x = int( Side * Random_float() ); y = int( Side * Random_float() ); // Check if it is empty if( World.grid[ x ][ y ] > 0 ) { // If there is a plant, let it mutate if( World.grid[ x ][ y ] == NORMAL ) { World.grid[ x ][ y ] = MUTATION; Species[ MUTATION ].fitness = 1 + StrToFloat( Form1 -> Edit2 -> Text ) / 100.0; } else // Let it mutate back { World.grid[ x ][ y ] = NORMAL; } found = true; } } while( found == false ); Species[ NEW ].type = World.grid[ x ][ y ]; // Tell what kind of mutation } int One_generation() { int n_mut = 0, // # of mutated individuals n_norm = 0, outcome, x, y; World.prepare_soil(); // Make it ready to receive seeds // Let each plant spread its seeds to closest locations for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) if( World.grid[ x ][ y ] > 0 ) Spread_seeds( x, y ); // Spread seeds only if there is a plant for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) { World.grid[ x ][ y ] = 0; // Let previous generation die and become soil outcome = Fight( x, y ); // Let the seed struggle for growth if( outcome == MUTATION ) n_mut++; // Let the growing seeds fight for survival if( outcome == NORMAL ) n_norm++; } if( n_mut * n_norm > 0 ) return( 1 ); else return( 0 ); } void Spread_seeds( int x, int y ) { if( ( x < Side - 1 ) ) // Stay inside the world { if( Random_float() < 0.4 ) // The plant creates 0 - 5 seeds, // two as a mean value World.soil[ 1 ][ x + 1 ][ y ] = World.grid[ x ][ y ]; } // No sub location will get more than one seed if( ( x > 0 ) ) { if( Random_float() < 0.4 ) World.soil[ 2 ][ x - 1 ][ y ] = World.grid[ x ][ y ]; } if( ( y < Side - 1 ) ) { if( Random_float() < 0.4 ) World.soil[ 3 ][ x ][ y + 1 ] = World.grid[ x ][ y ]; } if( ( y > 0 ) ) { if( Random_float() < 0.4 ) World.soil[ 4 ][ x ][ y - 1 ] = World.grid[ x ][ y ]; } if( Random_float() < 0.4 ) World.soil[ 5 ][ x ][ y ] = World.grid[ x ][ y ]; } void Setup() // Create environment and life { int layer, x, y; Side = StrToInt( Form1 -> Edit3 -> Text ); // Find size of the world for( x = 0; x < Side; x++ ) for( y = 0; y < Side; y++ ) World.grid[ x ][ y ] = 0; // Make world empty World.prepare_soil(); Species[ 0 ].fitness = 0; // Dummy Species[ NORMAL ].fitness = 1.0; Species[ NORMAL ].col = BLUE; Species[ MUTATION ].col = RED; Coordinates( -1, -1, Side + 1, Side + 1 ); World.grid[ Side / 2 ][ Side / 2 ] = NORMAL; Draw(); } //Windowsfil: Unit1.cpp //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- #include "darwin.cpp" void __fastcall TForm1::Button1Click(TObject *Sender) { Generations(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { static bool created = false; if( created == false ) { Setup(); Button2->Caption = "Catastrophy"; created = true; } else Catastrophy(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { Mutation(); Draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button4Click(TObject *Sender) { int n; n = Evolve(); Form1 -> Edit1 -> Text = n; Draw(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button5Click(TObject *Sender) { Find_swap(); } //--------------------------------------------------------------------------- //Headerfil: Unit1.h //--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include #include #include #include #include //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TLabel *Label1; TEdit *Edit1; TPaintBox *SimArea; TButton *Button2; TButton *Button3; TEdit *Edit2; TLabel *Label2; TLabel *Label3; TLabel *Label4; TLabel *Label5; TEdit *Edit3; TLabel *Label6; TButton *Button4; TButton *Button5; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); void __fastcall Button4Click(TObject *Sender); void __fastcall Button5Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif //Verktygsfil: allan.cpp #include #include #include #include #define DEFAULT 2 #define TRUE 1 #define FALSE 0 #define UNDEFINED -1 #define BACKGROUND clSilver #define WHITE (Graphics::TColor)0x00FFFFFF #define BLACK clBlack #define GRAY clGray #define DARKGRAY clDkGray #define RED clRed #define YELLOW clYellow #define GREEN clGreen #define BLUE clBlue TColor PixColor, Background = BACKGROUND, BoarderColor; short Boarder = UNDEFINED; #define PI 3.14159 #undef RAND_MAX #define RAND_MAX 65536 #define FOREVER for(;;) #define stccpy strncpy float XLeft, XRight, XSize, YDown, YSize, YUp, Winheight, Winwidth; FILE *In, *Out; unsigned long Last_random = 1000; short GraphicMode; int Pen_x, Pen_y; TColor Background_colour = clBtnFace; void Clear_area() { TRect NewRect = Rect( 1, 1, Winwidth, Winheight ); Form1 -> SimArea -> Canvas -> Brush -> Color = Background_colour; Form1 -> SimArea -> Canvas -> FillRect( NewRect ); } void Coordinates( float x_left, float y_down, float x_right, float y_up ) { XLeft = x_left; YDown = y_down; XRight = x_right; YUp = y_up; XSize = XRight - XLeft; YSize = YUp - YDown; Winwidth = Form1 -> SimArea -> Width; Winheight = Form1 -> SimArea -> Height; } void Filled_circle_2d( float left, float down, float right, float up, TColor fill, TColor boarder ) { int left_win, down_win, right_win, up_win; left_win = (int)( ( left - XLeft ) / XSize * Winwidth ) - 1; down_win = Winheight - (int)(( down - YDown ) / YSize * Winheight ) + 1; right_win = (int)( ( right - XLeft ) / XSize * Winwidth ) + 1; up_win = Winheight - (int)(( up - YDown ) / YSize * Winheight ) - 1; Form1 -> SimArea -> Canvas -> Brush -> Color = fill; Form1 -> SimArea -> Canvas -> Pen -> Color = boarder; Form1 -> SimArea -> Canvas -> Ellipse( left_win, down_win, right_win, up_win ); } Rnd() { Last_random = ( (long)Last_random * 31991 + 11 ) % RAND_MAX; return( Last_random ); } float Random_float() { float number; Rnd(); number = (float)Last_random / (float)RAND_MAX; return(number); } void Start_random_gen( long seed ) { Last_random = seed; }