📄 statistfire.c
字号:
#include <airobot/c/SimpleRobot.h>
/**
* 用统计学瞄准的机器人
* @author xiemin
*/
#define BEARING_GAP 0.0523 /*统计概率时角度的间隔,3度*/
#define POWER 0.1 /*发弹的火力*/
#define DISTANCE_GAP 100 /*按距离分区的间隔*/
#define FACTOR_SIZE 30 /*概率分布数组的大小*/
#define STATIST_SIZE 15 /*总的分区数*/
#define WAVE_SIZE 60 /*波的个数*/
/*概率*/
struct Statist
{
//概率分布数组
double factors[FACTOR_SIZE];
};
/*波,用于统计敌人移动的概率*/
struct Wave
{
int statist; /*当前分区下的概率分布*/
double center;/*波的中心方向*/
double startX, startY;/*波的开始位置*/
double velocity;/*波的速度*/
long startTime;/*波出发的时间*/
int active;/*波是否是活动的*/
};
struct Statist statists[STATIST_SIZE];
struct Wave waves[WAVE_SIZE];
int getIndex(double bearing); /* 得到指定的夹角在概率数组中的索引*/
int getHeightestIndex(int statist); /* 得到概率最高的索引 */
double getBestFireBearing(int statist); /* 得到最好的开火夹角 */
void rate(int statist, double bearing); /* 提高指定角度下的概率值 */
void addWave(struct Bot*); /*添加一个Wave*/
int getNextWave(void); /*返回下一个空闲的Wave位置*/
int getStatist(struct Bot*); /*返回与Bot对应的statist*/
void updateWaves(struct Bot*); /*更新所有的Wave*/
void updateWave(int wave, long time, double x, double y); /*更新Wave*/
void doMove(void); /*执行移动*/
void doFire(struct Bot* bot);/*执行开火操作*/
void onTick(struct TickAction* action)
{
struct Bot* opponent = getFirstOpponent();
if(opponent==NULL) return;
addWave(opponent);
updateWaves(opponent);
doFire(opponent);
doMove();
}
void onRoundBegin(struct RoundBeginAction* action)
{
//清除上一轮发射的波
int i;
for(i=0; i<WAVE_SIZE; i++)
waves[i].active = 0;
}
int getIndex(double bearing)
{
return FACTOR_SIZE/2+(int)(bearing/BEARING_GAP);
}
int getHeightestIndex(int statist)
{
int heightestIndex = 0;
int i;
for(i=0; i<FACTOR_SIZE; i++)
{
if(statists[statist].factors[i]>statists[statist].factors[heightestIndex])
{
heightestIndex = i;
}
}
return heightestIndex;
}
void rate(int statist, double bearing)
{
int i;
statists[statist].factors[getIndex(bearing)]+=0.01;
for(i=0; i<FACTOR_SIZE; i++)
statists[statist].factors[i] *= 0.99;
}
double getBestFireBearing(int statist)
{
return (getHeightestIndex(statist)-FACTOR_SIZE/2)*BEARING_GAP;
}
void addWave(struct Bot* bot)
{
int wave = getNextWave();
if(wave<0) return;
waves[wave].active = 1;
waves[wave].statist = getStatist(bot);
waves[wave].center = heading(getX(), getY(), bot->x, bot->y);
waves[wave].startX = getX();
waves[wave].startY = getY();
waves[wave].startTime = getTime();
waves[wave].velocity = getBulletVelocity(POWER);
}
void updateWaves(struct Bot* bot)
{
int i;
for(i=0; i<WAVE_SIZE; i++)
{
if(waves[i].active)
{
updateWave(i, getTime(), bot->x, bot->y);
}
}
}
void updateWave(int wave, long time, double x, double y)
{
//检查是否撞到了对手
double d1 = distance(waves[wave].startX, waves[wave].startY, x, y);
double d2 = waves[wave].velocity*(time-waves[wave].startTime);
//hited!!
if(d2>=d1)
{
double h = heading(waves[wave].startX, waves[wave].startY, x, y);
//计算开火的夹角
double b = bearing(h, waves[wave].center);
//更新这个夹角的命中率
rate(waves[wave].statist, b);
waves[wave].active = 0;
}
}
int getNextWave(void)
{
int i;
for(i=0; i<WAVE_SIZE; i++)
{
if(!waves[i].active) return i;
}
return -1;
}
int getStatist(struct Bot* bot)
{
double d = distance(getX(), getY(), bot->x, bot->y);
return (int)(d/DISTANCE_GAP);
}
void doMove(void)
{
//移动到场地的中央
moveTo(getCourtWidth()/2, getCourtHeight()/2);
}
void doFire(struct Bot* bot)
{
if(getFirePrepareTime()<=0)
{
int statist = getStatist(bot);
double b = getBestFireBearing(statist);
double h = heading(getX(), getY(), bot->x, bot->y);
fire(h+b, POWER);
}
}
/**
* 机器人程序入口
*/
int main(int argC, char* argV[])
{
tickHook = onTick;
roundBeginHook = onRoundBegin;
return startup(argC, argV);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -