标题:Robocode介绍
只看楼主
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
结帖率:90.32%
 问题点数:0 回复次数:10 
Robocode介绍
Robocode是2001年7月在美国IBM 的Web alphaWorks上发布的坦克机器人战斗仿真引擎。与通常玩的游戏不同的是:参赛者必须利用对机器人进行编程,给机器人设计智能来自动指挥它,而不是由键盘、鼠标简单地直接控制。Robocode是一种有趣的竞赛性编程,使用几行简单的代码,就能够让你创建一个活生生的机器人,一个真正的在屏幕上与其他机器人互相对抗的机器人。你可以看到它在屏幕上四处疾驰,碾碎一切挡道的东西。机器人配有雷达与火炮,选手在躲避对手进攻的同时攻击对手,以此来较量得分的多少。Robocode可以让你在娱乐的同时学习与提高Java技术。

http://robocode.
搜索更多相关主题的帖子: Robocode 
2010-03-04 17:45
gameohyes
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:53
帖 子:1275
专家分:3629
注 册:2009-3-5
得分:0 
Robocode是2001年7月
哇这么早

C#超级群 74862681,欢迎大家的到来!
2010-03-05 00:16
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
得分:0 
以下是引用gameohyes在2010-3-5 00:16:12的发言:

Robocode是2001年7月
哇这么早
最新版本是
Robocode 1.7.2.0-Beta
有时间大家比赛一下,看谁的坦克最利害,呵呵

你的优秀和我的人生无关!!!!
    
    我要过的,是属于我自己的生活~~~
2010-03-05 11:09
wangking1029
Rank: 2
等 级:论坛游民
威 望:1
帖 子:10
专家分:41
注 册:2009-8-24
得分:0 
版主有没有这个东西的入门说明或教程一类的东西啊,发给我一份吧wangking1029@谢谢了
2010-03-05 20:26
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
得分:0 
 首先访问 IBM alphaWorks Robocode 页面,在这个页面上,找到 Robocode 系统最新的可执行文件。这个分发包是一个自包含的安装文件,在下载该分发包之后,就可以使用下面的命令行在系统上安装这个软件包(当然,我们假定您的机器上已经预安装了 Java VM(JDK 1.3.x)以上的版本)。

java -jar robocode-setup.jar

  在安装过程中,Robocode 将问您是否要使用这个外部的 Java VM 来编译机器人。您也可以选择使用作为 Robocode 分发包一部分而提供的 Jikes 编译器。

  当激活 Robocode 时,将看到两个相关的 GUI 窗口,这两个窗口构成了 Robocode 的 IDE:

战场
Robot Editor
  战场是机器人之间进行战斗直至分出胜负的场地。主要的仿真引擎被置于其中,并且允许在这里创建战斗、保存战斗以及打开新建的或现有的战斗。通过界面区域内的控件,可以暂停或继续战斗、终止战斗、消灭任何机器人个体或获取任何机器人的统计数据。此外,可以在此屏幕上激活 Robot Editor。

  Robot Editor 是一个定制的文本编辑器,它可以用于编辑生成机器人的 Java 源文件。在它的菜单里集成了 Java 编译器(用于编译机器人代码)以及定制的 Robot 打包器。由 Robot Editor 创建并成功编译的所有机器人都会处于战场上一个部署就绪的位置。(个人认为它所提供的文本编辑器不怎么好,最后还是用jb来编辑,只要在Requird Libraries 加入解压缩后的robocode.jar就可以了)

  Robocode 里的每个机器人都由一个或多个 Java 类构成。这些类可以被压缩成一个 JAR 包。为此,Robocode 的最新版本提供了一个可以在战场 GUI 窗口中激活的“Robot Packager”。

  Robocode 机器人是一个图形化的坦克,请注意,机器人有一门可以旋转的炮,炮上面的雷达也是可以旋转的。机器人坦克车(Vehicle)、炮(Gun)以及雷达(Radar)都可以单独旋转,也就是说,在任何时刻,机器人坦克车、炮以及雷达都可以转向不同的方向。缺省情况下,这些方向是一致的,都指向坦克车运动的方向。

附:Robot 命令
  Robocode 机器人的命令集都收录在 Robocode API Javadoc 中。这些命令都是 robocode.Robot 类的公共方法。

(1)移动机器人、炮和雷达

  移动机器人及其装备的基本命令:

turnRight(double degree) 和 turnLeft(double degree) 使机器人转过一个指定的角度。
ahead(double distance) 和 back(double distance) 使机器人移动指定的像素点距离;这两个方法在机器人碰到墙或另外一个机器人时即告完成。
turnGunRight(double degree) 和 turnGunLeft(double degree) 使炮可以独立于坦克车的方向转动。
turnRadarRight(double degree) 和 turnRadarLeft(double degree) 使炮上面的雷达转动,转动的方向也独立于炮的方向(以及坦克车的方向)。
  这些命令都是在执行完毕后才把控制权交还给程序。此外,转动坦克车的时候,除非通过调用下列方法分别指明炮(和雷达)的方向,否则炮(和雷达)的指向也将移动。

setAdjustGunForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车转动时,炮保持原来的方向。
setAdjustRadarForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车(和炮)转动时,雷达会保持原来的方向。
setAdjustRadarForGunTurn(boolean flag):如果 flag 被设置成 true,那么炮转动时,雷达会保持原来的方向。而且,它执行的动作如同调用了 setAdjustRadarForRobotTurn(true)。
(2)获取关于机器人的信息

getX() 和 getY() 可以捕捉到机器人当前的坐标。
getHeading()、getGunHeading() 和 getRadarHeading() 可以得出坦克车、炮或雷达当前的方向,该方向是以角度表示的。
getBattleFieldWidth() 和 getBattleFieldHeight() 可以得到当前这一回合的战场尺寸。

(3)射击命令

  一旦掌握了移动机器人以及相关的武器装备的方法,我们就该考虑射击和控制损害的任务了。每个机器人在开始时都有一个缺省的“能量级别”,当它的能量级别减小到零的时候,我们就认为这个机器人已经被消灭了。射击的时候,机器人最多可以用掉三个能量单位。提供给炮弹的能量越多,对目标机器人所造成的损害也就越大。 fire(double power) 和 fireBullet(double power) 用来发射指定能量(火力)的炮弹。调用的 fireBullet() 版本返回 robocode.Bullet 对象的一个引用,该引用可以用于高级机器人。(也就是说,当你确定能击中对方,火力越大越好咯^_^)

(4)事件

  每当机器人在移动或转动时,雷达一直处于激活状态,如果雷达检测到有机器人在它的范围内,就会触发一个事件。作为机器人创建者,我们有权选择处理可能在战斗中发生的各类事件。基本的 Robot 类中包括了所有这些事件的缺省处理程序。但是,们可以覆盖其中任何一个“什么也不做的”缺省处理程序,然后实现自己的定制行为。下面是一些较为常用的事件:

ScannedRobotEvent。通过覆盖 onScannedRobot() 方法来处理 ScannedRobotEvent;当雷达检测到机器人时,就调用该方法。
HitByBulletEvent。通过覆盖 onHitByBullet() 方法来处理 HitByBulletEvent;当机器人被炮弹击中时,就调用该方法。
HitRobotEvent。通过覆盖 onHitRobot() 方法来处理 HitRobotEvent;当您的机器人击中另外一个机器人时,就调用该方法。
HitWallEvent。通过覆盖 onHitWall() 方法来处理 HitWallEvent;当您的机器人撞到墙时,就调用该方法。

你的优秀和我的人生无关!!!!
    
    我要过的,是属于我自己的生活~~~
2010-03-05 20:31
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
得分:0 
 很多研究Robocode的 玩家都被其中的方向及坐标弄糊涂了。整个屏幕哪个是0度角,整个是坐标原点呢? 顺时针与逆时针的方向如何区分?

一段英文的翻译及说明:

heading - absolute angle in degrees with 0 facing up the screen, positive clockwise. 0 <= heading < 360.
bearing - relative angle to some object from your robot's heading, positive clockwise. -180 < bearing <= 180
heading:是机器人方向与屏幕正上方的角度差,方向在0到360之间.
bearing:是机器人的某个部件如雷达发现的目标与方向的角度差,顺时针为正角度在-180到180之间
几个在Robocode中很重要的概念:

坐标系:Robocode整个坐标系都是战场屏幕以左下角为原点
绝对方向系:Robocode中不管机器人在哪个方向都是以静态战场屏幕为参照的绝对角度(也即大家说的Heading),正上方为0度角。也即不管是Robot,Gun,Radar向北为0,向东为90,向南为180,向西为270。
相对方向系:相对方向是Robot,Gun,Radar以机器人的动态heading角度为参照的角度差不再以整个静态屏幕为参照了,叫它相对因为机器人的heading是随着机器人移动而不停的在改变,heaing只是个相对物体。
顺时针和逆时针是看另一机器人是在你的Heading角度的(0,180)还是(-180,0)之间。
  再次提醒:Heading是个静态角度,正上方总为0.不管是取Heading,还是取方向。Bearing是个角度差值,是由参照的Heading和发现时的Heading的差值。好了,方向的问题就说到这,欢迎大家来讨论。



你的优秀和我的人生无关!!!!
    
    我要过的,是属于我自己的生活~~~
2010-03-05 20:32
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
得分:0 
Rob例子:

double previousEnergy = 100; //初始状态对方能量为100
int movementDirection = 1; //移动方向
int gunDirection = 1; //炮管方向

/**
   * 当检测到对方Bot,触发事件
   * @param e
   */
public void onScannedRobot(ScannedRobotEvent e) {
    //调整自己和对方之间的角度
    setTurnRight(e.getBearing()+90-30*movementDirection);

    //如果对方的能量损耗一定值,进行躲避动作
    double changeInEnergy = previousEnergy - e.getEnergy();
    if (changeInEnergy>0 && changeInEnergy<=3) {
      //躲避!
      movementDirection = -movementDirection; //和上次的躲避方向相反
      setAhead((e.getDistance()/4+25)*movementDirection);
    }
    //将炮管指向对方当前位置
    gunDirection = -gunDirection;
    setTurnGunRight(99999*gunDirection);

    //射击
    fire(1);

    //重新设置对方能量
    previousEnergy = e.getEnergy();
}


你的优秀和我的人生无关!!!!
    
    我要过的,是属于我自己的生活~~~
2010-03-05 20:35
lampeter123
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:54
帖 子:2508
专家分:6424
注 册:2009-1-30
得分:0 
另外一个例子:

import robocode.*;

public class HanicBot extends AdvancedRobot{
private double eDist; //对方的距离
private double move; //移动的距离
private double radarMove = 45; //雷达移动的角度
private double dFirePower; //火力

/**
   * main func run()
   */
public void run() {
    eDist = 300;
    while(true){
      //每过一个周期,运动随机的距离
      double period = 4*((int)(eDist/80)); //周期;敌人越接近,周期越短,移动越频繁
      //周期开始,则移动
      if(getTime()%period == 0){
        move = (Math.random()*2-1)*(period*8 - 25);
        setAhead(move + ((move >= 0) ? 25: -25));
      }
      //避免撞墙
      double heading = getHeadingRadians(); //取得bot方向的弧度数
      double x = getX() + move*Math.sin(heading); //移动move后将要达到的x坐标
      double y = getY() + move*Math.cos(heading); //移动move后将要达到的y坐标
      double dWidth = getBattleFieldWidth(); //战场的宽度
      double dHeight = getBattleFieldHeight(); //战场的长度
      //当(x,y)超过指定的范围,则反向移动move
      if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
        setBack(move);
      }
      turnRadarLeft(radarMove); //转动雷达
    }
}//end run()

/**
   * 当检测到对方Bot,触发事件
   * @param e
   */
public void onScannedRobot(ScannedRobotEvent e) {
    eDist = e.getDistance(); //取得对方距离
    radarMove = -radarMove; //设置雷达
    double eBearing = e.getBearingRadians(); //取得和对方相对角度的弧度数
    //将bot转动相对的角度,以后bot的运动将是以对方为圆心的圆周运动
    setTurnLeftRadians(Math.PI/2 - eBearing);
    //转动炮管指向对方
    setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(
      getHeadingRadians() + eBearing - getGunHeadingRadians()));
    //根据对方距离射击
    dFirePower = 400/eDist;
    if (dFirePower > 3){
      dFirePower = 3;
    }
    fire(dFirePower);
}
}

  首先,为了迷惑对方,不让对方容易的得到Bot的移动规律,Bot就要在一定的时间内做出随机的运动,这个很容易办到。并且,我给Bot的运动改变时间规定了周期。这个周期随离对方的距离改变,敌人越接近,周期越短,移动越频繁。

double period = 4*((int)(eDist/80));
if(getTime()%period == 0){
move = (Math.random()*2-1)*(period*8 - 25);
setAhead(move + ((move >= 0) ? 25: -25));
}

  其次,Bot的运动不是呈直线的。而是以对方为圆心的圆周运动。

setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(
      getHeadingRadians() + eBearing - getGunHeadingRadians()));

  最后是如何避免撞墙。这里要用到点三角函数-_-!! 原理就是,计算Bot一次运动后将要达到的坐标是不是位于规定的危险区域。如果是,则立即反方向运动。

double heading = getHeadingRadians();
double x = getX() + move*Math.sin(heading);
double y = getY() + move*Math.cos(heading);
double dWidth = getBattleFieldWidth();
double dHeight = getBattleFieldHeight();
if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
setBack(move);
}


你的优秀和我的人生无关!!!!
    
    我要过的,是属于我自己的生活~~~
2010-03-05 20:36
gameohyes
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:53
帖 子:1275
专家分:3629
注 册:2009-3-5
得分:0 
回复 3楼 lampeter123
能联网玩吗?
    我应该玩不过你

C#超级群 74862681,欢迎大家的到来!
2010-03-05 20:38
llooppzhang
Rank: 7Rank: 7Rank: 7
来 自:江苏
等 级:黑侠
威 望:5
帖 子:308
专家分:518
注 册:2009-10-18
得分:0 
有点难玩
2010-03-06 16:07



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-298569-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.546437 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved