int bfs(const vector<vector<int>> &grid, const int r, const int c) { bool visited[128][128]; memset(visited, 0, sizeof(visited)); point_t q[128*128]; int q_beg = 0, q_end = 1; q[0] = point_t(r, c); visited[r][c] = true; const int roffs[] = { -1, 0, 1, 0 }; const int coffs[] = { 0, 1, 0, -1 }; int cnt = 0; while (q_beg != q_end) { point_t pnt = q[q_beg++]; for (int i = 0; i < 4; i++) { int roff = roffs[i]; int coff = coffs[i]; int newr = pnt.first + roff; int newc = pnt.second + coff; if (!is_land(grid, newr, newc)) { cnt++; } else { if (visited[newr][newc]) continue; visited[newr][newc] = true; q[q_end++] = point_t(newr, newc); } } } return cnt; }
void _iterate_humidity (const Planet& planet, const Climate_parameters& par, Climate_generation_season& season) { std::deque<float> humidity; std::deque<float> precipitation; humidity.resize(tile_count(planet)); precipitation.resize(tile_count(planet)); float delta = 1.0; while (delta > par.error_tolerance) { // std::cout << "delta: " << delta << "\n"; for (int i=0; i<tile_count(planet); i++) { precipitation[i] = 0.0; if (is_land(nth_tile(terrain(planet), i))) { humidity[i] = 0.0; precipitation[i] = 0.0; float incoming_wind = _incoming_wind(planet, season, i); float outgoing_wind = _outgoing_wind(planet, season, i); if (incoming_wind > 0.0) { float convection = outgoing_wind - incoming_wind; float incoming_humidity = _incoming_humidity(planet, season, i); // less humidity when incoming wind is less than outgoing float density = convection > 0 ? incoming_humidity / (incoming_wind + convection) : incoming_humidity / incoming_wind; float saturation = saturation_humidity(season.tiles[i].temperature); // limit to saturation humidity humidity[i] = std::min(saturation, density); if (saturation < density) precipitation[i] += (density - saturation) * incoming_wind; // increase humidity when outgoing wind is less than incoming if (convection < 0) { float convective = humidity[i] * (-convection / incoming_wind); if (humidity[i] + convective > saturation) precipitation[i] += (humidity[i] + convective - saturation) * (-convection); humidity[i] = std::min(saturation, humidity[i] + convective); } } // scale by constant and area precipitation[i] *= 3.0 / area(planet, nth_tile(planet, i)); } else humidity[i] = season.tiles[i].humidity; } float largest_change = 0.0; for (int i=0; i<tile_count(planet); i++) { largest_change = std::max(largest_change, _humidity_change(season.tiles[i].humidity, humidity[i])); } delta = largest_change; for (int i=0; i<tile_count(planet); i++) { season.tiles[i].humidity = humidity[i]; season.tiles[i].precipitation = precipitation[i]; } } }
void _set_temperature (const Planet& planet, const Climate_parameters&, Climate_generation_season& season) { auto temperature_at_latitude = [](float latitude) { return freezing_point() - 25 + 50*cos(latitude); }; for (auto& t : tiles(planet)) { float temperature = temperature_at_latitude(season.tropical_equator - latitude(planet, vector(t))); if (is_land(nth_tile(terrain(planet), id(t)))) { if (elevation(nth_tile(terrain(planet), id(t))) > sea_level(planet)) temperature -= temperature_lapse(elevation(nth_tile(terrain(planet), id(t))) - sea_level(planet)); } else { temperature = 0.3*temperature + 0.7*temperature_at_latitude(latitude(planet, vector(t))); } season.tiles[id(t)].temperature = temperature; } }
Wind _default_wind (const Planet& p, int i, double tropical_equator) { Vector2 pressure_force = _default_pressure_gradient_force(tropical_equator, latitude(p, vector(nth_tile(p,i)))); double coriolis_coeff = coriolis_coefficient(p, latitude(p, vector(nth_tile(p,i)))); double friction = is_land(nth_tile(terrain(p), i)) ? 0.000045 : 0.000045; return _prevailing_wind(pressure_force, coriolis_coeff, friction); }