void veta_symbolsloaded(symbol *symbols,int n){ if(n==0) return; symbolsloaded++; uk_log("Symbols are loaded got %i symbols",n); conf_save_symbols("platform_symbols.json",symbols,n); int cellsize=conf_get_int("n_columns",CELLS_W)*conf_get_int("n_rows",CELLS_H); root_cell=create_cells(symbols,n,cellsize,TREE_DEPTH,1); clear_selection(root_cell); }
ih_box_system_t *ih_box_system_create (ih_box_coordinate_t *dimension_coordinate, ih_box_object_get_cell_f get_cell, ih_box_object_set_cell_f set_cell, ih_core_compare_f compare_objects, ih_core_copy_f copy_object, ih_core_destroy_f destroy_object, ih_audit_log_t *log) { assert(dimension_coordinate); assert(dimension_coordinate->x >= 1); assert(dimension_coordinate->y >= 1); assert(dimension_coordinate->z >= 1); assert(get_cell); assert(set_cell); assert(compare_objects); assert(copy_object); assert(log); ih_box_system_t *system; ih_core_bool_t so_far_so_good; system = malloc(sizeof *system); if (system) { ih_box_coordinate_copy(&system->dimension_coordinate, dimension_coordinate); system->get_cell = get_cell; system->set_cell = set_cell; system->destroy_object = destroy_object; system->log = log; system->volume = dimension_coordinate->x * dimension_coordinate->y * dimension_coordinate->z; if (create_cells(system)) { so_far_so_good = ih_core_bool_true; set_neighbor_references(system); } else { so_far_so_good = ih_core_bool_false; ih_audit_log_trace(log, "box", "create_cells"); } } else { so_far_so_good = ih_core_bool_false; ih_core_trace("malloc"); } if (!so_far_so_good && system) { if (system->cells) { ih_container_array_destroy(system->cells); } free(system); system = NULL; } return system; }
/* all this is rather expensive :( */ static void tick( State *st ) { int new_num_cells, num_cells=0; int b, j; int x, y, w4=st->width/4, h4=st->height/4, offset; double min_dist; int min_index; int num_living = 0; const double check_dist = 0.75*st->move_dist; const double grow_dist = 0.75*st->radius; const double adult_radius = st->radius; /* find number of cells capable of division and count living cells */ for (b=0; b<st->num_cells; ++b) { if (st->cell[b].energy > 0) num_living++; if (can_divide( st, &st->cell[b] )) num_cells++; } new_num_cells = st->num_cells + num_cells; /* end of simulation ? */ if (0 == num_living || new_num_cells >= st->max_cells) { if (st->pause_counter > 0) st->pause_counter--; if (st->pause_counter > 0) return; create_cells( st ); st->pause_counter = st->pause; } else if (num_cells) { /* any fertile candidates ? */ for (b=0, j=st->num_cells; b<st->num_cells; ++b) { if (can_divide( st, &st->cell[b] )) { st->cell[b].vx = random_interval( -50, 50 ) * 0.01; st->cell[b].vy = random_interval( -50, 50 ) * 0.01; st->cell[b].age = random_max( 0x0f ); /* half energy for both plus some bonus for forking */ st->cell[b].energy = st->cell[b].energy/2 + random_max( 0x0f ); /* forking makes me shrink */ st->cell[b].growth = 0.995; /* this one initially goes into the oposite direction */ st->cell[j].vx = -st->cell[b].vx; st->cell[j].vy = -st->cell[b].vy; /* same center */ st->cell[j].x = st->cell[b].x; st->cell[j].y = st->cell[b].y; st->cell[j].age = random_max( 0x0f ); st->cell[j].energy = (st->cell[b].energy); st->cell[j].rotation = ((double)random()/(double)RAND_MAX)*360.0; st->cell[j].growth = st->cell[b].growth; st->cell[j].radius = st->cell[b].radius; ++j; } else { st->cell[b].vx = 0.0; st->cell[b].vy = 0.0; } } st->num_cells = new_num_cells; } /* for each find a direction to escape */ if (st->num_cells > 1) { for (b=0; b<st->num_cells; ++b) { if (st->cell[b].energy > 0) { double vx; double vy; double len; /* grow or shrink */ st->cell[b].radius *= st->cell[b].growth; /* find closest neighbour */ min_dist = 100000.0; min_index = 0; for (j=0; j<st->num_cells; ++j) { if (j!=b) { const double dx = st->cell[b].x - st->cell[j].x; const double dy = st->cell[b].y - st->cell[j].y; if (fabs(dx) < check_dist || fabs(dy) < check_dist) { const double dist = dx*dx+dy*dy; /*const double dist = sqrt( dx*dx+dy*dy );*/ if (dist<min_dist) { min_dist = dist; min_index = j; } } } } /* escape step is away from closest normalized with distance */ vx = st->cell[b].x - st->cell[min_index].x; vy = st->cell[b].y - st->cell[min_index].y; len = sqrt( vx*vx + vy*vy ); if (len > 0.0001) { st->cell[b].vx = vx/len; st->cell[b].vy = vy/len; } st->cell[b].min_dist = len; /* if not adult (radius too small) */ if (st->cell[b].radius < adult_radius) { /* if too small 60% stop shrinking */ if (st->cell[b].radius < adult_radius * 0.6) { st->cell[b].growth = 1.0; } /* at safe distance we start growing again */ if (len > grow_dist) { if (st->cell[b].energy > 30) { st->cell[b].growth = 1.005; } } } else { /* else keep size */ st->cell[b].growth = 1.0; } } } } else { st->cell[0].min_dist = 2*st->move_dist; } /* now move em, snack and burn energy */ for (b=0; b<st->num_cells; ++b) { /* if still alive */ if (st->cell[b].energy > 0) { /* agility depends on amount of energy */ double fac = (double)st->cell[b].energy / 50.0; if (fac < 0.0) fac = 0.0; if (fac > 1.0) fac = 1.0; st->cell[b].x += fac*(2.0 - (4.0*(double)random() / (double)RAND_MAX) + st->cell[b].vx); st->cell[b].y += fac*(2.0 - (4.0*(double)random() / (double)RAND_MAX) + st->cell[b].vy); /* get older and burn energy */ if (st->cell[b].energy > 0) { st->cell[b].age++; st->cell[b].energy--; } /* have a snack */ x = ((int)st->cell[b].x)/4; if (x<0) x=0; if (x>=w4) x = w4-1; y = ((int)st->cell[b].y)/4; if (y<0) y=0; if (y>=h4) y = h4-1; offset = x+y*w4; /* don't eat if already satisfied */ if (st->cell[b].energy < 100 && st->food[offset] > 0) { st->food[offset]--; st->cell[b].energy++; /* if you are hungry, eat more */ if (st->cell[b].energy < 50 && st->food[offset] > 0) { st->food[offset]--; st->cell[b].energy++; } } } } }