Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <ctime>
- #include <array>
- #include <vector>
- #include <algorithm>
- #include <iostream>
- #include <SDL2/SDL.h>
- #define WIN_WIDTH 480
- #define WIN_HEIGHT 480
- #define CHANCE( m ) ((m == 0) || ((std::rand()% m + 1) == (int)m/2))
- #define RAND_BORN( mi, ma ) (std::rand() % (ma - mi) + mi)
- #define MALE 1
- #define FEMALE 0
- struct s_organism {
- struct {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- } gene;
- unsigned fitness;
- int id;
- int gender;
- unsigned reproduction_rate;
- bool can_reproduce;
- };
- struct s_color {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- };
- typedef struct s_organism t_organism;
- typedef struct s_color t_color;
- unsigned SortFunc( t_organism a, t_organism b ) {
- return ( a.fitness < b.fitness );
- }
- void ProcessMutation( std::vector<t_organism>& vec_organisms, t_color color_to_match, int tex_size, unsigned turn ) {
- float total_fitness = 0.f;
- unsigned best_fitness = 255 * 4;
- std::vector<t_organism> vec_org_male;
- std::vector<t_organism> vec_org_female;
- std::vector<t_organism> vec_best_org;
- for( t_organism& o : vec_organisms ) {
- o.fitness = sqrt( abs((color_to_match.r << 1 ) - (o.gene.r << 1)) +
- abs( (color_to_match.g << 1 ) - (o.gene.g << 1)) +
- abs( (color_to_match.b << 1 ) - (o.gene.b << 1)));
- total_fitness += o.fitness;
- if( o.fitness < best_fitness )
- best_fitness = o.fitness;
- }
- vec_best_org = vec_organisms;
- std::sort( vec_best_org.begin( ), vec_best_org.end(), SortFunc);
- for( int i = 0; i < 100; ++i ) {
- t_organism &o = vec_organisms.at( vec_best_org.at(i ).id);
- o.can_reproduce = true;
- o.reproduction_rate = RAND_BORN( 1, 12 );
- if( o.gender == 1 ) vec_org_male.push_back(o);
- else vec_org_female.push_back( o );
- }
- std::cout << "Turn: " << turn
- << "\n\t- Average fitness: " << total_fitness / vec_organisms.size( ) << "\n";
- for( t_organism& o : vec_organisms ) {
- if( !o.can_reproduce
- && !vec_org_male.empty( ) && !vec_org_female.empty()
- && RAND_BORN( 0, 100 ) < 70) {
- t_organism org_male;
- t_organism org_female;
- int n_color_father;
- int n_color_mother;
- bool a[2] = {false};
- bool reproduction;
- int i_male = RAND_BORN( 0, vec_org_male.size( ));
- int i_female = RAND_BORN( 0, vec_org_female.size( ));
- org_male = vec_org_male.at( i_male );
- org_female = vec_org_female.at( i_female );
- reproduction = ( (reproduction = CHANCE(org_male.reproduction_rate ) &&
- ( reproduction = CHANCE(org_female.reproduction_rate ))));
- if( reproduction ) {
- if( CHANCE(1000) ) {
- vec_org_male.erase( vec_org_male.begin( ) + i_male);
- vec_org_female.erase( vec_org_female.begin( ) + i_female);
- }
- n_color_father = RAND_BORN( 0, 3 );
- n_color_mother = RAND_BORN( 0, 3 );
- o.can_reproduce = false;
- o.gender = RAND_BORN( 0, 2 );
- while( n_color_mother == n_color_father )
- n_color_mother = RAND_BORN( 0, 3 );
- switch( n_color_father ) {
- case 0:
- a[0] = true;
- o.gene.r = org_male.gene.r;
- break;
- case 1:
- a[1] = true;
- o.gene.r = org_male.gene.g;
- break;
- case 2:
- a[2] = true;
- o.gene.b = org_male.gene.b;
- break;
- default:
- break;
- }
- switch( n_color_mother ) {
- case 0:
- a[0] = true;
- o.gene.r = org_female.gene.r;
- break;
- case 1:
- a[1] = true;
- o.gene.r = org_female.gene.g;
- break;
- case 2:
- a[2] = true;
- o.gene.b = org_female.gene.b;
- break;
- default:
- break;
- }
- if( !a[0] )
- o.gene.r = ( org_male.gene.r + org_female.gene.r ) / 2;
- else if( !a[1] )
- o.gene.g = ( org_male.gene.g + org_female.gene.g ) / 2;
- else
- o.gene.b = ( org_male.gene.b + org_female.gene.b ) / 2;
- for( int i = 0; i < 3 ; ++i ) {
- if( CHANCE(10000 )) {
- if( i == 0 )
- o.gene.r = RAND_BORN( 0, 255 );
- else if( i == 1 )
- o.gene.g = RAND_BORN( 0, 255 );
- else
- o.gene.b = RAND_BORN( 0, 255 );
- }
- }
- }
- }
- }
- }
- void InitMutation( std::vector<t_organism>& vec_organisms, int tex_size ) {
- int i = 0;
- for( t_organism &o : vec_organisms ) {
- o.gene.r = RAND_BORN( 0, 255 );
- o.gene.g = RAND_BORN( 0, 255 );
- o.gene.b = RAND_BORN( 0, 255 );
- o.gender = RAND_BORN( 0, 2 );
- o.can_reproduce = false;
- o.id = i++;
- }
- }
- void SetWorldAndColorToMatch( t_color *color_to_match, int *tex_size ) {
- int tmp_tex_size;
- printf( "Taille du monde (20 - %d ): ", WIN_WIDTH);
- scanf( "%d", &tmp_tex_size );
- printf( "R (0 - 255 ): ");
- scanf( "%d", &color_to_match->r );
- printf( "G (0 - 255 ): ");
- scanf( "%d", &color_to_match->g );
- printf( "B (0 - 255 ): ");
- scanf( "%d", &color_to_match->b );
- *tex_size = tmp_tex_size;
- if( *tex_size < 20 )
- *tex_size = 20;
- else if( *tex_size > WIN_WIDTH )
- *tex_size = WIN_WIDTH;
- }
- int main( int argc, char *argv[] ) {
- SDL_Init( SDL_INIT_VIDEO );
- bool running = true;
- bool pause = false;
- bool sorts = false;
- t_color color_to_match = {0, 0, 0};
- int tex_size;
- int turn = 0;
- int update_ms = 100;
- int prev_time = 0;
- int act_time = 0;
- std::srand( std::time(NULL ));
- SetWorldAndColorToMatch( &color_to_match, &tex_size );
- const int n_pixels = tex_size * tex_size;
- std::vector<t_organism> org_female;
- std::vector<t_organism> org_male;
- std::vector<t_organism> vec_organisms( n_pixels );
- std::vector<unsigned char> arr_pixels( n_pixels * 4 );
- SDL_Window *window = SDL_CreateWindow( "ColorMutation",
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- WIN_WIDTH, WIN_HEIGHT,
- SDL_WINDOW_SHOWN );
- SDL_Renderer *renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );
- SDL_Event event;
- SDL_Texture *texture = SDL_CreateTexture( renderer,
- SDL_PIXELFORMAT_ARGB8888,
- SDL_TEXTUREACCESS_STREAMING,
- tex_size, tex_size );
- InitMutation( vec_organisms, tex_size );
- while( running ) {
- SDL_SetRenderDrawColor( renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
- SDL_RenderClear( renderer );
- while( SDL_PollEvent(&event )) {
- switch( event.type ) {
- case SDL_QUIT:
- running = false;
- break;
- case SDL_KEYDOWN:
- if( event.key.keysym.sym == SDLK_SPACE ) {
- pause = !pause;
- }
- else if( event.key.keysym.sym == SDLK_LEFT ) {
- update_ms -= 10;
- if( update_ms < 0 )
- update_ms = 0;
- }
- else if( event.key.keysym.sym == SDLK_RIGHT ) {
- update_ms += 10;
- }
- else if( event.key.keysym.sym == SDLK_s ) {
- sorts = !sorts;
- }
- break;
- }
- }
- act_time = SDL_GetTicks( );
- if( act_time - prev_time > update_ms && !pause ) {
- turn++;
- prev_time = act_time;
- ProcessMutation( vec_organisms, color_to_match, tex_size, turn );
- int i = 0;
- if( sorts ) {
- std::vector<t_organism> sorts_vec_organisms;
- sorts_vec_organisms = vec_organisms;
- std::sort( sorts_vec_organisms.begin( ), sorts_vec_organisms.end(), SortFunc);
- for( unsigned y = 0; y < tex_size; ++y ) {
- for( unsigned x = 0; x < tex_size; ++x ) {
- const unsigned offset = ( tex_size * 4 * y ) + x * 4;
- arr_pixels.at( offset + 0 ) = sorts_vec_organisms[i].gene.b;
- arr_pixels.at( offset + 1 ) = sorts_vec_organisms[i].gene.g;
- arr_pixels.at( offset + 2 ) = sorts_vec_organisms[i++].gene.r;
- arr_pixels.at( offset + 3 ) = SDL_ALPHA_OPAQUE;
- }
- }
- }
- else {
- for( unsigned y = 0; y < tex_size; ++y ) {
- for( unsigned x = 0; x < tex_size; ++x ) {
- const unsigned offset = ( tex_size * 4 * y ) + x * 4;
- arr_pixels.at( offset + 0 ) = vec_organisms[i].gene.b;
- arr_pixels.at( offset + 1 ) = vec_organisms[i].gene.g;
- arr_pixels.at( offset + 2 ) = vec_organisms[i++].gene.r;
- arr_pixels.at( offset + 3 ) = SDL_ALPHA_OPAQUE;
- }
- }
- }
- SDL_UpdateTexture( texture, NULL, &arr_pixels[0], tex_size * 4 );
- SDL_RenderCopy( renderer, texture, NULL, NULL );
- SDL_RenderPresent( renderer );
- }
- else {
- SDL_Delay(update_ms - (act_time - prev_time));
- }
- }
- SDL_DestroyRenderer( renderer );
- SDL_DestroyWindow( window );
- SDL_Quit( );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement