Tests About Natural Selection In Virtual Environment
c
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

genome.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. Copyright (C) 2011 Weber Yann, Schuck Clement
  3. This file is part of Tansive.
  4. Tansive is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Tansive is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with Tansive. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include"genome.h"
  16. t_genome rand_genome()
  17. {
  18. t_genome genome;
  19. genome.name = rand_name();
  20. genome.nb_creat=0;
  21. genome.nb_nat_dead=0;
  22. genome.nb_star_dead=0;
  23. genome.nb_figt_dead=0;
  24. genome.nb_eat_dead=0;
  25. genome.weight = rand()%(GNOME_MAX_WEIGHT-GNOME_MIN_WEIGHT)+GNOME_MIN_WEIGHT;
  26. genome.strenght = rand()%GNOME_MAX_STRENGHT+1;
  27. genome.life = rand()%(GNOME_MAX_LIFE-GNOME_MIN_LIFE)+GNOME_MIN_LIFE;
  28. genome.speed = rand()%(GNOME_MAX_SPEED-GNOME_MIN_SPEED)+GNOME_MIN_SPEED;
  29. genome.reprofreq = rand()%(GNOME_MAX_REPROFREQ-GNOME_MIN_REPROFREQ)+GNOME_MIN_REPROFREQ;
  30. genome.aggression = rand()%GNOME_MAX_AGGRESSION+1;
  31. genome.perception = rand()%GNOME_MAX_PERCEP;
  32. genome.lifetime = rand()%(GNOME_MAX_LIFETIME-GNOME_MIN_LIFETIME)+GNOME_MIN_LIFETIME;
  33. genome.food = rand()%4;
  34. genome.energy = rand()%GNOME_MAX_ENERGY+1;
  35. genome.nbchild = rand()%(GNOME_MAX_NBCHILD-GNOME_MIN_NBCHILD)+GNOME_MIN_NBCHILD;
  36. genome.mem_capabilities = rand()%8;
  37. genome.mem_type = rand()%3;
  38. genome.mem_size = rand()%GNOME_MAX_MEM_SIZE;
  39. return genome;
  40. }
  41. t_tree_genome* create_new_gnometree_node(t_genome gnome)
  42. {
  43. t_tree_genome *res = malloc(sizeof(t_tree_genome));
  44. if(res == NULL)
  45. {
  46. fprintf(stderr, "Error while allocating memory\n");
  47. exit(-1);
  48. }
  49. res->child = malloc(sizeof(t_tree_genome*));
  50. if(res->child == NULL)
  51. {
  52. fprintf(stderr, "Error while allocating memory\n");
  53. exit(-1);
  54. }
  55. res->child[0] = NULL;
  56. res->parent = NULL;
  57. res->gnome = gnome;
  58. res->nb_child = 0;
  59. return res;
  60. }
  61. t_tree_genome* add_child_treegnome(t_tree_genome* t, t_tree_genome* child)
  62. {
  63. /*t_tree_genome **sav_child = t->child;
  64. int i;
  65. t->child = malloc(sizeof(t_tree_genome*)*(t->nb_child+1));
  66. if(t->child == NULL)
  67. {
  68. fprintf(stderr, "Error while allocating memory\n");
  69. exit(-1);
  70. }
  71. for(i=0;i<t->nb_child;i++)
  72. t->child[i] = sav_child[i];*/
  73. t->child = realloc(t->child, sizeof(t_tree_genome*)*(t->nb_child+1));
  74. if(t->child == NULL)
  75. {
  76. fprintf(stderr, "Error while allocating memory\n");
  77. exit(-1);
  78. }
  79. //t->child[i] = child;
  80. t->child[t->nb_child] = child;
  81. child->parent = t;
  82. //free(sav_child);
  83. t->nb_child++;
  84. return child;
  85. }
  86. t_tree_genome* del_node_treegnome(t_tree_genome* t)
  87. {
  88. if(t->nb_child >0)
  89. return t;
  90. if(t->parent == NULL)
  91. {
  92. free(t);
  93. return NULL;
  94. }
  95. else
  96. {
  97. t_tree_genome *parent = t->parent;
  98. t_tree_genome **sav_child = parent->child;
  99. parent->child = malloc(sizeof(t_tree_genome*)*(parent->nb_child-1));
  100. int i,j=0;
  101. for(i=0;i<parent->nb_child;i++)
  102. {
  103. if(sav_child[i] == t)
  104. {
  105. free(t->child);
  106. free(t);
  107. }
  108. else
  109. {
  110. parent->child[j] = sav_child[i];
  111. j++;
  112. }
  113. }
  114. free(sav_child);
  115. parent->nb_child--;
  116. return parent;
  117. }
  118. }
  119. char calc_proba(int proba)
  120. {
  121. return !(rand()%proba);
  122. }
  123. t_genome mutation(t_genome orig)
  124. {
  125. t_genome genome = orig;
  126. int i=0;
  127. genome.name = rand_name();
  128. genome.nb_creat=0;
  129. genome.nb_nat_dead=0;
  130. genome.nb_star_dead=0;
  131. genome.nb_figt_dead=0;
  132. genome.nb_eat_dead=0;
  133. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  134. genome.weight = (genome.weight += (rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%(GNOME_MAX_WEIGHT-GNOME_MIN_WEIGHT)+GNOME_MIN_WEIGHT);
  135. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  136. genome.strenght = (genome.strenght += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%GNOME_MAX_STRENGHT+1;
  137. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  138. genome.life = (genome.life += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%(GNOME_MAX_LIFE-GNOME_MIN_LIFE)+GNOME_MIN_LIFE;
  139. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  140. genome.speed = (genome.speed += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%(GNOME_MAX_SPEED-GNOME_MIN_SPEED)+GNOME_MIN_SPEED;
  141. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  142. genome.reprofreq = (genome.reprofreq += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%(GNOME_MAX_REPROFREQ-GNOME_MIN_REPROFREQ)+GNOME_MIN_REPROFREQ;
  143. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  144. genome.aggression = (genome.aggression += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%GNOME_MAX_AGGRESSION+1;
  145. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  146. genome.perception = (genome.perception += rand()%(5-1)+1*(rand()%2?-1:1))%GNOME_MAX_PERCEP;
  147. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  148. genome.lifetime = (genome.lifetime += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%(GNOME_MAX_LIFETIME-GNOME_MIN_LIFETIME)+GNOME_MIN_LIFETIME;
  149. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  150. genome.energy = (genome.energy += rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%GNOME_MAX_ENERGY+1;
  151. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  152. genome.food = (genome.food += (rand()%2*(rand()%2?-1:1)))%4;
  153. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  154. genome.nbchild = (genome.nbchild += (rand()%3*(rand()%2?-1:1))%(GNOME_MAX_NBCHILD-GNOME_MIN_NBCHILD))+GNOME_MIN_NBCHILD;
  155. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  156. genome.mem_capabilities = (genome.mem_capabilities += rand()%2*(rand()%2?-1:1))%8;
  157. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  158. genome.mem_type = (genome.mem_type += rand()%2*(rand()%2?-1:1))%3;
  159. if(calc_proba(GNOME_MUTATION_GNOM_MODIF))
  160. genome.mem_size = (genome.mem_size = rand()%(GNOME_MUTATION_MAX-GNOME_MUTATION_MIN)+GNOME_MUTATION_MIN*(rand()%2?-1:1))%GNOME_MAX_MEM_SIZE;
  161. return genome;
  162. }
  163. char rand_char(char type)
  164. {
  165. char res = rand()%('z'-'a')+'a';
  166. while(1)
  167. {
  168. if(res == 'a' || res == 'e' || res == 'i' || res == 'o' || res == 'u' || res == 'y')
  169. {
  170. if(type == 0)
  171. return res;
  172. }
  173. else
  174. {
  175. if(type == 1)
  176. return res;
  177. }
  178. res = rand()%('z'-'a')+'a';
  179. }
  180. }
  181. char* rand_name()
  182. {
  183. int max = rand()%(GNOME_MAX_NAMESIZE-GNOME_MIN_NAMESIZE)+GNOME_MIN_NAMESIZE, type = rand()%2,i;
  184. char *res = malloc(sizeof(char)*(max+1));
  185. for(i=0;i<max;i++)
  186. {
  187. res[i] = rand_char(type);
  188. type = (++type)%2;
  189. }
  190. res[i] = '\0';
  191. return res;
  192. }
  193. void disp_genome_tree_info(t_tree_genome* t, char eq_zero)
  194. {
  195. unsigned long nb_node = 1;
  196. t_tree_genome **visit = (t_tree_genome**)malloc(sizeof(t_tree_genome*)*nb_node), **tmp;
  197. #ifdef DEBUG
  198. if(!visit)
  199. {
  200. fprintf(stderr,"Error in malloc\n");
  201. exit(-1);
  202. }
  203. #endif
  204. visit[0] = t;
  205. unsigned long cur = 0;
  206. unsigned long i = 0;
  207. do
  208. {
  209. if(visit[cur]->gnome.nb_creat>eq_zero)
  210. printf("Gnome : %s | nb_creat : %d | deads : natural = %d, starved = %d, fight = %d, eat = %d\n", visit[cur]->gnome.name, visit[cur]->gnome.nb_creat, visit[cur]->gnome.nb_nat_dead, visit[cur]->gnome.nb_star_dead, visit[cur]->gnome.nb_figt_dead, visit[cur]->gnome.nb_eat_dead);
  211. if(visit[cur]->nb_child>0)
  212. {
  213. //tmp = visit;
  214. visit = realloc(visit,sizeof(t_tree_genome*)*(nb_node+visit[cur]->nb_child));
  215. if(!visit)
  216. {
  217. fprintf(stderr,"Error in realloc\n");
  218. exit(-1);
  219. }
  220. /*for(i=0;i<nb_node;i++)
  221. visit[i] = tmp[i];*/
  222. //free(tmp);
  223. for(i=nb_node;i<nb_node+visit[cur]->nb_child;i++)
  224. {
  225. visit[i] = visit[cur]->child[i-nb_node];
  226. }
  227. nb_node += visit[cur]->nb_child;
  228. }
  229. cur++;
  230. }while(cur<nb_node-1);
  231. }
  232. void clean_treegnome(t_tree_genome* t)
  233. {
  234. int nb_node = 1;
  235. t_tree_genome **visit = (t_tree_genome**)malloc(sizeof(t_tree_genome*)*nb_node), **tmp;
  236. visit[0] = t;
  237. int cur = 0;
  238. t_tree_genome *cur_node = t, *prev = NULL;
  239. int i = 0;
  240. do
  241. {
  242. if(visit[cur]->nb_child>0)
  243. {
  244. //tmp = visit;
  245. visit = realloc(visit, sizeof(t_tree_genome*)*(nb_node+visit[cur]->nb_child));
  246. if(!visit)
  247. {
  248. fprintf(stderr,"Error in realloc\n");
  249. exit(-1);
  250. }
  251. /*for(i=0;i<nb_node;i++)
  252. visit[i] = tmp[i];*/
  253. //free(tmp);
  254. for(i=nb_node;i<nb_node+visit[cur]->nb_child;i++)
  255. {
  256. visit[i] = visit[cur]->child[i-nb_node];
  257. }
  258. nb_node += visit[cur]->nb_child;
  259. }
  260. else if(visit[cur]->gnome.nb_creat<=0 && visit[cur] != t)
  261. {
  262. #ifndef DEBUG
  263. if(visit[cur] != t)
  264. del_node_treegnome(visit[cur]);
  265. #endif
  266. #ifdef DEBUG
  267. if(!del_node_treegnome(visit[cur]))
  268. {
  269. fprintf(stderr, "Bug del treegnome\n");
  270. exit(-1);
  271. }
  272. #endif
  273. }
  274. cur++;
  275. }while(cur<nb_node-1);
  276. }
  277. void write_graphviz_genome_tree(FILE* file, t_tree_genome* t)
  278. {
  279. fprintf(file, "digraph G {\n");
  280. int nb_node = 1;
  281. t_tree_genome **visit = (t_tree_genome**)malloc(sizeof(t_tree_genome*)*nb_node), **tmp;
  282. visit[0] = t;
  283. int cur = 0;
  284. t_tree_genome *cur_node = t, *prev = NULL;
  285. int i = 0;
  286. do
  287. {
  288. if(visit[cur]->nb_child>0)
  289. {
  290. //tmp = visit;
  291. visit = realloc(visit, sizeof(t_tree_genome*)*(nb_node+visit[cur]->nb_child));
  292. /*for(i=0;i<nb_node;i++)
  293. visit[i] = tmp[i];
  294. free(tmp);*/
  295. for(i=nb_node;i<nb_node+visit[cur]->nb_child;i++)
  296. {
  297. visit[i] = visit[cur]->child[i-nb_node];
  298. if(visit[i]->nb_child>0)
  299. {
  300. fprintf(file, "\t\"%s(%d)\" [fontcolor=%s];\n",visit[cur]->gnome.name,visit[cur]->gnome.nb_creat,(visit[cur]->gnome.food & GNOME_VEGAN?(visit[cur]->gnome.food & GNOME_CARNI?"purple":"green"):"red"));
  301. fprintf(file, "\t\"%s(%d)\" [fontcolor=%s];\n",visit[cur]->child[i-nb_node]->gnome.name,visit[cur]->child[i-nb_node]->gnome.nb_creat,(visit[cur]->child[i-nb_node]->gnome.food & GNOME_VEGAN?(visit[cur]->child[i-nb_node]->gnome.food & GNOME_CARNI?"purple":"green"):"red"));
  302. fprintf(file, "\t\"%s(%d)\" -> \"%s(%d)\"\n", visit[cur]->gnome.name,visit[cur]->gnome.nb_creat, visit[cur]->child[i-nb_node]->gnome.name,visit[cur]->child[i-nb_node]->gnome.nb_creat);
  303. }
  304. }
  305. nb_node += visit[cur]->nb_child;
  306. }
  307. cur++;
  308. }while(cur<nb_node-1);
  309. fprintf(file, "}\n");
  310. }