X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fantithread%2Fexamples%2Farabella.c;h=47aca2ef20562c610b6311e43ff1dc31417b7f47;hp=2171dc12673fbbeea53fada0bd7c79748cf70e37;hb=48b700953f9c856102e91596103238f5da9ea079;hpb=d65da2dbb4c43bd7c0e83e299b374acd6bff54f9 diff --git a/ccan/antithread/examples/arabella.c b/ccan/antithread/examples/arabella.c index 2171dc12..47aca2ef 100644 --- a/ccan/antithread/examples/arabella.c +++ b/ccan/antithread/examples/arabella.c @@ -311,18 +311,30 @@ static struct drawing *new_drawing(const void *ctx, unsigned int num_tris) 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); } @@ -365,7 +377,7 @@ static struct drawing *breed_drawing(const void *ctx, /* 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; @@ -485,12 +497,13 @@ static struct drawing *random_drawing(const void *ctx, /* 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++) { @@ -523,7 +536,8 @@ static int compare_drawing_scores(const void *_a, const void *_b) } /* 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; @@ -534,15 +548,16 @@ static void dump_drawings(struct drawing **drawing, const char *outname) 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], @@ -567,7 +582,7 @@ static void dump_state(struct drawing *drawing[POPULATION_SIZE], 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); @@ -628,19 +643,21 @@ int main(int argc, char *argv[]) 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); } @@ -663,7 +680,7 @@ int main(int argc, char *argv[]) /* 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]; @@ -712,6 +729,7 @@ int main(int argc, char *argv[]) if (gen == 100) exit(0); #endif + gen++; } /* Dump final state */