void add_grain_on_random_square (int radius, int seed) { TRACEINW("(radius=%d seed=%d)", radius, seed); srandom(seed); int random_x = random_number_in_range(-radius, radius); int random_y = random_number_in_range(-radius, radius); TRACEMESS("Add 1 grain on (%d,%d)", random_x, random_y); add_grains_on_square(random_x, random_y, 1); TRACEOUT; }
/* ADD_GRAINS_ON_SQUARE modifies the board by adding DELTA (can be 0) on X,Y. Maintains counts. No collapse. New val ≥ 4 are stacked in waiting list (no checking if new val ≠ prev val) Prev val ≥ 4 are assumed to have been unstacked by caller */ void add_grains_on_square (int x, int y, int delta) { TRACEINW("(x=%d, y=%d, delta=%d)", x, y, delta); // dump_waitinglist(stdout, true); if ((x < xmin) || (x > xmax) || (y < ymin) || (y > ymax)) { TRACEMESS ("have to enlarge"); enlarge_envelop_for (x,y); } int * p = cboard + x*ydim + y; int val = *p; assert ((val + delta >= 0) || (val == UNUSEDSQ)); switch (val) {//update count case 0: assert(count0 > 0); count0--; break; case 1: assert(count1 > 0); count1--; break; case 2: assert(count2 > 0); count2--; break; case 3: assert(count3 > 0); count3--; break; case UNUSEDSQ: val=0; area++; break; /* needs real val in later computation */ default: assert(val>3); /* do nothing */ } mass += delta; val += delta; *p = val; switch (val) { case 0: assert(count0 < INT_MAX); count0++; break; case 1: assert(count1 < INT_MAX); count1++; break; case 2: assert(count2 < INT_MAX); count2++; break; case 3: assert(count3 < INT_MAX); count3++; break; default: assert(val>3); /* only stackin when val goes 3->4, 7->8, ... Other options are 5->6, 8->4 etc. */ if ((val%4 == 0) && (delta == 1)) stackin_waiting(x,y); break; } #ifdef TRACE if ((terminal_mode != false) && (anim_level >= 2)) dump_waitinglist(stdout, false); #endif /* TRACE */ TRACEOUT; }