robocode 相关的总结

article/2025/6/22 18:41:24

基础知识

1. heading 角度系

如图所示,所谓heading角,即从Y轴出发,然后顺时针绕回Y轴的这么个角度区间,取值范围: [0,360]

2. bearing角度系

所谓bearing 角,即从Y轴顺、逆时针出发,绕半圈回到Y轴所形成的两个角度区间,取值范围:顺时针[0,180) ;逆时针[0,-180]

实例分析

说明:

e.getBearingRadians(),如图中的∠FBC所示

是敌机(Enemy)与自己车头方向(你使用setAhead(正值)前进的方向即为车头方向,如BC箭头所示)所成的角,因为是以BC为Y轴的bearing角,所以这个角在这个例子中是个负值。

getHeadingRadians(),如图中∠ABC所示

是以自己的车头方向与屏幕垂直正上方为Y轴所成的heaing角。

absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());

所以absBearing角即为∠FBA,即自己与敌机的连线,与Y轴所成的bearing角,取值范围为[-180,180)。
 

相应的代码

 public void onScannedRobot(ScannedRobotEvent e) {//注意 这里的计算都以弧度为单位double absBearing=0d;//雷达转动角度double radarTurnAngle=0d;//得到绝对角度差
absBearing=robocode.util.Utils.normalRelativeAngle(e.getBearingRadians()+getHeadingRadians());//根据absBearing角算出Radar要调整的角度radarTurnAngle=Math.sin(absBearing - getRadarHeadingRadians());//转动雷达,注意是向右setTurnRadarRightRadians(radarTurnAngle);}

雷达锁定

我们要写这样一个代码,它将让敌人逃不出我们的眼睛。雷达锁定是一个高效战斗机器人的基础,因为robot只有执行onScannedRobot方法,我们才能够获取敌人的信息,而onScannedRobot方法只有在我们的雷达扫描到敌人之后才会被调用,当然,调用的过程是自动的。

雷达的扫描实际上是一条线,当扫描线扫描到目标时,触发onScannedRobot事件,更新当前数据,包括direction。当程序执行到onScannedRobot内的代码时,雷达扫描线的角度getRadarHeadingRadians()已经和direction有所偏离。为了锁定目标,我们可以把雷达往反方向扫描。因为雷达旋转很快,而且getRadarHeadingRadians()和direction的偏移量不大,机器人是有一定大小的。于是扫描线在目标身上来回扫动,实现了雷达锁定。

public void onScannedRobot(ScannedRobotEvent e) {enemy.update(e,this);doubleOffset = rectify( enemy.direction-getRadarHeadingRadians() );setTurnRadarRightRadians( Offset * 1.5);}

这是我们的onScannedRobot方法,enemy.updata(e,this);是调用我们的enemy对象里面的方法,更新敌人信息,当然,忘了一点,在这之前,我们需要生成一个enemy对象,具体方法为:

Enemy enemy = new Enemy();

这里我们还要解释一下rectify方法,它的作用是对角度进行修正,因为direction减去我们雷达的朝向,有可能会大于180度或者小于-180度,比如当大于180度时,我们所需要转动的角度并不需要那么大,只需方向转一个角度就可以了。这个rectify方法很简单,当在后面应用很多。它的代码为:

	public double rectify(double angle){System.out.println("angle:"+angle);if (angle < -Math.PI)angle += 2 * Math.PI;if (angle > Math.PI)angle -= 2 * Math.PI;return angle;}

在代码中,enemy.direction -getRadarHeadingRadians()是雷达所要旋转的偏移量。假设之前雷达顺时针扫描,那么enemy.direction略小于getRadarHeadingRadians(),为负。经rectify()方法修正后即为需要转动的值。然后用setTurnRadarRightRadians旋转雷达,旋转度数为偏移的1.5倍,因为RadarOffset为负,故反方向扫描,保证无论目标

如何移动,扫描线始终在目标身上。上面的1.5可以改成2,3等数。当你在Options中打开了Visible Scan Arcs选项后,就可以看到绿色的扇形,倍数为1.5的时候,类似一条线,而倍数为2,3的时候就可以看到像是一个扇形。

另外我们还要说一下另外两段代码:

setAdjustGunForRobotTurn( true );
setAdjustRadarForGunTurn( true );

它们的作用是使雷达、大炮、车身运动独立,具体参考API手册。

到这里我们雷达扫描的代码就完成了,运行试试我们的“观察者号”吧!!

完整代码

package com;import java.awt.Color;
import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;public class ObserverRobot extends AdvancedRobot {Enemy enemy = new Enemy();public static double PI = Math.PI;public void run() {setAdjustGunForRobotTurn(true);setAdjustRadarForGunTurn(true);this.setColors(Color.red, Color.blue, Color.yellow, Color.black, Color.green);while (true) {if (enemy.name == null) {setTurnRadarRightRadians(2 * PI);execute();}else {execute();}}}public void onScannedRobot(ScannedRobotEvent e){enemy.update(e, this);double Offset = rectify(enemy.direction - getRadarHeadingRadians());setTurnRadarRightRadians(Offset * 1.5);}// 角度修正方法,重要public double rectify(double angle){if (angle < -Math.PI)angle += 2 * Math.PI;if (angle > Math.PI)angle -= 2 * Math.PI;return angle;}public class Enemy {public double x, y;public String name = null;public double headingRadian = 0.0D;public double bearingRadian = 0.0D;public double distance = 1000D;public double direction = 0.0D;public double velocity = 0.0D;public double prevHeadingRadian = 0.0D;public double energy = 100.0D;public void update(ScannedRobotEvent e, AdvancedRobot me) {name = e.getName();headingRadian = e.getHeadingRadians();bearingRadian = e.getBearingRadians();this.energy = e.getEnergy();this.velocity = e.getVelocity();this.distance = e.getDistance();direction = bearingRadian + me.getHeadingRadians();x = me.getX() + Math.sin(direction) * distance;y = me.getY() + Math.cos(direction) * distance;}}}

敌方坦克坐标预测

完整代码

...

AdvancedRobot类中相应的API解读

1. getHeadingRadians

public double getHeadingRadians()

Returns the direction that the robot's body is facing, in radians. The value returned will be between 0 and 2 * PI (is excluded).

Note that the heading in Robocode is like a compass, where 0 means North, PI / 2 means East, PI means South, and 3 * PI / 2 means West.

Overrides:

getHeadingRadians in class _AdvancedRadiansRobot

Returns:

the direction that the robot's body is facing, in radians.

疑问

I want to fire a bullet every turn, but I can't. Why?

Every time you fire, the gun generates some heat. You must wait till it is cool again to fire. If you give a fire order when your gun is hot, it will do nothing. The heat generated by a shot is 1 + (firepower / 5). The gun cools down at a default rate of 0.1 per turn (note that you can change this parameter when you run the battle, but nobody usually does). It means you can fire a 3.0 power bullet every 16 ticks.

See Rules.getGunHeat() and Robot.getGunCoolingRate().

What is the difference between the setXXX() (e.g. setFire()) and the XXX() (e.g. fire()) methods?

Basically, the setXXX() methods just notify Robocode to take some action at the end of the turn. The XXX()-type methods end the turn when you call them, and they block your robot's thread until the command finishes. Unless you have a good reason, you should almost always use the setXXX() version when writing AdvancedRobots.

What is the difference between a set method like setAhead() and ahead() without the set-prefix?

The difference between a method like ahead(), and the method setAhead() is that set-methods are only available with the AdvancedRobot. The difference is that you can call multiple setters like e.g. setAhead()setTurnGunLeft(), and setFire() in the same turn. These set commands will first take effect, i.e. execute, when you call the execute() method explicitly in a turn. Methods that are not setters like e.g. ahead()turnGunLeft(), and fire() will execute independently and take one to many turns to complete, as one command will need to execute and complete before the next command is being executed. Setters are called in the same turn when execute() is called. So the method ahead() is actually the same as setAhead() + execute(), and in that order. The set methods can be seen as "fire and forget" methods that are executed immediately, whereas the methods like ahead() must first complete its movement, turning, firing etc. before the next command is being run. Hence those commands need to wait for the other commands to complete first before the method itself will be executed.

How fast can I turn my gun?

The gun turns at 20 degrees per tick.

See Rules.GUN_TURN_RATE.

How fast can I turn my radar?

It turns 45 degrees per tick.

See Rules.RADAR_TURN_RATE.

What are ticks, turns, and frames?

A tick refers to one unit, which is also called a turn in Robocode. During one turn, you may perform one action as a Robot, or multiple (independent) actions as an AdvancedRobot. A frame is a unit of drawing to the Robocode client interface. If you are processing turns slowly, you will get one frame per tick / turn. However, if you up the turns per second beyond your computer's ability to render the frames, you will miss some frames of animation. This won't affect the robots' behavior, unless you foolishly added code in your onPaint(Graphics2D) method that alters your bots behavior. In that case, your bot will behave differently depending on whether or not the Paint button has been enabled, and if the framerate can keep up with the turnrate.

参考资料

Robowiki

Robocode教程7——雷达锁定_dawnsun001的博客-CSDN博客Robocode中一个高效雷达的学习记录_lihe758的博客-CSDN博客_雷达 heading angle

https://github.com/robo-code/robocode/blob/master/robocode.api/src/main/java/robocode/AdvancedRobot.java


http://chatgpt.dhexx.cn/article/nuceqADU.shtml

相关文章

世界robocode机器人的四大运动方式分析

摘要&#xff1a;前言Robocode在短短的时间内风靡全球,全世界的robocode爱好者设计出了大量的优秀智能机器人,他们都拥有各自的运动方式,有的很轻易被击中,有的却很难射击。设计一个好的运动方式是优秀robocode机器人取胜的要害。上届世界中级组冠军Fermat就是靠他让敌人难以琢…

Robocode教程1——安装、运行、配置

Robocode 的安装 系统安装最小环境要求&#xff1a; CPU:Pentium2/400MHz以上 内存:64MB以上 硬盘&#xff1a;10M以上 对硬件要求也不是完全绝对的&#xff0c;你用小的机器配置&#xff0c;带来的是比较慢的运行速度。当然具备以上硬件条件后&#xff0c;还要具有Java运行环…

笔记:Istio 组件 基础概念学习

文章目录 1. Istio是什么&#xff1f;1.1 读音1.2 简介1.3 服务网格是什么&#xff1f;1.4 为什么使用Isito&#xff1f;1.5 Istio 是如何诞生的?1.6 为什么我想用 ISTIO&#xff1f;1.7 目前Istio支持哪些部署环境&#xff1f;1.8 架构1.8.1 组件1.8.1.1 Envoy1.8.1.2 Pilot1…

Notes Sixth day-渗透攻击-红队-打入内网

** Notes Sixth day-渗透攻击-红队-打入内网(dayu) ** 作者&#xff1a;大余 时间&#xff1a;2020-09-22 请注意&#xff1a;对于所有笔记中复现的这些终端或者服务器&#xff0c;都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技…

Notes Ninth Day-渗透攻击-红队-打入内网

** Notes Ninth Day-渗透攻击-红队-打入内网(dayu) ** 作者&#xff1a;大余 时间&#xff1a;2020-09-25 请注意&#xff1a;对于所有笔记中复现的这些终端或者服务器&#xff0c;都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技…

Notes Fifth Day-渗透攻击-红队-信息收集

** Notes first day-渗透攻击-红队-信息收集(dayu) ** 作者&#xff1a;大余 时间&#xff1a;2020-09-20 请注意&#xff1a;对于所有笔记中复现的这些终端或者服务器&#xff0c;都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技…

Notes Fifteenth Day-渗透攻击-红队-内部信息搜集

** Notes Fifteenth Day-渗透攻击-红队-内部信息搜集(dayu) ** 作者&#xff1a;大余 时间&#xff1a;2020-10-1 请注意&#xff1a;对于所有笔记中复现的这些终端或者服务器&#xff0c;都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里…

多个容器一起打包_容器快速入门完全指南

介 绍 容器&#xff0c;以及Docker和Kubernetes之类的容器技术已经日益成为许多开发人员工具包中常见的工具。容器化的核心目标是提供一种更好的方式&#xff0c;以可预测和便于管理的方式在不同的环境中创建、打包以及部署软件。 在本文中&#xff0c;我们将一窥什么是容器&am…

项目经验123

DDDRPC架构 DDD分层架构介绍 DDD&#xff08;Domain-Driven Design 领域驱动设计&#xff09;&#xff0c;目的是对软件所涉及到的领域进行建模&#xff0c;以应对系统规模过大时引起的软件复杂性的问题。开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消…

区块链详解

一、比特币简介 区块链&#xff08;Blockchain&#xff09;技术源于比特币。在比特币中&#xff0c;为了保证每笔交易可信并不可篡改&#xff0c;中本聪发明了区块链&#xff0c;它通过后一个区块对前一个区块的引用&#xff0c;并以加密技术保证了区块链不可修改。 随着比特…

网络安全面试题目及详解

获取目标站点的绝对路径 如果是iis系统,尝试对参数进行恶意传值,使其出现报错页面对目标网站进行js代码审计,查看是否存在信息泄露出站点的绝对路径使用字典猜解目标站点的绝对路径如果目标是thinkphp框架,尝试访问无效的路径,或者对参数进行而已传值使其报错phpinfo页面泄露站…

云计算基础教程(第2版)笔记——基础篇与技术篇介绍

文章目录 前言 第一篇 基础篇 一 绪论 1.1 云计算的概念以及特征 1.1.1云计算的基本概念 1.1.2云计算的基本特征 1.2 云计算发展简史 1.3 三种业务模式介绍 1. 基础设施即服务&#xff08;IaaS&#xff09; 2. 平台即服务&#xff08;PaaS&#xff09; 3. 软…

2023年网络安全面试题(渗透测试):详细答案解析与最佳实践分享

如果在数据来源和网络分享方面存在侵权问题&#xff0c;请立即联系我以删除相关内容。 一、一句话木马 1、基本原理 通过利用存在文件上传漏洞的目标网站&#xff0c;将恶意的一行代码或脚本&#xff08;通常是PHP语言&#xff09;上传到目标服务器上&#xff0c;从而实现对…

一到两年工作经验的看完这些面试轻松拿offer

Java基础面试题 1、面向对象的特征有哪些方面 面向对象的特征主要有以下几个方面&#xff1a; 抽象&#xff1a;抽象是将一类对象的共同特征总结出来构造类的过程&#xff0c;包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为&#xff0c;并不关注这些行为的细…

容器快速入门完全指南

介 绍 容器&#xff0c;以及Docker和Kubernetes之类的容器技术已经日益成为许多开发人员工具包中常见的工具。容器化的核心目标是提供一种更好的方式&#xff0c;以可预测和便于管理的方式在不同的环境中创建、打包以及部署软件。 在本文中&#xff0c;我们将一窥什么是容器&a…

JavaWeb编年史(黄金时代)

从JavaWeb编年史的远古时代&#xff0c;一直到白银时代&#xff0c;我们见证了JavaWeb开发模式的大致变迁。说白了&#xff0c;就是不断解耦合的过程。接下来我们来聊聊项目架构的演变&#xff0c;之所以我把它划到了JavaWeb编年史&#xff08;黄金时代&#xff09;&#xff0c…

Docker、Podman 容器“扫盲“ 学习笔记【与云原生的故事】

【摘要】 笔记内容&#xff1a;由理论和具体docker常用操作构成。这篇博文笔记的定位是&#xff1a;温习&#xff0c;查阅&#xff0c;不适合新手学习。你拥有青春的时候&#xff0c;就要感受它&#xff0c;不要虚掷你的黄金时代&#xff0c;不要去倾听... 写在前面 笔记内容…

Docker、Podman 容器“扫盲“ 学习笔记

写在前面 之前只是做毕业设计时&#xff0c;接触一点&#xff0c;用DockFile在阿里云上部署了毕设。后来docker端口问题&#xff0c;机器被植入木马&#xff0c;拉去挖矿&#xff0c;cup天天爆满&#xff0c;百度半天删了好多文件不管用&#xff0c;后来恢复镜像了&#xff0c…

大数据-1

1、什么是大数据&#xff1f;特点&#xff1f; 大数据&#xff08;英语&#xff1a;Big data&#xff09;&#xff0c;又称为巨量资料&#xff0c;指的是传统数据处理应用软件不足以处理它们的大或复杂的数据集的术语。在总数据量相同的情况下&#xff0c;与个别分析独立的小型…

大数据(2)

案例3 有一个包含20亿个全是32位整数的大文件&#xff0c;在其中找到出现次数最多的数&#xff0c;但内存限制只有2G 解决思路 下再用哈希表依次处理各个文件&#xff0c;统计每种数出现的次数&#xff0c;此时肯定不会溢出。 案例4 先分析哈希表思路&#xff1a;…