#include #include #include #include #include static const int colortab[][3] = { { 0, 0, 0 }, { 0, 0, 255 }, { 0, 255, 0 }, { 0, 255, 255 }, { 255, 0, 0 }, { 255, 0, 255 }, { 255, 255, 0 }, { 255, 255, 255 }, { 0, 0, 128, }, { 0, 128, 0, }, { 0, 128, 128, }, { 0, 128, 255, }, { 0, 255, 128, }, { 128, 0, 0, }, { 128, 0, 128, }, { 128, 0, 255, }, { 128, 128, 0, }, { 128, 128, 128, }, { 128, 255, 0, }, { 128, 255, 128, }, { 128, 255, 255, }, { 255, 0, 128, }, { 255, 128, 0, }, { 255, 128, 128, }, { 255, 255, 128, }, }; #define MAXCOLORS (sizeof colortab / sizeof colortab[0]) static int width = 256, height = 256, colors = MAXCOLORS, npixels, seeds = 1; static int *map; #define pixel(x,y) map[height * (y) + (x)] static inline int stop(int x, int y) { int c; if(x > 0 && (c = pixel(x - 1, y))) return c; if(x < width - 1 && (c = pixel(x + 1, y))) return c; if(y > 0 && (c = pixel(x, y - 1))) return c; if(y < height - 1 && (c = pixel(x, y + 1))) return c; return 0; } static void xprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); if(vprintf(fmt, ap) < 0) { perror("ERROR: writing to stdout"); exit(1); } va_end(ap); } static void xputchar(int c) { if(putchar(c) < 0) { perror("ERROR: writing to stdout"); exit(1); } } int main(int argc, char **argv) { int c, n, x, y, maxnpixels; while((n = getopt(argc, argv, "w:h:c:s:p:")) >= 0) { switch(n) { case 'w': width = atoi(optarg); break; case 'h': height = atoi(optarg); break; case 'c': colors = atoi(optarg); break; case 's': seeds = atoi(optarg); break; case 'p': npixels = atoi(optarg); break; default: exit(1); } } if((unsigned)colors > MAXCOLORS) { fprintf(stderr, "ERROR: too many colors\n"); exit(1); } if(!(map = calloc(width * height, sizeof (int)))) { perror("ERROR: calloc"); exit(1); } if(!npixels) npixels = width * height / 2; maxnpixels = npixels; srand48((long)time(0)); for(n = 0; n < seeds; ++n) { for(c = 1; c < colors; ++c) { /* pick a random unoccupied non-edge pixel */ do { x = drand48() * (width - 2) + 1; y = drand48() * (height - 2) + 1; } while(pixel(x,y)); pixel(x, y) = c; --npixels; } } while(npixels > 0) { if(npixels % 1024 == 0) fprintf(stderr, "\r[%d%%]", 100 - 100 * npixels / maxnpixels); /* pick a random unoccupied pixel */ do { x = drand48() * width; y = drand48() * height; } while(pixel(x, y)); /* wander about until we bump into an existing pixel */ while(!(c = stop(x, y))) { for(;;) { switch((int)(drand48() * 4)) { case 0: if(x == 0) continue; else --x; break; case 1: if(x == width - 1) continue; else ++x; break; case 2: if(y == 0) continue; else --y; break; case 3: if(y == height - 1) continue; else ++y; break; default: assert("!reached"); } break; } } pixel(x, y) = c; --npixels; } fprintf(stderr, "\r \r"); xprintf("P6\n%d %d %d\n", width, height, 255); for(y = 0; y < height; ++y) { for(x = 0; x < width; ++x) { n = pixel(x, y); xputchar(colortab[n][0]); xputchar(colortab[n][1]); xputchar(colortab[n][2]); } } return 0; }