当前位置:天才代写 > tutorial > JAVA 教程 > 在Robocode中利用Vector实现仇人列表

在Robocode中利用Vector实现仇人列表

2017-11-11 08:00 星期六 所属: JAVA 教程 浏览:712

副标题#e#

媒介

RoboCode的混战模式中,如何更好的把握多个敌手的环境,从而采纳更好的 计策,成为每一个玩家急切需要办理的问题。而世界级的呆板人多半回收了向量 (vector)数组的方法来生存多个敌手的信息。

并且vector的浸染不止于此,上届世界冠军Yngwie还利用vector来生存子弹 的掷中率信息,为更好的决定提供依据。虽然这超出了我们本日的话题,有乐趣 的伴侣可以看一下Yngwie中的Enemy类和Strategy类。

好了,让我们正式开始本日的vector之旅吧,假如您对JAVA中的vector还不 是出格相识,不要紧,我在最后先容了一些关于vector的常识。

给我们的仇人排个队

熟悉JAVA的伴侣都知道,vector是用来生存一系列工具的荟萃。本日我们用 他来生存我们的仇人的一些信息,把这些四处乱跑的家伙都抓进我们的荟萃还真 不是个轻松的活。孔子云:“万物皆类”。所以,我们首先要声明一个类: Track类。将我们能知道的仇人的属性全都作为这里类中的一个属性:名称、绝 对角度、仇人坦克相对付你车头偏向的相对角度、间隔、能量、速率和仇人坦克 所面临的偏向等。这些都是通过ScannedRobotEvent工具获得的,详细的API函数 请参考Robocode的API辅佐。代码如下:

/**
  * Track类,生存方针的信息
  */
package mytest;
import robocode.*;
public class Track
{
     public String Name; //仇人坦克的名称
     //仇人的绝对角度,通过计较得出
    public double Heading;
     //仇人坦克相对付你车头偏向的相对角度
    public double Bearing;
     public double Distance; //仇人坦克的间隔
     public double Energy; //能量
     public double Velocity; //速率
     public double FaceHeading; //仇人坦克面向的偏向
     public double trackX,trackY; //仇人坦克的坐标
    //下一个尺度时间中仇人坦克地址的位置
   public double nextTrackX,nextTrackY;
     public void update(ScannedRobotEvent e)
     {
        Name=e.getName(); //仇人坦克的名称
        Bearing=e.getBearing(); //仇人坦克相对付你车头偏向的 相对角度
        Distance=e.getDistance(); //仇人坦克的间隔
        Energy=e.getEnergy(); //能量
        Velocity=e.getVelocity(); //速率
        FaceHeading=e.getHeading(); //仇人坦克面向的偏向
     }
}


#p#副标题#e#

在疆场上,一个优秀的批示官会很好的操作他手头有限的信息,而我们的信 息都来自于雷达找到仇人后发生的ScannedRobotEvent事件,至于我们能获得哪 些信息,看上边的注释好了,不多表明白。

下一步就是如何把已经现身在雷达中的仇人抓到一个vector里去了,让我们 回到我们的呆板人主体中去:派生自AdvancedRobot 类的MyVector类中。

首先,声明一个vector范例,并在run中举办初始化。

public class MyVector extends AdvancedRobot
{
     final double version=0.1; //版本号
     private Vector trackVector; //声明我们的向量数组
     /**
     * run: MyVector's default behavior
     */
     public void run() {
        out.println("myVector Version is  "+version);

        trackVector=new Vector(); //初始化我们的向量数组

        while(true) {
            // Replace the next 4 lines with any  behavior you would like
            showTrack();
            setTurnRadarRight(360); //让雷达不断转
            execute();
        }
     }

好了,vector建好了,那下一步就……

请君入队

在Robocode中90%以上的外界信息来自于雷达的扫描,在这个例子里,我没有 对雷达的行动举办更细致地处理惩罚,一直让他在不断旋转,从而能更多的收集差异 仇人的信息。假如是在单挑模式中,大概采纳雷达锁定方针会越发有效。

只要雷达事情正常,我们就能获取每一个仇人的信息了。当仇人的信息源源 不绝地涌入我们的onScannedRobot中,我们的呆板人要像一个优秀的批示官一样 去辨别情报,那些是已经有的,那些是没有的。假如已经存在我们则更新该工具 的属性;假如没有的话,就在向量数组中添加一个新的成员。让我们去 onScannedRobot事件里看一下吧。

#p#分页标题#e#

/**
     * onScannedRobot: What to do when you see  another robot
     */
     public void onScannedRobot(ScannedRobotEvent e) {
        if(!isInVector(e))
        {
            Track myTrack=new Track();
            myTrack.update(e);
            trackVector.add(myTrack);
        }
     }

#p#副标题#e#

我的myVector呆板人是靠自界说要领 isInVector来判定该呆板人是否存在于 向量数组中的,我们等下去看isInVector的里边。假如isInVector返回值为 false,则初始化一个Track工具,挪用它的update要领来初始化仇人的信息,然 后挪用Vector范例的add要领,将该工具插手到向量数组中。

在这里请各人留意的一点是:同一个Vector工具中可以存储差异范例的工具 ,这是JAVA优于C++的一点,可是切忌滥用,我们在trackVector工具中存贮的对 象都是Track范例。 好了,让我们去isInVector里边看看吧。

/**
    * isInVector:自界说要领,判定该呆板人是否已存在于行列中
    */
     public boolean isInVector(ScannedRobotEvent e)
     {
        int i=0;
        while(i<trackVector.size())
        {
            Track myTrack=(Track)trackVector.get(i);
            if(myTrack.Name==e.getName())
            {
               myTrack.update(e);
               return true;
            }
            i++;
        }
        return false;
     }

isInVector 要领的根基思路是,通过传进来的ScannedRobotEvent中的 getName来和vector中已经存在的工具的Name来举办较量,假如有沟通的Name存 在,则说明该仇人的工具已经储存在vector中了,我们只需要简朴的挪用Track 类的update要领,更新信息,并返回true 就可以了。假如没有在vector中找到 同名的呆板人,则返回false,交给onScannedRobot事件来将这个呆板人添加到 vector中来。

这里我利用了Vector范例的size要领来获得向量数组中存在的工具的数量, 在后边我们还会用到这个要领。同时利用一个int变量来节制操纵哪个工具,更 好的步伐是利用迭代器,有乐趣的伴侣可以参考一下《JAVA编程指南》。要获得 vector中的Track工具,则需要利用Vector 范例的get要领,它指定返回第几个 工具。留意,这里需要举办强制范例的转换。获得工具后我们就可以较量Track 的 Name和ScannedRobotEvent的getName()是否沟通了。

仇人不见了

在 Robocode的疆场上,杀戮与被杀的几率是沟通的。不知道各人想过没有, 假如一个仇人被干掉了,他的工具还生存在我们的vector中!假如我们的火控系 统偏巧选中了他来作为下一个进攻方针的话……不消担忧,假如我的呆板人真那 么傻,他恐怕等不到别人被杀的环境。很简朴,我们只需要在 onRobotDeath事 件中挪用Vector范例的remove要领。Remove要领是用来删除指定位置上的工具的 。下面代码的根基思路和 isInVector是一样的。显示如下:

/**
    * onScannedRobot:有呆板人被没落时发生该事件
    */
     public void onRobotDeath(RobotDeathEvent event)
     {
        int i=0;
        while(i<trackVector.size())
        {
            Track myTrack=(Track)trackVector.get(i);
            if(myTrack.Name==event.getName())
            {
               trackVector.remove(i);
            }
            i++;
        }
     }

#p#副标题#e#

显示仇人的间隔

我们这么辛苦地生存了疆场上所有仇人的信息后,由myVector在每个根基时 间里陈诉每个呆板人距我们的间隔。但这里应该留意的是,myVector陈诉的间隔 是我们的雷达最后一次看到仇人时的间隔,仇人很大概已经移动了。正如一位物 理学家所说:“我们无法预测将来是因为我们无法看到真实的此刻。”

我在run的while中挪用了下面的函数,用来显示当前的时间、仇人的数量及 每个仇人与我们的间隔。对数量的计较用到了Vector 的size要领。

#p#分页标题#e#

/**
    * 自界说函数:显示当前仇人的间隔
    */
   public void showTrack()
   {
       int i=0;
        out.println("This Time is "+getTime());
        out.println("Track's count is "+trackVector.size ());

        while(i<trackVector.size())
        {
            Track myTrack=(Track)trackVector.get(i);
            out.println(myTrack.Name+"'s Distance is  "+myTrack.Distance);
            i++;
        }
}

好了,一个简朴的利用vector来生存仇人信息的呆板人完成了,你可以在这 里下载他的代码。在这里我们的呆板人仅仅是将仇人的间隔显示了出来,可是, 实战中我们可以通过对这些信息的阐明,来确定下一个进攻方针,好比最近的一 个。这就要看你的发挥了。我在这里提供的呆板人可以说是很幼稚的,甚至公开 违反了一些面向工具编程的原则,好比把类中的元素直接声明成public。这些问 题请各人在编码的进程中制止。我在这里想说明的是,在Robocode中你可以利用 任何的JAVA技能,让你的呆板人更强大。

下面是我写的呆板人myVector输出丈量功效时的环境,各人可以看到Time2和 Time3时的环境是差异的,在Time2时,雷达只扫描到了Crazy和Fire两个仇人; Time3的时候雷达又发明白Corner。当有呆板人被没落的时候,Vector中的工具 会顿时被删除。各人假如有乐趣可以从下面找到myVector的源代码(resource), 各人可以亲自尝试一下。

在Robocode中操作Vector实现对头列表

#p#副标题#e#

Vector根基观念

最后,我来为不十分熟悉JAVA的伴侣来简朴讲授一些Vector的基本常识,熟 悉这些内容的伴侣可以跳过。

Vector 范例界说了Object 范例的一个元素荟萃,它最大的特点是可以或许按照 你的需要动态增长。它实现了List接口,因此你可以把它看作一个列表。Vector 中只储存工具的引用,而不是实际的工具。这里引用的观念和C++中的很雷同, 熟悉C++的伴侣可以比较领略一下。

Vector的长度可以通过size()来得到,而它的容量则用capacity()来获得。 容量(capacity)指的是为这个Vector分派的空间,而长度(size)则是Vector 中已经利用了的空间,size和储存的工具个数沟通。而长度永远小于容量,这点 请各人留意。

Vector的容量可以通过setSize(i)来变动,假如Vector工具占用的元素个数 小于i,则其余元素将被null填充;假如包括的数量高出i,则所有i后的工具引 用将被扬弃。

Vector 中利用add为向量数组添加新的元素。Add(yourObject)是在vector的 最后添加一个元素。而Add(i,yourObject)则是在 i指定的位置添加一个元素, 使i今后的元素向后移动,总长度加1。与此雷同,set(i,yourObject)则是由 yourObject替换i位置上的元素。这里各人需要留意的是,Vector的记数是从0开 始的,而不是从1开始的。

Vector中利用get(i)来获得工具的引用,利用remove(i)来删除i位置上的元 素。别的你还可以利用firstElement()来获得Vector中的第一个元素。形式如下 :

YourObject you=(YourObject)vector.firstElement();

我们可以通过把一个工具作为参数通报给indexOf()要领来得到存储在一个 Vector中的工具的索引位置。

至于,迭代器等一些高级属性,假如有乐趣,各人可以参考一下《Java编程指南》。内里举办了很具体的讲解.

最后,我还要感激天翼.李(Skyala.Li)耐性地看完了这篇文章的初稿,并提 出了名贵的意见。

 

    关键字:

天才代写-代写联系方式