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

📄 avoidbullet.cpp

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

/**
 * 该类代表一颗子弹
 * @author xiemin
 */
class BaseBullet
{
	private:
		Point2D fireLocation;
		double heading;
		double velocity;
		long fireTime;
		
	public:
		BaseBullet(Bullet* bullet, Bot* bot)
		{
			fireLocation = bullet->getFireLocation();
			velocity = SimpleRobot::getBulletVelocity(bullet->getPower());
			fireTime = bullet->getFireTime();
			heading = Math::heading(fireLocation, bot->getLocation());
		}
		/**
		 * 得到子弹在指定时间的位置
		 * @param time
		 * @return
		 */
		Point2D getLocation(long time)
		{
			return Math::nextPoint(fireLocation, 
				heading, velocity*(time-fireTime));
		}
		
		/**
		 * 判断这颗子弹对机器人是否是有效的,即判断子弹是否已经处在
		 * 机器人的后方,不可能再击中机器人
		 * @param time
		 * @param robotLocation
		 * @return
		 */
		bool isValid(long time, const Point2D& robotLocation)
		{
			Point2D bulletLocation = getLocation(time);
			if(bulletLocation.distance(fireLocation)>robotLocation.distance(fireLocation))
				return false;
			else return true;
		}
};

///////////////////////////////////////////////////////////////

/**
 * 躲避子弹的机器人
 * @author xiemin
 */
class AvoidBullet : public SimpleRobot
{
	private:
		//计算目标点时采用的搜索半径
		static const double SEARCH_DIS;
		//每次迭代的递增量
		static const double GAP;
		//存放对手发射的子弹
		vector<BaseBullet*> bullets;
		
	public:
		void onFire(FireAction* action)
		{
			Bot* fireBot = getBot(action->getBullet()->getOwner());
			if(isTeammate(fireBot)) return;	
			BaseBullet* bullet = new BaseBullet(action->getBullet(), getSelfBot());
			bullets.push_back(bullet);
		}
		
		void onRoundBegin(RoundBeginAction* action)
		{
			for(int i=0; i<bullets.size(); i++)
				delete bullets[i];
			bullets.clear();
		}
		
		void onTick(TickAction* action)
		{
			Point2D destination = getDestination();
			moveTo(destination);
		}

	private:
		//计算目标点
		Point2D getDestination()
		{
			Point2D destination;
			double bestRist = 100000000;
			for(int i=0; i*GAP<2*Math::PI; i++)
			{
				//下一个点
				Point2D next = Math::nextPoint(getLocation(), i*GAP, SEARCH_DIS);
				//保证该点在场地中
				if(!inCourt(next)) continue;
				//比较该点的危险系数
				double rist = getRisk(next);
				if(rist<bestRist)
				{
					destination = next;
					bestRist = rist;
				}
			}
			return destination;
		}
		
		//计算指定目标点的风险系数
		double getRisk(Point2D& destination)
		{
			double rist = 0;
			for(int i=0; i<bullets.size(); i++)
			{
				BaseBullet* bullet = bullets[i];
				if(!bullet->isValid(getTime(), getLocation())) continue;
				
				Point2D bulletLocation = bullet->getLocation(getTime());
				double dis = destination.distance(bulletLocation);
				rist += 1/dis;
			}
			return rist;
		}
		
};

//计算目标点时采用的搜索半径
const double AvoidBullet::SEARCH_DIS = 100;
//每次迭代的递增量
const double AvoidBullet::GAP = Math::toRadians(1);


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

⌨️ 快捷键说明

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