?? 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 + -