稍微复杂一点的瞄准算法-直线瞄准算法

package jiaqi;

import java.awt.geom.Point2D;

import robocode.AdvancedRobot;
import robocode.Rules;
import robocode.ScannedRobotEvent;

public class MyDemoRobot extends AdvancedRobot{

	/**
	 * 扫描到敌人的时间
	 */
	private double time1 = 0;
	private Enemy enemy = new Enemy();
	private boolean discover = false;// 敌人是否被发现属性
	private double heading = 0.0;
	private double radarHeading = 0.0;
	private double bPower = 3;
	private double time = 0; // 子弹飞行时间
	private double distance = 3000;// 敌人即将到达的位置的距离

	@Override
	public void onScannedRobot(ScannedRobotEvent e) {
		discover = true;// 发现敌人
		time1 = getTime();

		// 初始化敌人
		enemy.setBearing(e.getBearingRadians());
		enemy.setSpeed(e.getVelocity());
		enemy.setDistance(e.getDistance());
		enemy.setHeading(e.getHeadingRadians());

		time = distance / Rules.getBulletSpeed(bPower);
	}

	/**
	 * 打扮
	 */
	private void dressing() {
	}

	/**
	 * 车炮和雷达分离
	 */
	private void severance() {
		setAdjustGunForRobotTurn(true);
		setAdjustRadarForGunTurn(true);
	}

	/**
	 * 最简单的移动算法
	 */
	private void simpleMove() {
		double increment = 0;
		if (enemy.getBearing() > 0) {
			increment = Math.PI / 2 - enemy.getBearing();
			setTurnLeftRadians(increment);
		} else {
			increment = Math.PI / 2 + enemy.getBearing();
			setTurnRightRadians(increment);
		}
		setAhead(1000);
	}

	/**
	 * 安全距离
	 */
	private double safDis = 100;

	/**
	 * 移动
	 */
	private void movement() {
		if (getDistanceRemaining() < 1) {
			double nx = 0;
			double ny = 0;
			// 计算一个随机的安全的X,Y坐标
			nx = Math.random() * (getBattleFieldWidth() - 2 * safDis) + safDis;
			ny = Math.random() * (getBattleFieldHeight() - 2 * safDis) + safDis;

			double headArg = 90 - Math.atan2(ny - getY(), nx - getX());// 计算我们车身要旋转的角度
			headArg = getPA(headArg);
			double dis = Point2D.distance(getX(), getY(), nx, ny);// 计算我们的机器人移动的距离

			if (headArg - getHeadingRadians() > Math.PI / 2) {
				setTurnRightRadians(headArg - getHeadingRadians() + Math.PI);
				setAhead(-dis);
			} else {
				setTurnRightRadians(headArg - getHeadingRadians());
				setAhead(dis);
			}
		}
	}

	/**
	 * 雷达锁定敌人
	 */
	private void doScan() {
		// 判断是否扫描到敌人
		if (discover) {
			// 计算雷达旋转的角度
			heading = this.getHeadingRadians();
			radarHeading = this.getRadarHeadingRadians();
			double temp = radarHeading - heading - enemy.getBearing();
			// 处理异常角度
			temp = correctAngle(temp);
			temp *= 1.2;
			// 设置机器人的雷达回扫
			setTurnRadarLeftRadians(temp);
			// 开始执行机器人运行的设置

		}
	}

	/**
	 * 选择火力
	 */
	private double firePower() {

		return bPower;
	}

	private double correctAngle(double scan) {
		scan %= 2 * Math.PI;// 防止出现大于360度的角
		if (scan > Math.PI) {
			scan = -(2 * Math.PI - scan);// 计算出角度取负为了让雷达反方向旋转
		}
		if (scan < -Math.PI) {
			scan = 2 * Math.PI + scan;
		}
		return scan;
	}

	/**
	 * 直接瞄准
	 */
	private double immidate() {
		double increment = heading + enemy.getBearing()
				- getGunHeadingRadians();
		increment %= 2 * Math.PI;
		increment = correctAngle(increment);
		return increment;
	}

	/**
	 * 调炮
	 */
	private void gun() {
		// double increment = immidate();
		double increment = line();
		setTurnGunRightRadians(increment);

	}

	/**
	 * 获得正角的方法
	 *
	 * @return
	 */
	private double getPA(double angle) {
		angle %= 2 * Math.PI;
		if (angle < 0) {
			angle += 2 * Math.PI;
		}
		return angle;
	}

	/**
	 * 直线瞄准
	 *
	 * @return
	 */
	private double line() {
		// 计算出敌人即将出现的坐标
		// 1. 计算敌人目前的坐标
		double ea = getPA(getHeadingRadians() + enemy.getBearing());// 敌人的所在方向角度
		double ex = getX() + enemy.getDistance() * Math.sin(ea);// 敌人目前的X坐标
		double ey = getY() + enemy.getDistance() * Math.cos(ea);// 敌人目前的Y坐标

		// 2. 计算敌人即将运动距离
		double s = 0;// 保存敌人运动距离
		if (enemy.getSpeed() >= Rules.MAX_VELOCITY - 0.1) {
			s = enemy.getSpeed() * time;
		} else if (enemy.getSpeed() > 0.0) {
			double as = (Math.pow(Rules.MAX_VELOCITY, 2) - Math.pow(
					enemy.getSpeed(), 2))
					/ 2 * Rules.ACCELERATION;// 加速运动的距离
			double vs = (time - (Rules.MAX_VELOCITY - enemy.getSpeed())
					/ Rules.ACCELERATION)
					* Rules.MAX_VELOCITY;// 匀速运动的距离
			s = as + vs;
		} else {
			s = 0.0;
		}

		// 3. 计算敌人即将出现的坐标
		double nextx = ex + s * Math.sin(enemy.getHeading());
		double nexty = ey + s * Math.cos(enemy.getHeading());
		distance = Point2D.distance(getX(), getY(), nextx, nexty);
		double t = Math.atan2(nexty - getY(), nextx - getX());// 计算敌人即将到达位置的角度

		return correctAngle((Math.PI / 2 - t - getGunHeadingRadians())
				% (2 * Math.PI));
	}

	public void run() {
		// 第一步:要给机器人一身漂亮的行头,车身,炮和雷达及扫描弧要着上独特的颜色。
		dressing();
		// 第二步:要让机器人的车炮和雷达分离,互不影响。高级机器人都这样做。
		severance();
		// 让雷达先转一圈,以触发雷达扫描事件
		// setTurnRadarLeft(400);
		// execute();
		while (true) {
			if (!discover) {
				setTurnRadarLeftRadians(Math.PI * 2.1);
				execute();
			} else {
				// 第三步:要确定机器人如何移动的算法
				movement();
				// 第四步:要确定机器人如何选择火力的算法
				double fire = firePower();
				// 第五步:要确定机器人如何锁定其它机器人的算法
				doScan();
				// 第六步:要确定机器人如何计算角度并调整炮口瞄准敌人的算法
				gun();
				// if (getGunTurnRemaining() <= 0) {
				// 开枪
				setFire(fire);
				execute();
				// }
				// 判断敌人是否丢失
				loseTarget();
				execute();
			}
		}
	}

	/**
	 * 判断是否丢掉敌人
	 *
	 */
	private void loseTarget() {
		if ((getTime() - time1) >= 4)
			discover = false;
	}

}
======================================
package jiaqi;

public class Enemy {

	private double bearing;//自己与敌人的夹角
	private double distance;//与敌人的距离
	private double heading;
	private double velocity;

	private double speed;

	public double getSpeed() {
		return speed;
	}
	public void setSpeed(double speed) {
		this.speed = speed;
	}
	public double getBearing() {
		return bearing;
	}
	public void setBearing(double bearing) {
		this.bearing = bearing;
	}
	public double getDistance() {
		return distance;
	}
	public void setDistance(double distance) {
		this.distance = distance;
	}
	public double getHeading() {
		return heading;
	}
	public void setHeading(double heading) {
		this.heading = heading;
	}
	public double getVelocity() {
		return velocity;
	}
	public void setVelocity(double velocity) {
		this.velocity = velocity;
	}

}

  

时间: 2024-12-21 01:53:51

稍微复杂一点的瞄准算法-直线瞄准算法的相关文章

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

一.首先说明: 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线):②种子填充法(即:填充多边形):③扫描线填充法 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用.这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现:另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的. 是啥样? ——  如下面的操作,不言而喻. 二.进入正题: 2-1.直线的扫描转换 图形的扫描转换实质就是在光栅

直线拟合算法(续)

直线拟合算法(续) 曾经写过一篇博客.介绍直线拟合算法. http://blog.csdn.net/liyuanbhu/article/details/50866802 给出的代码事实上有一点小问题,就是 den = 0 时会出现除以 0 的错误. 今天正好也有网友问起这个问题. 我就再写一篇短文来说说怎样解决问题. 首先我们知道: den=D2xy+(λ?Dxx)2??????????????√ 那么 den=0 意味着: Dxy=0λ=Dxx 我们还有关于 λ 的计算式: λ=Dxx+Dyy

opengl实现直线扫描算法和区域填充算法

总体介绍 1.   使用线性扫描算法画一条线,线性离散点 2.   利用区域填充算法画多边形区域,区域离散的点 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel HD Graphics Family 设计思路 一.直线扫描算法 1.数值微分法(DDA) 已知过端点P0 (x0, y0), P1(x1, y1)的直线段L:y = kx + b,easy得知直线斜率为:k = (y1-y0)/(x1-x0).(如果x1≠x0). 我们如果|k|≤1,这样x每添加1

程序员生存定律--如何尽快变的稍微专业一点

程序员生存定律这系列的目录在这里:程序员生存定律--目录 喜欢从头瞄的,可以移步. ------------------------------------------------------------------------------- 1 掌握读代码的方法和技巧 不管最终想成为什么,刚入行之后,一定离不开的是读代码和写代码.这里将介绍一些读代码的方法和技巧. 读代码这事,先要分是精读还是泛读.从学习的目的来看,一定要精读一定量的经典代码.而精读是指每行都读懂,不看代码脑子里就能勾画出程序

清华版CG 实验2 直线生成算法实现

1.实验目的: 理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.实验内容: (1) 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果: (2) 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告: (3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告: (4) 了解和使用OpenGL的生成直线的命令,来验证程序运行结果. 3.实验原理: 示范代码原理参见教材直线

霍夫直线检测算法进行树干提取

霍夫直线检测算法进行树干提取 霍夫直线检测是常用的直线检测算法,原理比较简单. 我叙述一下我对霍夫直线检测算法的理解:将像素点在图像中的二维坐标,通过坐标变换转化为极坐标,然后通过比较每个点在极坐标下的角度值,如果角度值相同,则判定为同直线. 该算法有几个可调参数: C++: void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLe

有序链表合并C语言递归版--我稍微会一点编程

假期最后一天,闲着没事编个程,天天吆喝自己不会编程,其实还是稍微会一点的. ??以下是一个有序链表合并的代码,一刻钟内盲写,花了10分钟左右调试通过,通篇只有一个if语句作为递归退出条件! #include <stdio.h> #include <stdlib.h> int a[] = {1,3,5,7,8,10,11,12,15,19,21,22,24,25,26}; int b[] = {2,4,5,6,9,16,17,18,27,30,31}; struct list { s

稍微学一点项目管理

稍微学一点项目管理的相关知识. 项目管理是管理什么 项目管理的主要内容是交付管理.客户管理.人员管理和过程管理. 交付管理. 说白了就是要保证项目的按时交付,为了达到这样的目的,作为项目负责人需要关注交付范围.预算.人员计划和发布计划,并且需要实时监控项目进展,评估是否有潜在风险并给出应对措施. 客户管理. 有些团队可能没有我们平常意义上的客户,但是每一个客户都有一个广义上的客户.你可以认为你是Boss就是你的客户,或者是说甲方就是一个客户.作为团队的管理者,客户的所有沟通.合作都是你的职责.

数据挖掘算法之k-means算法

系列文章:数据挖掘算法之决策树算法 [QQ群: 189191838,对算法和C++感兴趣可以进来]       k-means算法可以说是数据挖掘中十大经典算法之一了,属于无监督的学习.该算法由此衍生出了很多类k-means算法,比如k中心点等等,在数据挖掘领域,很多地方都会用到该算法,他能够把相似的一类很好的聚在一起.一类指的是,他们之间的相似度较高,计算相似度的常用度量有欧氏距离.余弦定理等.本算法采用的是欧式距离度量.这个对理解k-means算法不会造成任何实质性的影响. 为了更好的说明k