/** * Finds the minimum successor cell. * * @param Map::Cell* root * @return <Map::Cell*,double> successor */ pair<Map::Cell*,double> Planner::_min_succ(Map::Cell* u) { Map::Cell** nbrs = u->nbrs(); double tmp_cost, tmp_g; Map::Cell* min_cell = NULL; double min_cost = Math::INF; for (unsigned int i = 0; i < Map::Cell::NUM_NBRS; i++) { if (nbrs[i] != NULL) { tmp_cost = _cost(u, nbrs[i]); tmp_g = _g(nbrs[i]); if (tmp_cost == Math::INF || tmp_g == Math::INF) continue; tmp_cost += tmp_g; if (tmp_cost < min_cost) { min_cell = nbrs[i]; min_cost = tmp_cost; } } } return pair<Map::Cell*,double>(min_cell, min_cost); }
/** * Update map. * * @param Map::Cell* cell to update * @param double new cost of the cell * @return void */ void Planner::update(Map::Cell* u, double cost) { if (u == _goal) return; // Update km _km += _h(_last, _start); _last = _start; _cell(u); double cost_old = u->cost; double cost_new = cost; u->cost = cost; Map::Cell** nbrs = u->nbrs(); double tmp_cost_old, tmp_cost_new; double tmp_rhs, tmp_g; // Update u for (unsigned int i = 0; i < Map::Cell::NUM_NBRS; i++) { if (nbrs[i] != NULL) { u->cost = cost_old; tmp_cost_old = _cost(u, nbrs[i]); u->cost = cost_new; tmp_cost_new = _cost(u, nbrs[i]); tmp_rhs = _rhs(u); tmp_g = _g(nbrs[i]); if (Math::greater(tmp_cost_old, tmp_cost_new)) { if (u != _goal) { _rhs(u, min(tmp_rhs, (tmp_cost_new + tmp_g))); } } else if (Math::equals(tmp_rhs, (tmp_cost_old + tmp_g))) { if (u != _goal) { _rhs(u, _min_succ(u).second); } } } } _update(u); // Update neighbors for (unsigned int i = 0; i < Map::Cell::NUM_NBRS; i++) { if (nbrs[i] != NULL) { u->cost = cost_old; tmp_cost_old = _cost(u, nbrs[i]); u->cost = cost_new; tmp_cost_new = _cost(u, nbrs[i]); tmp_rhs = _rhs(nbrs[i]); tmp_g = _g(u); if (Math::greater(tmp_cost_old, tmp_cost_new)) { if (nbrs[i] != _goal) { _rhs(nbrs[i], min(tmp_rhs, (tmp_cost_new + tmp_g))); } } else if (Math::equals(tmp_rhs, (tmp_cost_old + tmp_g))) { if (nbrs[i] != _goal) { _rhs(nbrs[i], _min_succ(nbrs[i]).second); } } _update(nbrs[i]); } } }
/** * Computes shortest path. * * @return bool successful */ bool Planner::_compute() { if (_open_list.empty()) return false; KeyCompare key_compare; int attempts = 0; Map::Cell* u; pair<double,double> k_old; pair<double,double> k_new; Map::Cell** nbrs; double g_old; double tmp_g, tmp_rhs; while (( ! _open_list.empty() && key_compare(_open_list.begin()->first, _k(_start))) || ! Math::equals(_rhs(_start), _g(_start))) { // Reached max steps, quit if (++attempts > Planner::MAX_STEPS) return false; u = _open_list.begin()->second; k_old = _open_list.begin()->first; k_new = _k(u); tmp_rhs = _rhs(u); tmp_g = _g(u); if (key_compare(k_old, k_new)) { _list_update(u, k_new); } else if (Math::greater(tmp_g, tmp_rhs)) { _g(u, tmp_rhs); tmp_g = tmp_rhs; _list_remove(u); nbrs = u->nbrs(); for (unsigned int i = 0; i < Map::Cell::NUM_NBRS; i++) { if (nbrs[i] != NULL) { if (nbrs[i] != _goal) { _rhs(nbrs[i], min(_rhs(nbrs[i]), _cost(nbrs[i], u) + tmp_g)); } _update(nbrs[i]); } } } else { g_old = tmp_g; _g(u, Math::INF); // Perform action for u if (u != _goal) { _rhs(u, _min_succ(u).second); } _update(u); nbrs = u->nbrs(); // Perform action for neighbors for (unsigned int i = 0; i < Map::Cell::NUM_NBRS; i++) { if (nbrs[i] != NULL) { if (Math::equals(_rhs(nbrs[i]), (_cost(nbrs[i], u) + g_old))) { if (nbrs[i] != _goal) { _rhs(nbrs[i], _min_succ(nbrs[i]).second); } } _update(nbrs[i]); } } } } return true; }
void init_building_data() { for (int i = 0; i < BUILD_MAX; i++) { Building_data[i] = new Building_datum; Building_data[i]->uid = i; } int cur_id; _build(BUILD_PARK); _name("park"); _cost(RES_GOLD, 300); _build_time(3); _destroy_cost(20); _upkeep(4); _base_morale(3); _description("\ A park is a well-groomed area of nature, with carefully designed paths and \ seating areas.\ "); _build(BUILD_PLAZA); _name("plaza"); _cost(RES_GOLD, 500); _cost(RES_STONE, 500); _build_time(5); _destroy_cost(150); _upkeep(4); _base_morale(1); _description("\ A plaza is an urban area that combines the pleasant environment and seating \ and strolling areas of a <link=park>park</link>, with the \ <link=building>business</link> space of a <link=marketplace>marketplace</link>.\ "); _build(BUILD_MARKETPLACE); _name("marketplace"); _cost(RES_GOLD, 800); _cost(RES_STONE, 1500); _build_time(7); _destroy_cost(350); _upkeep(2); _description("\ A marketplace is an area designed purely for business, with lots of space for \ <link=building>buildings</link> of various natures.\ "); _build(BUILD_HOVEL); _name("hovels"); _plural(); _cost(RES_GOLD, 300); _cost(RES_WOOD, 300); _build_time(3); _destroy_cost(250); _upkeep(5); _housing(CIT_PEASANT, 100); _description("\ Hovels are simple homes, sacrificing comfort and style to be a purely \ utilitarian living space for <link=peasants>peasants</link>.\ "); _build(BUILD_HOUSE); _name("houses"); _plural(); _cost(RES_GOLD, 800); _cost(RES_WOOD, 500); _build_time(10); _destroy_cost(600); _upkeep(10); _housing(CIT_MERCHANT, 100); _description("\ Houses are respectable homes with a moderate degree of comfort, suitable for \ the <link=merchants>middle classes</link>.\ "); _build(BUILD_MANOR); _name("manor"); _cost(RES_GOLD, 1200); _cost(RES_WOOD, 500); _cost(RES_STONE, 1000); _build_time(30); _destroy_cost(1250); _upkeep(20); _housing(CIT_BURGHER, 50); _description("\ A manor is a large, well-furnished home. Its high degree of comfort and low-\ density quarters are ideal for the <link=burghers>upper class</link>.\ "); _build(BUILD_KEEP); _name("keep"); _cost(RES_GOLD, 3000); _cost(RES_STONE, 4000); _build_time(90); _destroy_cost(2500); _upkeep(30); _housing(CIT_BURGHER, 5); _housing(CIT_MERCHANT, 50); _housing(CIT_PEASANT, 100); _description("\ A keep is the center of any city. It provides a home for the \ <link=nobles>nobility</link> as well as space for some <link=citizens>citizens\ </link>. It also has space to support several <link=building>businesses\ </link>.\ "); _build(BUILD_FARM); _name("farm"); _cost(RES_GOLD, 250); _build_time(1); _destroy_cost(50); _upkeep(1); _jobs(CIT_PEASANT, 15); _wages(1); _produces(RES_FARMING, 1); _description("\ A farm is a tilled piece of land designed for growing <link=crop>crops</link>.\ "); _build(BUILD_HUNTING_CAMP); _name("hunting camp"); _cost(RES_GOLD, 200); _build_time(1); _destroy_cost(100); _upkeep(3); _jobs(CIT_PEASANT, 10); _wages(1); _produces(RES_HUNTING, 1); _description("\ A hunting camp is a base of operations for <link=hunting>hunters</link>, \ allowing them to catch <link=animals>game</link> in the land upon which it is \ built.\ "); _build(BUILD_MINE); _name("mine"); _cost(RES_GOLD, 500); _cost(RES_WOOD, 400); _build_time(10); _destroy_cost(1500); _upkeep(8); _jobs(CIT_PEASANT, 8); _wages(2); _produces(RES_MINING, 5); _description("\ A mine is set of several shafts dug into the land, allowing <link=mining>miners\ </link> to pull <link=minerals>minerals</link> from the ground.\ "); _build(BUILD_SAWMILL); _name("sawmill"); _forbidden(RACE_ELF); _cost(RES_GOLD, 200); _cost(RES_STONE, 350); _build_time(5); _destroy_cost(350); _upkeep(3); _jobs(CIT_PEASANT, 6); _wages(1); _produces(RES_LOGGING, 5); _description("\ A sawmill is a site for the processing of <link=logging>logging</link> \ operations. It should be built on a <link=city map tile>map tile</link> that \ has <link=trees>trees</link> growing on it; it will remove the trees and turn \ them into <link=wood>wood</link> for use. Once the trees are cleared, the \ sawmill will automatically close.\ "); _build(BUILD_PASTURE); _name("pasture"); _cost(RES_GOLD, 100); _cost(RES_WOOD, 100); _build_time(1); _destroy_cost(20); _upkeep(1); _livestock(500); _description("\ A pasture is a fenced-in area used for keeping <link=livestock>livestock\ </link>. The terrain it is built upon does not matter.\ "); _build(BUILD_BARRACKS); _name("barracks"); _plural(); _cost(RES_GOLD, 800); _cost(RES_WOOD, 650); _build_time(14); _destroy_cost(800); _upkeep(15); _military(50); _description("\ Barracks are a space for the housing and training of <link=army>military units\ </link>.\ "); _build(BUILD_MASONRY); _category(BUILDCAT_MANUFACTURING); _name("masonry"); _cost(RES_GOLD, 250); _cost(RES_WOOD, 600); _build_time(5); _upkeep(3); _jobs(CIT_PEASANT, 3); _wages(1); _recipe(RES_STONE, 1); _units_per_day(3); _max_deficit(0); _uses_mineral(MINERAL_STONE, 1); _description("\ A masonry is a <link=building>building</link> where uncut <link=stone>stone\ </link> is cut into useful blocks.\ "); _build(BUILD_SMELTERY); _category(BUILDCAT_MANUFACTURING); _name("smeltery"); _cost(RES_GOLD, 500); _cost(RES_STONE, 1000); _build_time(6); _unlock(CITY_ACHIEVE_ORES, 0, 0); _jobs(CIT_PEASANT, 10); _wages(2); _recipe(RES_TIN, 1); _recipe_name("Smelt tin (burn wood)"); _units_per_day(1); _max_deficit(0); _uses_mineral(MINERAL_TIN, 1); _uses_resource(RES_WOOD, 3); _recipe(RES_TIN, 3); _recipe_name("Smelt tin (burn coal)"); _units_per_day(3); _max_deficit(0); _uses_mineral(MINERAL_TIN, 3); _uses_mineral(MINERAL_COAL, 1); _recipe(RES_COPPER, 1); _recipe_name("Smelt copper (burn wood)"); _units_per_day(1); _max_deficit(0); _uses_mineral(MINERAL_COPPER, 1); _uses_resource(RES_WOOD, 3); _recipe(RES_COPPER, 3); _recipe_name("Smelt copper (burn coal)"); _units_per_day(3); _max_deficit(0); _uses_mineral(MINERAL_COPPER, 3); _uses_mineral(MINERAL_COAL, 1); _recipe(RES_IRON, 1); _recipe_name("Smelt iron (burn wood)"); _days_per_unit(2); _max_deficit(0); _uses_mineral(MINERAL_IRON, 1); _uses_resource(RES_WOOD, 3); _recipe(RES_IRON, 3); _recipe_name("Smelt iron (burn coal)"); _units_per_day(2); _max_deficit(0); _uses_mineral(MINERAL_IRON, 3); _uses_mineral(MINERAL_COAL, 1); _description("\ A smeltery is a high-temperature furnace used to melt metals out of the \ <link=minerals>ores</link> they naturally appear in. These ores are virtually \ useless before smelting; thus a smeltery is a vital addition to any mining \ operation. It is possible to smelt ores using <link=wood>wood</link> as a \ fuel; however, it is much faster and more efficient to burn <link=coal>coal\ </link> if it is available.\ "); _build(BUILD_MINT); _category(BUILDCAT_MANUFACTURING); _name("mint"); _cost(RES_GOLD, 500); _cost(RES_STONE, 1000); _cost(RES_IRON, 200); _build_time(6); _unlock( CITY_ACHIEVE_POP, CIT_MERCHANT, 1 ); _upkeep(6); _jobs(CIT_MERCHANT, 3); _wages(4); _recipe(RES_GOLD, 1); _recipe_name("Gold (burn wood)"); _units_per_day(3); _max_deficit(0); _uses_mineral(MINERAL_GOLD, 1); _uses_resource(RES_WOOD, 3); _recipe(RES_GOLD, 3); _recipe_name("Gold (burn coal)"); _units_per_day(3); _max_deficit(0); _uses_mineral(MINERAL_GOLD, 3); _uses_mineral(MINERAL_COAL, 1); _description("\ A mint is a <link=building>building</link> where raw <link=gold>gold</link> \ ore can be forged into spendable coins and bars. Doing so requires a fuel \ source; <link=wood>wood</link> can be used, but <link=coal>coal</link> is more \