📄 statistfire.cpp
字号:
#include <airobot/cpp/SimpleRobot.hpp>
/**
* 概率
* @author xiemin
*/
class Statist
{
private:
//角度的间隔
static const double GAP;
//概率分布数组的大小
enum { FACTOR_SIZE = 30 };
//概率分布数组
double factors[FACTOR_SIZE];
public:
/*
* 提高指定角度下的概率值
*/
void rate(double bearing)
{
factors[getIndex(bearing)]+=0.01;
for(int i=0; i<FACTOR_SIZE; i++)
factors[i] *= 0.99;
}
/**
* 得到最好的开火夹角
* @return
*/
double getBestFireBearing(void)
{
return (getHeightestIndex()-FACTOR_SIZE/2)*GAP;
}
private:
/*
* 得到指定的夹角在概率数组中的索引
*/
int getIndex(double bearing)
{
return FACTOR_SIZE/2+(int)(bearing/GAP);
}
/*
* 得到概率最高的索引
*/
int getHeightestIndex(void)
{
int heightestIndex = 0;
for(int i=0; i<FACTOR_SIZE; i++)
if( factors[i]>factors[heightestIndex])
heightestIndex = i;
return heightestIndex;
}
};
const double Statist::GAP = Math::toRadians(3);
///////////////////////////////////////////////////////////////////
/**
* 这个类代表一个波,用于统计敌人移动的概率
* @author xiemin
*/
class Wave
{
private:
//当前分区下的概率分布
Statist* statist;
//波的中心方向
double center;
//波的开始位置
Point2D startLocation;
//波的速度
double velocity;
//波出发的时间
long startTime;
//波是否是可用的
bool valid;
public:
Wave(Statist* s)
{
statist = s;
valid = true;
}
/**
* 更新波的状态
* @param time
* @param enemyLocation
*/
void update(long time, const Point2D& enemyLocation)
{
if(!valid) return;
//检查是否撞到了对手
double distance = startLocation.distance(enemyLocation);
double moveDistance = velocity*(time-startTime);
//hited!!
if(moveDistance>=distance)
{
valid = false;
double heading = Math::heading(startLocation, enemyLocation);
//计算开火的夹角
double bearing = Math::bearing(heading, center);
//更新这个夹角的命中率
statist->rate(bearing);
}
}
/**
* @param startTime The startTime to set.
*/
void setStartTime(long t)
{
startTime = t;
}
/**
* @param center The center to set.
*/
void setCenter(double c)
{
center = c;
}
/**
* @param startLocation The startLocation to set.
*/
void setStartLocation(Point2D l)
{
startLocation = l;
}
/**
* @param velocity The velocity to set.
*/
void setVelocity(double v)
{
velocity = v;
}
/**
* @return Returns the isAvailable.
*/
bool isValid()
{
return valid;
}
};
///////////////////////////////////////////////////////////////////////////
/**
* 用统计学瞄准的机器人
* @author xiemin
*/
class StatistFire : public SimpleRobot
{
private:
//发弹的火力
static const double POWER;
//按距离分区的间隔
static const double GAP;
//机器人之间的最大距离
static const int MAX_DIS;
//不同分区下的概率
Statist* statists;
//发射的波
vector<Wave*> waves;
public:
StatistFire(void)
{
int size = (int)(MAX_DIS/GAP);
statists = new Statist[size];
}
void onTick(TickAction* action)
{
Bot* bot = getFirstOpponent();
if(bot==NULL) return;
addWave(bot);
updateWaves(bot);
doFire(bot);
doMove();
}
void onRoundBegin(RoundBeginAction* action)
{
//清除上一轮发射的波
for(int i=0; i<waves.size(); i++)
delete waves[i];
waves.clear();
}
private:
//执行移动
void doMove()
{
//移动到场地的中央
Point2D center(getCourtWidth()/2, getCourtHeight()/2);
moveTo(center);
}
/*
* 执行开火操作
*/
void doFire(Bot* bot)
{
if(getFirePrepareTime()<=0)
{
Statist* statist = getStatist(bot);
double bearing = statist->getBestFireBearing();
double heading = Math::heading(getLocation(), bot->getLocation());
double fireHeading = heading+bearing;
fire(fireHeading, POWER);
}
}
/*
* 增加一个波
*/
void addWave(Bot* bot)
{
Statist* statist = getStatist(bot);
Wave* wave = new Wave(statist);
double center = Math::heading(getLocation(), bot->getLocation());
wave->setCenter(center);
wave->setStartLocation(getLocation());
wave->setStartTime(getTime());
wave->setVelocity(getBulletVelocity(POWER));
waves.push_back(wave);
}
/*
* 更新所有的波
*/
void updateWaves(Bot* bot)
{
for(int i=0; i<waves.size(); i++)
{
Wave* wave = waves[i];
if(wave->isValid())
wave->update(getTime(), bot->getLocation());
}
}
//得到当前分区的概率
Statist* getStatist(Bot* bot)
{
double distance = Math::distance(getLocation(), bot->getLocation());
int index = (int)(distance/GAP);
return &statists[index];
}
};
//发弹的火力
const double StatistFire::POWER = 0.1;
//按距离分区的间隔
const double StatistFire::GAP = 100;
//机器人之间的最大距离
const int StatistFire::MAX_DIS = 1000;
//启动机器人程序
int main(int argC, char* argV[])
{
Robot* robot = new StatistFire();
return startup(argC, argV, robot);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -