📄 aaibrain.cpp
字号:
map->sector[x+1][y].distance_to_base = i;
sectors[i].push_back(&map->sector[x+1][y]);
++neighbours;
}
// check upper neighbour
if(y > 0 && ai->map->sector[x][y-1].distance_to_base == -1)
{
map->sector[x][y-1].distance_to_base = i;
sectors[i].push_back(&map->sector[x][y-1]);
++neighbours;
}
// check lower neighbour
if(y < (ai->map->ySectors - 1) && ai->map->sector[x][y+1].distance_to_base == -1)
{
map->sector[x][y+1].distance_to_base = i;
sectors[i].push_back(&map->sector[x][y+1]);
++neighbours;
}
if(i == 1 && !neighbours)
(*sector)->interior = true;
}
}
//fprintf(ai->file, "Base has now %i direct neighbouring sectors\n", sectors[1].size());
}
bool AAIBrain::SectorInList(list<AAISector*> mylist, AAISector *sector)
{
// check if sector already added to list
for(list<AAISector*>::iterator t = mylist.begin(); t != mylist.end(); t++)
{
if(*t == sector)
return true;
}
return false;
}
bool AAIBrain::ExpandBase(SectorType sectorType)
{
// TODO: improve expansion algorithm
//if(expandable)
if(sectors[0].size() < cfg->MAX_BASE_SIZE)
{
// debug purposes:
//fprintf(ai->file, "Found %i possible target sectors \n", neighbouring_sectors.size());
// now targets should contain all neighbouring sectors that are not currently part of the base
// only once; select the sector with most metalspots and least danger
AAISector *best_sector = 0;
float best_rating = 0, my_rating;
int spots;
float dist;
for(list<AAISector*>::iterator t = sectors[1].begin(); t != sectors[1].end(); ++t)
{
// dont expand if enemy structures in sector && check for allied buildings
if((*t)->enemy_structures <= 0 && (*t)->allied_structures < 200 && map->team_sector_map[(*t)->x][(*t)->y] == -1)
{
// rate current sector
spots = (*t)->GetNumberOfMetalSpots();
my_rating = 2.0f + (float)spots / 2.0f;
my_rating += 4.0f / (*t)->GetMapBorderDist();
// minmize distance between sectors
dist = 0.1f;
for(list<AAISector*>::iterator sector = sectors[0].begin(); sector != sectors[0].end(); ++sector)
dist += sqrt( pow( (float)((*t)->x - (*sector)->x) , 2) + pow( (float)((*t)->y - (*sector)->y) , 2) );
dist *= 3.0f;
if(sectorType = LAND_SECTOR)
{
// prefer flat sectors without water
my_rating += ((*t)->flat_ratio - (*t)->water_ratio) * 8.0f;
my_rating /= dist;
}
else if(sectorType == WATER_SECTOR)
{
my_rating += 8.0f * (*t)->water_ratio;
my_rating /= dist;
}
else
my_rating = 0;
// choose higher rated sector
if(my_rating > best_rating)
{
best_rating = my_rating;
best_sector = *t;
}
}
}
if(best_sector)
{
// add this sector to base
AddSector(best_sector);
// debug purposes:
if(sectorType == LAND_SECTOR)
fprintf(ai->file, "\nAdding land sector %i,%i to base; base size: %i \n\n", best_sector->x, best_sector->y, sectors[0].size());
else
fprintf(ai->file, "\nAdding water sector %i,%i to base; base size: %i \n\n", best_sector->x, best_sector->y, sectors[0].size());
// update neighbouring sectors
UpdateNeighbouringSectors();
UpdateBaseCenter();
// check if further expansion possible
if(sectors[0].size() == cfg->MAX_BASE_SIZE)
expandable = false;
freeBaseSpots = true;
return true;
}
}
return false;
}
void AAIBrain::UpdateMaxCombatUnitsSpotted(vector<float>& units_spotted)
{
for(int i = 0; i < bt->combat_categories; ++i)
{
// decrease old values
max_units_spotted[i] *= 0.996f;
// check for new max values
if(units_spotted[i] > max_units_spotted[i])
max_units_spotted[i] = units_spotted[i];
}
}
void AAIBrain::UpdateAttackedByValues()
{
for(int i = 0; i < bt->combat_categories; ++i)
{
attacked_by[i] *= 0.96f;
}
}
void AAIBrain::AttackedBy(int combat_category_id)
{
// update counter for current game
attacked_by[combat_category_id] += 1;
// update counter for memory dependent on playtime
bt->attacked_by_category[0][combat_category_id][GetGamePeriod()] += 1.0f;
}
void AAIBrain::UpdateDefenceCapabilities()
{
for(int i = 0; i < bt->assault_categories.size(); ++i)
defence_power_vs[i] = 0;
if(cfg->AIR_ONLY_MOD)
{
for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); ++category)
{
for(list<AAIGroup*>::iterator group = ai->group_list[*category].begin(); group != ai->group_list[*category].end(); ++group)
{
defence_power_vs[0] += (*group)->GetPowerVS(0);
defence_power_vs[1] += (*group)->GetPowerVS(1);
defence_power_vs[2] += (*group)->GetPowerVS(2);
defence_power_vs[3] += (*group)->GetPowerVS(3);
}
}
}
else
{
// anti air power
for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); ++category)
{
for(list<AAIGroup*>::iterator group = ai->group_list[*category].begin(); group != ai->group_list[*category].end(); ++group)
{
if((*group)->group_type == ASSAULT_UNIT)
{
if((*group)->category == GROUND_ASSAULT)
{
defence_power_vs[0] += (*group)->GetPowerVS(0);
defence_power_vs[2] += (*group)->GetPowerVS(2);
}
else if((*group)->category == HOVER_ASSAULT)
{
defence_power_vs[0] += (*group)->GetPowerVS(0);
defence_power_vs[2] += (*group)->GetPowerVS(2);
defence_power_vs[3] += (*group)->GetPowerVS(3);
}
else if((*group)->category == SEA_ASSAULT)
{
defence_power_vs[2] += (*group)->GetPowerVS(2);
defence_power_vs[3] += (*group)->GetPowerVS(3);
defence_power_vs[4] += (*group)->GetPowerVS(4);
}
else if((*group)->category == SUBMARINE_ASSAULT)
{
defence_power_vs[3] += (*group)->GetPowerVS(3);
defence_power_vs[4] += (*group)->GetPowerVS(4);
}
}
else if((*group)->group_type == ANTI_AIR_UNIT)
defence_power_vs[1] += (*group)->GetPowerVS(1);
}
}
}
// debug
/*fprintf(ai->file, "Defence capabilities:\n");
for(int i = 0; i < bt->assault_categories.size(); ++i)
fprintf(ai->file, "%-20s %f\n" , bt->GetCategoryString2(bt->GetAssaultCategoryOfID(i)),defence_power_vs[i]);
*/
}
void AAIBrain::AddDefenceCapabilities(int def_id, UnitCategory category)
{
if(cfg->AIR_ONLY_MOD)
{
defence_power_vs[0] += bt->units_static[def_id].efficiency[0];
defence_power_vs[1] += bt->units_static[def_id].efficiency[1];
defence_power_vs[2] += bt->units_static[def_id].efficiency[2];
defence_power_vs[3] += bt->units_static[def_id].efficiency[3];
}
else
{
if(bt->GetUnitType(def_id) == ASSAULT_UNIT)
{
if(category == GROUND_ASSAULT)
{
defence_power_vs[0] += bt->units_static[def_id].efficiency[0];
defence_power_vs[2] += bt->units_static[def_id].efficiency[2];
}
else if(category == HOVER_ASSAULT)
{
defence_power_vs[0] += bt->units_static[def_id].efficiency[0];
defence_power_vs[2] += bt->units_static[def_id].efficiency[2];
defence_power_vs[3] += bt->units_static[def_id].efficiency[3];
}
else if(category == SEA_ASSAULT)
{
defence_power_vs[2] += bt->units_static[def_id].efficiency[2];
defence_power_vs[3] += bt->units_static[def_id].efficiency[3];
defence_power_vs[4] += bt->units_static[def_id].efficiency[4];
}
else if(category == SUBMARINE_ASSAULT)
{
defence_power_vs[3] += bt->units_static[def_id].efficiency[3];
defence_power_vs[4] += bt->units_static[def_id].efficiency[4];
}
}
else if(bt->GetUnitType(def_id) == ANTI_AIR_UNIT)
defence_power_vs[1] += bt->units_static[def_id].efficiency[1];
}
}
void AAIBrain::SubtractDefenceCapabilities(int def_id, UnitCategory category)
{
}
float AAIBrain::Affordable()
{
return 35.0 /(cb->GetMetalIncome() + 5.0);
}
void AAIBrain::BuildUnits()
{
int side = ai->side-1;
UnitCategory category;
bool urgent = false;
int k;
float cost = 1 + Affordable()/12.0;
float ground_eff = 0;
float air_eff = 0;
float hover_eff = 0;
float sea_eff = 0;
float stat_eff = 0;
float submarine_eff = 0;
int anti_air_urgency;
int anti_sea_urgency;
int anti_ground_urgency;
int anti_hover_urgency;
int anti_submarine_urgency;
// determine elapsed game time
int t = GetGamePeriod();
// todo: improve selection
category = UNKNOWN;
MapType mapType = map->mapType;
float ground_usefulness = map->map_usefulness[0][side] + bt->mod_usefulness[0][side][mapType];
float air_usefulness = map->map_usefulness[1][side] + bt->mod_usefulness[1][side][mapType];
float hover_usefulness = map->map_usefulness[2][side] + bt->mod_usefulness[2][side][mapType];
float sea_usefulness = map->map_usefulness[3][side] + bt->mod_usefulness[3][side][mapType];
float submarine_usefulness = map->map_usefulness[4][side] + bt->mod_usefulness[4][side][mapType];
if(cfg->AIR_ONLY_MOD)
{
// determine effectiveness vs several other units
anti_ground_urgency = (int)( 2 + (0.05f + bt->attacked_by_category[1][0][t]) * ground_usefulness * (2.0f * attacked_by[0] + 1.0f) * (4.0f * max_units_spotted[0] + 0.2f) / (4.0f * defence_power_vs[0] + 1));
anti_air_urgency = (int)( 2 + (0.05f + bt->attacked_by_category[1][1][t]) * air_usefulness * (2.0f * attacked_by[1] + 1.0f) * (4.0f * max_units_spotted[1] + 0.2f) / (4.0f * defence_power_vs[1] + 1));
anti_hover_urgency = (int)( 2 + (0.05f + bt->attacked_by_category[1][2][t]) * hover_usefulness * (2.0f * attacked_by[2] + 1.0f) * (4.0f * max_units_spotted[2] + 0.2f) / (4.0f * defence_power_vs[2] + 1));
anti_sea_urgency = (int) (2 + (0.05f + bt->attacked_by_category[1][3][t]) * sea_usefulness * (2.0f * attacked_by[3] + 1.0f) * (4.0f * max_units_spotted[3] + 0.2f) / (4.0f * defence_power_vs[3] + 1));
for(int i = 0; i < execute->unitProductionRate; ++i)
{
ground_eff = 0;
air_eff = 0;
hover_eff = 0;
sea_eff = 0;
// build super units only in late game
if(cost < 1.1 && rand()%16 == 1)
{
category = SEA_ASSAULT;
}
else
{
if(rand()%1024 > 384)
category = GROUND_ASSAULT;
else if(rand()%1024 > 384)
category = AIR_ASSAULT;
else
category = HOVER_ASSAULT;
}
k = rand()%(anti_ground_urgency + anti_air_urgency + anti_hover_urgency + anti_sea_urgency);
if(k < anti_ground_urgency)
{
ground_eff = 4;
}
else if(k < anti_ground_urgency + anti_air_urgency)
{
air_eff = 4;
}
else if(k < anti_ground_urgency + anti_air_urgency + anti_hover_urgency)
{
hover_eff = 4;
}
else
{
sea_eff = 4;
}
BuildUnitOfCategory(category, cost, ground_eff, air_eff, hover_eff, sea_eff, submarine_eff, stat_eff, urgent);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -