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

📄 statistfire.c

📁 偶然收集到的一个C语言源码
💻 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 + -