//--------- Begin of function Nation::capture_expected_resistance --------// // // The lowest resistance can be expected if we are going to capture the // town. // int Nation::capture_expected_resistance(int townRecno) { //--- we have plenty of cash, use cash to decrease the resistance of the villagers ---// if( should_use_cash_to_capture() ) return 0; // return zero resistance //----- the average resistance determines the captureRating ------// int captureRating = 0; Town* townPtr = town_array[townRecno]; int averageResistance; if( townPtr->nation_recno ) averageResistance = townPtr->average_loyalty(); else averageResistance = townPtr->average_resistance(nation_recno); //----- get the id. of the most populated races in the town -----// int majorityRace = townPtr->majority_race(); err_when( !majorityRace ); // this should not happen //---- see if there are general available for capturing this town ---// int targetResistance=0; if( !find_best_capturer(townRecno, majorityRace, targetResistance) ) return 100; int resultResistance = ( targetResistance * townPtr->race_pop_array[majorityRace-1] + averageResistance * (townPtr->population - townPtr->race_pop_array[majorityRace-1]) ) / townPtr->population; return resultResistance; }
//--------- Begin of function Nation::think_capture_independent --------// // // Think about capturing independent towns. // int Nation::think_capture_independent() { //------- Capture target choices -------// std::priority_queue<CaptureTown> captureTownQueue; //--- find the town that makes most sense to capture ---// int townRecno; Town* townPtr; for(townRecno=town_array.size(); townRecno>0; townRecno--) { if(town_array.is_deleted(townRecno)) continue; townPtr = town_array[townRecno]; if( townPtr->nation_recno ) // only capture independent towns continue; if( townPtr->no_neighbor_space ) // if there is no space in the neighbor area for building a new firm. continue; if( townPtr->rebel_recno ) // towns controlled by rebels will not drop in resistance even if a command base is present continue; //------ only if we have a presence/a base town in this region -----// if( !has_base_town_in_region(townPtr->region_id) ) continue; //---- check if there are already camps linked to this town ----// int i; for( i=townPtr->linked_firm_count-1 ; i>=0 ; i-- ) { Firm* firmPtr = firm_array[ townPtr->linked_firm_array[i] ]; if( firmPtr->firm_id != FIRM_CAMP ) continue; //------ if we already have a camp linked to this town -----// if( firmPtr->nation_recno == nation_recno ) break; //--- if there is an overseer with high leadership and right race in the opponent's camp, don't bother to compete with him ---// if( firmPtr->overseer_recno ) { Unit* unitPtr = unit_array[firmPtr->overseer_recno]; if( unitPtr->skill.skill_level >= 70 && unitPtr->race_id == townPtr->majority_race() ) { break; } } } if( i>=0 ) // there is already a camp linked to this town and we don't want to get involved with its capturing plan continue; //------ no linked camps interfering with potential capture ------// int captureUnitRecno; int targetResistance = capture_expected_resistance(townRecno, &captureUnitRecno); int averageResistance = townPtr->average_resistance(nation_recno); int minResistance = MIN( averageResistance, targetResistance ); if( minResistance < 50 - pref_peacefulness/5 ) // 30 to 50 depending on { captureTownQueue.push({townRecno, minResistance, captureUnitRecno}); } } //------- try to capture the town in their resistance order ----// const bool needToCheckDistance = !config.explore_whole_map && info.game_date-info.game_start_date > MAX(MAX_WORLD_X_LOC, MAX_WORLD_Y_LOC) * (5-config.ai_aggressiveness) / 5; // 3 to 5 / 5 while( captureTownQueue.size() > 0 ) { int captureRecno = captureTownQueue.top().town_recno; int captureUnitRecno = captureTownQueue.top().capture_unit_recno; captureTownQueue.pop(); err_when( town_array.is_deleted(captureRecno) ); //-------------------------------------------// // If the map is set to unexplored, wait for a // reasonable amount of time before moving out // to build the camp. //-------------------------------------------// if( needToCheckDistance ) { Town* targetTown = town_array[ captureRecno ]; int j; for( j=0 ; j<ai_town_count ; j++ ) { Town* ownTown = town_array[ ai_town_array[j] ]; int townDistance = misc.points_distance(targetTown->center_x, targetTown->center_y, ownTown->center_x, ownTown->center_y); if( info.game_date-info.game_start_date > townDistance * (5-config.ai_aggressiveness) / 5 ) // 3 to 5 / 5 { break; } } if( j==ai_town_count ) continue; } if( start_capture( captureRecno, captureUnitRecno ) ) return 1; } return 0; }
//-------- Begin of function Nation::find_best_capturer ------// // // Find an existing unit as the capturer of the town. // // <int> townRecno - recno of the town to capture // <int> raceId - race id. of the capturer. 0 if any races. // <int&> bestTargetResistance - a reference var for returning the target resistance if the returned unit is assigned as the overseer // // return: <int> the recno of the unit found. // int Nation::find_best_capturer(int townRecno, int raceId, int& bestTargetResistance) { #define MIN_CAPTURE_RESISTANCE_DEC 20 // if we assign a unit as the commander, the minimum expected resistance decrease should be 20, otherwise we don't do it. Unit* unitPtr; Town* targetTown = town_array[townRecno]; Firm* firmPtr; int targetResistance; int bestUnitRecno=0; bestTargetResistance = 100; for( int i=ai_general_count-1 ; i>=0 ; i-- ) { unitPtr = unit_array[ ai_general_array[i] ]; if( raceId && unitPtr->race_id != raceId ) continue; err_when( unitPtr->nation_recno != nation_recno ); err_when( unitPtr->rank_id != RANK_KING && unitPtr->rank_id != RANK_GENERAL ); if( unitPtr->nation_recno != nation_recno ) continue; //---- if this unit is on a mission ----// if( unitPtr->home_camp_firm_recno ) continue; //---- don't use the king to build camps next to capture enemy towns, only next to independent towns ----// if( unitPtr->rank_id == RANK_KING && targetTown->nation_recno ) continue; //----- if this unit is in a camp -------// if( unitPtr->unit_mode == UNIT_MODE_OVERSEE ) { firmPtr = firm_array[unitPtr->unit_mode_para]; //--- check if the unit currently in a command base trying to take over an independent town ---// int j; for( j=firmPtr->linked_town_count-1 ; j>=0 ; j-- ) { Town* townPtr = town_array[ firmPtr->linked_town_array[j] ]; //--- if the unit is trying to capture an independent town and he is still influencing the town to decrease resistance ---// if( townPtr->nation_recno==0 && townPtr->average_target_resistance(nation_recno) < townPtr->average_resistance(nation_recno) ) { break; // then don't use this unit } } if( j>=0 ) // if so, don't use this unit continue; } //--- if this unit is idle and the region ids are matched ---// if( unitPtr->action_mode != ACTION_STOP || unitPtr->region_id() != targetTown->region_id ) { continue; } //------- get the unit's influence index --------// err_when( unitPtr->skill.skill_id != SKILL_LEADING ); targetResistance = 100-targetTown->camp_influence(unitPtr->sprite_recno); // influence of this unit if he is assigned as a commander of a military camp //-- see if this unit's rating is higher than the current best --// if( targetResistance < bestTargetResistance ) { bestTargetResistance = targetResistance; bestUnitRecno = unitPtr->sprite_recno; } } return bestUnitRecno; }
//--------- Begin of function Nation::think_capture_independent --------// // // Think about capturing independent towns. // int Nation::think_capture_independent() { //------- Capture target choices -------// #define MAX_CAPTURE_TOWN 30 CaptureTown capture_town_array[MAX_CAPTURE_TOWN]; short capture_town_count=0; //--- find the town that makes most sense to capture ---// int townRecno; Town* townPtr; for(townRecno=town_array.size(); townRecno>0; townRecno--) { if(town_array.is_deleted(townRecno)) continue; townPtr = town_array[townRecno]; if( townPtr->nation_recno ) // only capture independent towns continue; if( townPtr->no_neighbor_space ) // if there is no space in the neighbor area for building a new firm. continue; if( townPtr->rebel_recno ) // towns controlled by rebels will not drop in resistance even if a command base is present continue; //------ only if we have a presence/a base town in this region -----// if( !has_base_town_in_region(townPtr->region_id) ) continue; //---- check if there are already camps linked to this town ----// int i; for( i=townPtr->linked_firm_count-1 ; i>=0 ; i-- ) { Firm* firmPtr = firm_array[ townPtr->linked_firm_array[i] ]; if( firmPtr->firm_id != FIRM_CAMP ) continue; //------ if we already have a camp linked to this town -----// if( firmPtr->nation_recno == nation_recno ) break; //--- if there is an overseer with high leadership and right race in the opponent's camp, do bother to compete with him ---// if( firmPtr->overseer_recno ) { Unit* unitPtr = unit_array[firmPtr->overseer_recno]; if( unitPtr->skill.skill_level >= 70 && unitPtr->race_id == townPtr->majority_race() ) { break; } } } if( i>=0 ) // there is already a camp linked to this town and we don't want to get involved with its capturing plan continue; //-- if the town has linked military camps of the same nation --// int targetResistance = capture_expected_resistance(townRecno); int averageResistance = townPtr->average_resistance(nation_recno); int minResistance = MIN( averageResistance, targetResistance ); if( minResistance < 50 - pref_peacefulness/5 ) // 30 to 50 depending on { capture_town_array[capture_town_count].town_recno = townRecno; capture_town_array[capture_town_count].min_resistance = minResistance; capture_town_count++; } } //------ sort the capture target choices by min_resistance ----// qsort( &capture_town_array, capture_town_count, sizeof(capture_town_array[0]), sort_capture_town_function ); //------- try to capture the town in their resistance order ----// for( int i=0 ; i<capture_town_count ; i++ ) { err_when( town_array.is_deleted(capture_town_array[i].town_recno) ); //-------------------------------------------// // If the map is set to unexplored, wait for a // reasonable amount of time before moving out // to build the mine. //-------------------------------------------// if( !config.explore_whole_map ) { Town* targetTown = town_array[ capture_town_array[i].town_recno ]; int j; for( j=0 ; j<ai_town_count ; j++ ) { Town* ownTown = town_array[ ai_town_array[j] ]; int townDistance = m.points_distance(targetTown->center_x, targetTown->center_y, ownTown->center_x, ownTown->center_y); if( info.game_date-info.game_start_date > townDistance * (5-config.ai_aggressiveness) / 5 ) // 3 to 5 / 5 { break; } } if( j==ai_town_count ) continue; } if( start_capture( capture_town_array[i].town_recno ) ) return 1; } return 0; }
//------- Begin of function FirmMarket::think_export_product -----------// // // Think about exporting products from this market to another market. // int FirmMarket::think_export_product() { //--- first check if there is any excessive supply for export ---// int exportProductId = 0; MarketGoods *marketGoods = market_goods_array; for( int i=0 ; i<MAX_MARKET_GOODS ; i++, marketGoods++ ) { if( marketGoods->product_raw_id ) { if( marketGoods->stock_qty > MAX_MARKET_STOCK * 3 / 4 && marketGoods->month_demand < marketGoods->supply_30days() / 2 ) // the supply is at least double of the demand { exportProductId = marketGoods->product_raw_id; break; } } } if( !exportProductId ) return 0; //----- locate for towns that do not have the supply of the product ----// Town* townPtr; Nation* nationPtr = nation_array[nation_recno]; for( int townRecno=town_array.size() ; townRecno>0 ; townRecno-- ) { if( town_array.is_deleted(townRecno) ) continue; townPtr = town_array[townRecno]; if( townPtr->population < 20 - (10*nationPtr->pref_trading_tendency/100) ) // 10 to 20 as the minimum population for considering trade continue; if( townPtr->has_product_supply[exportProductId-1] ) // if the town already has the supply of product, return now continue; if( townPtr->region_id != region_id ) continue; if( townPtr->no_neighbor_space ) // if there is no space in the neighbor area for building a new firm. continue; if( misc.points_distance( center_x, center_y, townPtr->center_x, center_y ) > MAX_WORLD_X_LOC/4 ) // don't consider if it is too far away continue; if( townPtr->town_recno && nationPtr->get_relation_status(townPtr->town_recno) < NATION_FRIENDLY ) // only build markets to friendly nation's town { continue; } //-----------------------------------------// if( townPtr->nation_recno ) { //--- if it's a nation town, only export if we have trade treaty with it ---// if( !nationPtr->get_relation(townPtr->nation_recno)->trade_treaty ) continue; } else { //--- if it's an independent town, only export if the resistance is low ---// if( townPtr->average_resistance(nation_recno) > INDEPENDENT_LINK_RESISTANCE ) continue; } //----- think about building a new market to the town for exporting our goods -----// if( think_build_export_market(townRecno) ) return 1; } return 0; }