Advertisement
Le_BuG63

Untitled

Dec 2nd, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.74 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <ctime>
  4. #include <array>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <iostream>
  8.  
  9. #include <SDL2/SDL.h>
  10.  
  11. #define WIN_WIDTH   480
  12. #define WIN_HEIGHT  480
  13.  
  14. #define CHANCE( m )           ((m == 0) || ((std::rand()% m + 1) == (int)m/2))
  15. #define RAND_BORN( mi, ma )   (std::rand() % (ma - mi) + mi)
  16.  
  17. #define MALE    1
  18. #define FEMALE  0
  19.  
  20. struct s_organism {
  21.     struct {
  22.         unsigned char r;
  23.         unsigned char g;
  24.         unsigned char b;
  25.     } gene;
  26.  
  27.     unsigned fitness;
  28.  
  29.     int      id;
  30.     int      gender;
  31.  
  32.     unsigned reproduction_rate;
  33.  
  34.     bool     can_reproduce;
  35. };
  36.  
  37. struct s_color {
  38.     unsigned char r;
  39.     unsigned char g;
  40.     unsigned char b;
  41. };
  42.  
  43. typedef struct s_organism t_organism;
  44. typedef struct s_color    t_color;
  45.  
  46. unsigned SortFunc( t_organism a, t_organism b ) {
  47.     return ( a.fitness < b.fitness );  
  48. }
  49.  
  50. void ProcessMutation( std::vector<t_organism>& vec_organisms, t_color color_to_match, int tex_size, unsigned turn ) {
  51.     float       total_fitness = 0.f;
  52.     unsigned    best_fitness = 255 * 4;
  53.  
  54.     std::vector<t_organism> vec_org_male;
  55.     std::vector<t_organism> vec_org_female;
  56.     std::vector<t_organism> vec_best_org;
  57.  
  58.     for( t_organism& o : vec_organisms ) {      
  59.         o.fitness = sqrt( abs((color_to_match.r << 1 ) - (o.gene.r << 1)) +
  60.                 abs( (color_to_match.g << 1 ) - (o.gene.g << 1)) +
  61.                 abs( (color_to_match.b << 1 ) - (o.gene.b << 1)));
  62.  
  63.         total_fitness += o.fitness;
  64.  
  65.         if( o.fitness < best_fitness )
  66.             best_fitness = o.fitness;
  67.     }
  68.  
  69.     vec_best_org = vec_organisms;
  70.  
  71.     std::sort( vec_best_org.begin( ), vec_best_org.end(), SortFunc);
  72.  
  73.     for( int i = 0; i < 100; ++i ) {
  74.         t_organism &o = vec_organisms.at( vec_best_org.at(i ).id);
  75.         o.can_reproduce = true;
  76.  
  77.         o.reproduction_rate = RAND_BORN( 1, 12 );
  78.  
  79.         if( o.gender == 1 )    vec_org_male.push_back(o);
  80.         else                 vec_org_female.push_back( o );
  81.     }
  82.  
  83.     std::cout << "Turn: " << turn
  84.         << "\n\t- Average fitness: " << total_fitness / vec_organisms.size(  ) << "\n";
  85.  
  86.     for( t_organism& o : vec_organisms ) {
  87.         if( !o.can_reproduce
  88.         && !vec_org_male.empty(  ) && !vec_org_female.empty()
  89.         && RAND_BORN( 0, 100 ) < 70) {
  90.             t_organism  org_male;
  91.             t_organism  org_female;
  92.  
  93.             int         n_color_father;
  94.             int         n_color_mother;
  95.  
  96.             bool        a[2] = {false};
  97.             bool        reproduction;
  98.             int         i_male = RAND_BORN( 0, vec_org_male.size( ));
  99.             int         i_female = RAND_BORN( 0, vec_org_female.size( ));
  100.  
  101.             org_male    = vec_org_male.at( i_male );
  102.             org_female  = vec_org_female.at( i_female );
  103.  
  104.             reproduction = ( (reproduction = CHANCE(org_male.reproduction_rate ) &&
  105.                         ( reproduction = CHANCE(org_female.reproduction_rate ))));
  106.             if( reproduction ) {
  107.                 if( CHANCE(1000) ) {
  108.                     vec_org_male.erase( vec_org_male.begin( ) + i_male);
  109.                     vec_org_female.erase( vec_org_female.begin( ) + i_female);
  110.                 }
  111.                 n_color_father = RAND_BORN( 0, 3 );
  112.                 n_color_mother = RAND_BORN( 0, 3 );
  113.  
  114.                 o.can_reproduce = false;
  115.                 o.gender = RAND_BORN( 0, 2 );
  116.  
  117.                 while( n_color_mother == n_color_father )
  118.                     n_color_mother = RAND_BORN( 0, 3 );
  119.  
  120.                 switch( n_color_father ) {
  121.                     case 0:
  122.                         a[0] = true;
  123.                         o.gene.r = org_male.gene.r;
  124.                         break;
  125.                     case 1:
  126.                         a[1] = true;
  127.                         o.gene.r = org_male.gene.g;
  128.                         break;
  129.                     case 2:
  130.                         a[2] = true;
  131.                         o.gene.b = org_male.gene.b;
  132.                         break;
  133.                     default:
  134.                         break;
  135.                 }
  136.  
  137.                 switch( n_color_mother ) {
  138.                     case 0:
  139.                         a[0] = true;
  140.                         o.gene.r = org_female.gene.r;
  141.                         break;
  142.                     case 1:
  143.                         a[1] = true;
  144.                         o.gene.r = org_female.gene.g;
  145.                         break;
  146.                     case 2:
  147.                         a[2] = true;
  148.                         o.gene.b = org_female.gene.b;
  149.                         break;
  150.                     default:
  151.                         break;
  152.                 }
  153.  
  154.                 if( !a[0] )
  155.                     o.gene.r = ( org_male.gene.r + org_female.gene.r ) / 2;
  156.                 else if( !a[1] )
  157.                     o.gene.g = ( org_male.gene.g + org_female.gene.g ) / 2;
  158.                 else
  159.                     o.gene.b = ( org_male.gene.b + org_female.gene.b ) / 2;
  160.  
  161.                 for( int i = 0; i < 3 ; ++i ) {
  162.                     if( CHANCE(10000 )) {
  163.                         if( i == 0 )
  164.                             o.gene.r = RAND_BORN( 0, 255 );
  165.                         else if( i == 1 )
  166.                             o.gene.g = RAND_BORN( 0, 255 );
  167.                         else
  168.                             o.gene.b = RAND_BORN( 0, 255 );
  169.                     }
  170.                 }
  171.             }
  172.         }
  173.     }
  174. }
  175.  
  176. void InitMutation( std::vector<t_organism>& vec_organisms, int tex_size ) {
  177.     int i = 0;
  178.  
  179.     for( t_organism &o : vec_organisms ) {
  180.         o.gene.r = RAND_BORN( 0, 255 );
  181.         o.gene.g = RAND_BORN( 0, 255 );
  182.         o.gene.b = RAND_BORN( 0, 255 );
  183.  
  184.         o.gender = RAND_BORN( 0, 2 );
  185.         o.can_reproduce = false;
  186.  
  187.         o.id = i++;
  188.     }
  189. }
  190.  
  191. void SetWorldAndColorToMatch( t_color *color_to_match, int *tex_size ) {
  192.     int tmp_tex_size;
  193.    
  194.     printf( "Taille du monde (20 - %d ): ", WIN_WIDTH);
  195.     scanf( "%d", &tmp_tex_size );
  196.  
  197.     printf( "R (0 - 255 ): ");
  198.     scanf( "%d", &color_to_match->r );
  199.  
  200.     printf( "G (0 - 255 ): ");
  201.     scanf( "%d", &color_to_match->g );
  202.  
  203.     printf( "B (0 - 255 ): ");
  204.     scanf( "%d", &color_to_match->b );
  205.  
  206.     *tex_size = tmp_tex_size;
  207.  
  208.     if( *tex_size < 20 )
  209.         *tex_size = 20;
  210.     else if( *tex_size > WIN_WIDTH )
  211.         *tex_size = WIN_WIDTH;
  212. }
  213.  
  214. int main( int argc, char *argv[] ) {
  215.     SDL_Init( SDL_INIT_VIDEO );
  216.  
  217.     bool            running = true;
  218.     bool            pause = false;
  219.     bool            sorts = false;
  220.  
  221.     t_color         color_to_match = {0, 0, 0};
  222.  
  223.     int             tex_size;
  224.     int             turn = 0;
  225.     int             update_ms = 100;
  226.  
  227.     int             prev_time = 0;
  228.     int             act_time = 0;
  229.  
  230.     std::srand( std::time(NULL ));
  231.  
  232.     SetWorldAndColorToMatch( &color_to_match, &tex_size );
  233.  
  234.     const int n_pixels = tex_size * tex_size;
  235.  
  236.     std::vector<t_organism>     org_female;
  237.     std::vector<t_organism>     org_male;
  238.     std::vector<t_organism>     vec_organisms( n_pixels );
  239.  
  240.     std::vector<unsigned char>  arr_pixels( n_pixels * 4 );
  241.  
  242.     SDL_Window      *window = SDL_CreateWindow( "ColorMutation",
  243.             SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  244.             WIN_WIDTH, WIN_HEIGHT,
  245.             SDL_WINDOW_SHOWN );
  246.  
  247.     SDL_Renderer    *renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED );
  248.     SDL_Event       event;
  249.  
  250.     SDL_Texture     *texture = SDL_CreateTexture( renderer,
  251.             SDL_PIXELFORMAT_ARGB8888,
  252.             SDL_TEXTUREACCESS_STREAMING,
  253.             tex_size, tex_size );
  254.  
  255.     InitMutation( vec_organisms, tex_size );
  256.  
  257.     while( running ) {
  258.         SDL_SetRenderDrawColor( renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
  259.         SDL_RenderClear( renderer );
  260.  
  261.         while( SDL_PollEvent(&event )) {
  262.             switch( event.type ) {
  263.                 case SDL_QUIT:  
  264.                     running = false;
  265.                     break;
  266.                 case SDL_KEYDOWN:
  267.                     if( event.key.keysym.sym == SDLK_SPACE ) {
  268.                         pause = !pause;  
  269.                     }
  270.                     else if( event.key.keysym.sym == SDLK_LEFT ) {
  271.                         update_ms -= 10;  
  272.                         if( update_ms < 0 )
  273.                             update_ms = 0;
  274.                     }
  275.                     else if( event.key.keysym.sym == SDLK_RIGHT ) {
  276.                         update_ms += 10;  
  277.                     }
  278.                     else if( event.key.keysym.sym == SDLK_s ) {
  279.                         sorts = !sorts;  
  280.                     }
  281.                     break;
  282.             }    
  283.         }
  284.  
  285.         act_time = SDL_GetTicks(  );
  286.  
  287.         if( act_time - prev_time > update_ms && !pause ) {
  288.             turn++;
  289.             prev_time = act_time;
  290.  
  291.             ProcessMutation( vec_organisms,  color_to_match, tex_size, turn );
  292.             int i = 0;
  293.  
  294.             if( sorts ) {
  295.                 std::vector<t_organism> sorts_vec_organisms;
  296.  
  297.                 sorts_vec_organisms = vec_organisms;
  298.  
  299.                 std::sort( sorts_vec_organisms.begin( ), sorts_vec_organisms.end(), SortFunc);
  300.  
  301.                 for( unsigned y = 0; y < tex_size; ++y ) {
  302.                     for( unsigned x = 0; x < tex_size; ++x ) {
  303.                         const unsigned offset = ( tex_size * 4 * y ) + x * 4;
  304.  
  305.                         arr_pixels.at( offset + 0 ) = sorts_vec_organisms[i].gene.b;
  306.                         arr_pixels.at( offset + 1 ) = sorts_vec_organisms[i].gene.g;
  307.                         arr_pixels.at( offset + 2 ) = sorts_vec_organisms[i++].gene.r;
  308.                         arr_pixels.at( offset + 3 ) = SDL_ALPHA_OPAQUE;
  309.                     }
  310.                 }
  311.             }
  312.             else {
  313.                 for( unsigned y = 0; y < tex_size; ++y ) {
  314.                     for( unsigned x = 0; x < tex_size; ++x ) {
  315.                         const unsigned offset = ( tex_size * 4 * y ) + x * 4;
  316.  
  317.                         arr_pixels.at( offset + 0 ) = vec_organisms[i].gene.b;
  318.                         arr_pixels.at( offset + 1 ) = vec_organisms[i].gene.g;
  319.                         arr_pixels.at( offset + 2 ) = vec_organisms[i++].gene.r;
  320.                         arr_pixels.at( offset + 3 ) = SDL_ALPHA_OPAQUE;
  321.                     }
  322.                 }
  323.             }
  324.             SDL_UpdateTexture( texture, NULL, &arr_pixels[0], tex_size * 4 );
  325.  
  326.             SDL_RenderCopy( renderer, texture, NULL, NULL );
  327.             SDL_RenderPresent( renderer );
  328.         }
  329.         else {
  330.             SDL_Delay(update_ms - (act_time - prev_time));  
  331.         }
  332.     }
  333.  
  334.     SDL_DestroyRenderer( renderer );
  335.     SDL_DestroyWindow( window );
  336.  
  337.     SDL_Quit(  );
  338.  
  339.     return 0;
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement