static PyObject *player_number(PyObject *self, PyObject *args){ PyObject *window; PyObject *image; int tolerance; if (!PyArg_ParseTuple(args, "OOi", &window, &image, &tolerance)){ return NULL; } int w_shape[2]; int i_shape[2]; PyObject *w_shape_obj = PyObject_GetAttrString(window, "shape"); PyObject *i_shape_obj = PyObject_GetAttrString(image, "shape"); PyArg_ParseTuple(w_shape_obj, "ii", &w_shape[0], &w_shape[1]); PyArg_ParseTuple(i_shape_obj, "ii", &i_shape[0], &i_shape[1]); Py_DECREF(w_shape_obj); Py_DECREF(i_shape_obj); int i = 0; int j = 0; int players = 0; while (i <= (w_shape[0] - i_shape[0])){ j = 0; while (j <= (w_shape[1] - i_shape[1])){ if (image_match(window, image, i, j, i_shape[0], i_shape[1], tolerance) == 1){ j = j + i_shape[1]; players++; }; j++; }; i++; }; return Py_BuildValue("i", players); }
void display() { if(!done && image_match(best_image, base_image)) { done = 1; } if(!paused && !done && generations < MAX_GENS) { float r; double accum_fitness = 0; fprintf(stderr, "evolving..."); // current best is start of sorted list t_image** new_pop = s_malloc(population_size * sizeof(t_image*)); // always add the best solution to survivors new_pop[0] = image_copy(best_image); // get more survivors using roulette wheel selection for(int i = 1; i < pop_select; i++) { r = rand_float(); for(int j = 0; j < population_size; j++) { accum_fitness += image_fitness(population[j]); if(accum_fitness >= r) { new_pop[i] = image_copy(population[j]); break; } } accum_fitness = 0; } // get a normalised fitness distribution for the survivors double survivor_fit[pop_select]; double survivor_sum_fit = 0; for(int i = 0; i < pop_select; i++) { survivor_fit[i] = image_fitness(new_pop[i]); survivor_sum_fit += survivor_fit[i]; } for(int i = 0; i < pop_select; i++) { survivor_fit[i] /= survivor_sum_fit; } // fill rest of population with children int i = pop_select; while(i < population_size) { // 2 random parents from survivors t_image* parents[N_PARENTS] = {0}; for(int j = 0; j < N_PARENTS; j++) { r = rand_float(); for(int k = 0; k < pop_select; k++) { accum_fitness += survivor_fit[k]; if(accum_fitness >= r) { parents[j] = new_pop[k]; break; } } accum_fitness = 0; } int p = 0; t_image* children[N_CHILDREN] = {0}; // seed children with parent data for(int c = 0; c < N_CHILDREN; c++) { children[c] = image_copy(parents[p]); /* NOTE: can get away with this instead of mod as parents is 2, but if we were to use more have to change it */ p = !p; } for(int x = 0; x < base_image->width; x++) { for(int y = 0; y < base_image->height; y++) { // crossover for(int c = 0; c < N_CHILDREN; c++) { /* // use 3 bits of c to get the 8 combinations for crossover p = (c & (1 << 0)) ? 1 : 0; children[c]->pix[x][y].r = parents[p]->pix[x][y].r; p = (c & (1 << 1)) ? 1 : 0; children[c]->pix[x][y].g = parents[p]->pix[x][y].g; p = (c & (1 << 2)) ? 1 : 0; children[c]->pix[x][y].b = parents[p]->pix[x][y].b; */ average_rgb(x, y, parents, children[c]); } // mutation for(int c = 0; c < N_CHILDREN; c++) { if(rand_float() <= MUTATION_RATE) mutate_rgb(&children[c]->pix[x][y]); } } } // add to new population for(int c = 0; c < N_CHILDREN; c++) { // this child is 'born' if(i < population_size && rand_float() <= CROSSOVER_RATE) { new_pop[i++] = children[c]; // you are dead to me! } else { free_image(children[c]); } } } // deallocate last generation for(int i = 0; i < population_size; i++) { free_image(population[i]); } free(population); // set new population as current population = new_pop; // determine new best member and compare to old best qsort(population, population_size, sizeof(t_image*), image_fitness_cmp); double current_fit = image_fitness(population[0]); if(current_fit < last_best) { free_image(best_image); best_image = image_copy(population[0]); last_best = current_fit; } generations++; fprintf(stderr, "done | gen %d | f %.1f\n", generations, current_fit); } // draw the best image glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, base_image->width, base_image->height, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glBegin(GL_POINTS); for(int x = 0; x < best_image->width; x++) { for(int y = 0; y < best_image->height; y++) { glColor3f(best_image->pix[x][y].r/255.0, best_image->pix[x][y].g/255.0, best_image->pix[x][y].b/255.0); glVertex2f(x + 0.5f, y + 0.5f); } } glEnd(); glutSwapBuffers(); }