⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aaibrain.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				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 + -