📄 avoidbullet.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 + -