resp step(city_st *cty) { uint16_t died = 0; died += starvation(cty); if (died > cty->population * 0.45) return ESTARVE; cty->avg_starved = 0.1*died + 0.9*cty->avg_starved; // EMA if (RAND(15) == 0) died += plague(cty); cty->tot_died += died; cty->population += births(cty); cty->migrated = 0.1*RAND(cty->population); cty->trade_val = 17+RAND(10); cty->yield = RAND(10)+1; cty->bushels += cty->yield*cty->planted; rats(cty); return OKAY; }
// This customized version carves holes defined by the regions. // It'll remove any element which doesn't receive any region. int custom_carveholes(struct mesh *m, struct behavior *b, const int *outside, const int *inside) { struct otri neighbortri; struct otri triangleloop; struct osub subsegloop; triangle **temptri; triangle ptr; /* Temporary variable used by sym(). */ double area; double attribute; double triangle_attribute; int sane_mesh; poolinit(& m->viri, sizeof( triangle * ), VIRUSPERBLOCK, VIRUSPERBLOCK, 0); /* Assigns every triangle a regional attribute of -1 */ traversalinit(& m->triangles); triangleloop.orient = 0; triangleloop.tri = triangletraverse(m); while ( triangleloop.tri != ( triangle * ) NULL ) { setelemattribute(triangleloop, m->eextras, -1.0); triangleloop.tri = triangletraverse(m); } sane_mesh = 1; /* Loop over all segments */ traversalinit(& m->subsegs); subsegloop.ss = subsegtraverse(m); subsegloop.ssorient = 0; while ( subsegloop.ss != ( subseg * ) NULL ) { if ( subsegloop.ss != m->dummysub ) { /* First neighbor. */ ssymself(subsegloop); stpivot(subsegloop, neighbortri); if ( neighbortri.tri != m->dummytri ) { area = 0.0; /// @todo Possible set this as the minimum as well. attribute = outside [ mark(subsegloop) - 1 ]; triangle_attribute = elemattribute(neighbortri, m->eextras); /* The region no number yet. */ if ( triangle_attribute < 0 && attribute >= 0 ) { infect(neighbortri); temptri = ( triangle ** ) poolalloc(& m->viri); * temptri = neighbortri.tri; /* Apply one region's attribute and/or area constraint. */ regionplague(m, b, attribute, area); /* The virus pool should be empty now. */ } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) { /* Check for problems. */ vertex v1, v2, v3; org(neighbortri, v1); dest(neighbortri, v2); apex(neighbortri, v3); fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (outside) at (%e, %e)\n", ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3); sane_mesh = 0; } } /* Second neighbor (same procedure). */ ssymself(subsegloop); stpivot(subsegloop, neighbortri); if ( neighbortri.tri != m->dummytri ) { area = 0.0; attribute = inside [ mark(subsegloop) - 1 ]; triangle_attribute = elemattribute(neighbortri, m->eextras); if ( triangle_attribute < 0 && attribute >= 0 ) { infect(neighbortri); temptri = ( triangle ** ) poolalloc(& m->viri); * temptri = neighbortri.tri; regionplague(m, b, attribute, area); } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) { vertex v1, v2, v3; org(neighbortri, v1); dest(neighbortri, v2); apex(neighbortri, v3); fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (inside) at (%e, %e)\n", ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3); sane_mesh = 0; } } subsegloop.ss = subsegtraverse(m); } } /* Remove all triangles with marker 0.0 */ traversalinit(& m->triangles); triangleloop.tri = triangletraverse(m); int triangle_number = 0; while ( triangleloop.tri != ( triangle * ) NULL ) { if ( triangleloop.tri != m->dummytri ) { triangle_number++; attribute = elemattribute(triangleloop, m->eextras); if ( attribute == -1.0 ) { fprintf(stderr, "Broken mesh at triangle %d\n", triangle_number); sane_mesh = 0; } else if ( attribute == 0.0 ) { infect(triangleloop); temptri = ( triangle ** ) poolalloc(& m->viri); * temptri = triangleloop.tri; } } triangleloop.tri = triangletraverse(m); } /* Remove the marked elements */ plague(m, b); if ( b->regionattrib && !b->refine ) { /* Note the fact that each triangle has an additional attribute. */ m->eextras++; } /* Free up memory. */ pooldeinit(& m->viri); return sane_mesh; }