static void mutate_drawing(struct drawing *drawing,
const struct image *master)
{
- unsigned int r = random();
+ unsigned int i, r = random();
struct triangle *tri = &drawing->tri[r % drawing->num_tris];
r /= drawing->num_tris;
- r %= 10;
+ r %= 12;
if (r < 6) {
+ /* Move one corner in x or y dir. */
if (r % 2)
tri->coord[r/2].x = random() % master->width;
else
tri->coord[r/2].y = random() % master->height;
- } else {
+ } else if (r < 10) {
+ /* Change one aspect of color. */
tri->color[r - 6] = random() % 256;
+ } else if (r == 10) {
+ /* Completely move a triangle. */
+ for (i = 0; i < 3; i++) {
+ tri->coord[i].x = random() % master->width;
+ tri->coord[i].y = random() % master->height;
+ }
+ } else {
+ /* Completely change a triangle's colour. */
+ for (i = 0; i < 4; i++)
+ tri->color[i] = random() % 256;
}
calc_multipliers(tri);
}
/* This is our anti-thread. It does the time-consuming operation of
* breeding two drawings together and scoring the result. */
-static void *breeder(struct at_pool *atp, const struct image *master)
+static void *breeder(struct at_pool *atp, struct image *master)
{
const struct drawing *a, *b;
/* Read in a drawing from the saved state file. */
static struct drawing *read_drawing(const void *ctx, FILE *in,
- const struct image *master)
+ const struct image *master,
+ unsigned int *generation)
{
struct drawing *drawing;
unsigned int i;
- if (fscanf(in, "%u triangles:\n", &i) != 1)
+ if (fscanf(in, "%u triangles, generation %u:\n", &i, generation) != 2)
errx(1, "Reading saved state");
drawing = new_drawing(ctx, i);
for (i = 0; i < drawing->num_tris; i++) {
}
/* Save one drawing to state file */
-static void dump_drawings(struct drawing **drawing, const char *outname)
+static void dump_drawings(struct drawing **drawing, const char *outname,
+ unsigned int generation)
{
FILE *out;
unsigned int i, j;
err(1, "Opening %s", tmpout);
fprintf(out, "POPULATION_SIZE=%u\n", POPULATION_SIZE);
for (i = 0; i < POPULATION_SIZE; i++) {
- fprintf(out, "%u triangles:\n", drawing[i]->num_tris);
+ fprintf(out, "%u triangles, generation %u:\n",
+ drawing[i]->num_tris, generation);
for (j = 0; j < drawing[i]->num_tris; j++) {
fprintf(out, "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
- drawing[i]->tri[i].coord[0].x,
- drawing[i]->tri[i].coord[0].y,
- drawing[i]->tri[i].coord[1].x,
- drawing[i]->tri[i].coord[1].y,
- drawing[i]->tri[i].coord[2].x,
- drawing[i]->tri[i].coord[2].y,
+ drawing[i]->tri[j].coord[0].x,
+ drawing[i]->tri[j].coord[0].y,
+ drawing[i]->tri[j].coord[1].x,
+ drawing[i]->tri[j].coord[1].y,
+ drawing[i]->tri[j].coord[2].x,
+ drawing[i]->tri[j].coord[2].y,
drawing[i]->tri[j].color[0],
drawing[i]->tri[j].color[1],
drawing[i]->tri[j].color[2],
char *out = talloc_asprintf(NULL, "%s.%08u.jpg", outpic, gen);
struct image *image;
printf("Dumping gen %u to %s & %s\n", gen, out, outstate);
- dump_drawings(drawing, outstate);
+ dump_drawings(drawing, outstate, gen);
image = image_of_drawing(out, drawing[0], master);
write_jpeg_file(image, out, 80);
talloc_free(out);
fflush(stdout);
}
printf("\n");
+ gen = 0;
} else {
FILE *state;
char header[100];
- state = fopen(argv[5], "r");
+ state = fopen(argv[6], "r");
if (!state)
- err(1, "Opening %s", argv[5]);
+ err(1, "Opening %s", argv[6]);
fflush(stdout);
fgets(header, 100, state);
- printf("Loading initial population from %s: %s", argv[5],
+ printf("Loading initial population from %s: %s", argv[6],
header);
for (i = 0; i < POPULATION_SIZE; i++) {
drawing[i] = read_drawing(at_pool_ctx(atp),
- state, master);
+ state, master, &gen);
+ gen++; /* We start working on the _next_ gen */
printf(".");
fflush(stdout);
}
/* Worse than theoretically worst case. */
prev_best = master->height * master->stride * 256;
- for (gen = 0; since_prev_best < PLATEAU_GENS; gen++) {
+ while (since_prev_best < PLATEAU_GENS) {
unsigned int j, done = 0;
struct drawing *new[POPULATION_SIZE/4];
if (gen == 100)
exit(0);
#endif
+ gen++;
}
/* Dump final state */