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

📄 patternfire.cpp

📁 AI-CODE坦克机器人 《C++语言学习利器 —AI-CODE坦克机器人》-杜飞雪-源代码
💻 CPP
字号:
#include <airobot/cpp/SimpleRobot.hpp>

/**
 * 用模式匹配算法开火的机器人
 * @author xiemin
 */
class PatternFire : public SimpleRobot
{
	private:
		//开火的火力
		static const double POWER;
		//用于匹配段的长度
		static const int MATCH_LENGHT;
		
		//保留历史纪录的最大长度
		enum { HISTORY_LENGHT = 2000 };  
		//对手的速度记录
		double velocityRecord[HISTORY_LENGHT];
		//对手的方向记录
		double headingRecord[HISTORY_LENGHT];
		//当前纪录位置
		int currentIndex;
	
	public:
			
		void onRoundBegin(RoundBeginAction* action)
		{
			currentIndex = 0;
		}
		
		void onTick(TickAction* action)
		{
			Bot* opponent = getFirstOpponent();
			if(opponent==NULL) return;
			
			record(opponent);
			int matchIndex = getMatchIndex();
			Point2D firePoint = getFirePoint(matchIndex, POWER);
			fire(firePoint, POWER);
		}
		
	private:
		//记录当前的机器人状态
		void record(Bot* bot)
		{
			velocityRecord[currentIndex] = bot->getVelocity();
			headingRecord[currentIndex] = bot->getHeading();
			currentIndex++;
		}
		
		//计算最佳的匹配点
		int getMatchIndex()
		{
			double beatSimilarity=1000000;
			int matchIndex=0;
			//这里取i<currentFrame-100是为了避免比较样本和被比较样本重复
			//和留取足够的节点给递推未来坐标用
			for(int i=MATCH_LENGHT; i<currentIndex-MATCH_LENGHT; i++)
			{
				//取10个样本节点计算相似度
				double similarity=0;
				for(int j=1; j<=MATCH_LENGHT; j++)
				{
					similarity+=fabs(velocityRecord[i-j]-velocityRecord[currentIndex-j]);
					similarity+=fabs(headingRecord[i-j]-headingRecord[currentIndex-j]);
					//加了权值得匹配度计算
					//similarity+=fabs(velocityRecord[i-j]-velocityRecord[currentIndex-j])/8;
					//similarity+=fabs(headingRecord[i-j]-headingRecord[currentIndex-j])/Math::PI;
				}
				//记录最相似的相似度,以及对应的记录节点下标
			   	if(similarity<beatSimilarity)
			   	{
				    matchIndex=i;
				   	beatSimilarity=similarity;
	    		}
			}
			return matchIndex;
		}
		
		//得到开火的位置
		Point2D getFirePoint(int matchIndex, double power)
		{
			//预测位置
	        Point2D firePoint = getFirstOpponent()->getLocation();
	        int time = 0;
	        while(matchIndex+time<currentIndex)
	        {
	        	double distance = Math::distance(getLocation(), firePoint);
	        	if(distance/getBulletVelocity(power)<=time) break;
	        	firePoint = Math::nextPoint(firePoint, 
	        		headingRecord[matchIndex+time], velocityRecord[matchIndex+time]);
	        	time++;
	        }
			return firePoint;
		}
};

//开火的火力
const double PatternFire::POWER = 0.5;
//用于匹配段的长度
const int PatternFire::MATCH_LENGHT = 20;


//启动机器人程序
int main(int argC, char* argV[])
{
	Robot* robot = new PatternFire();
	return startup(argC, argV, robot);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -