经典Robocode例子代码大全介绍

经典Robocode例子代码大全介绍

经典Robocode例子代码

作者:Alisdair
//*----------------------------------------------------------------------------------------------------------------*//

//*翻译:天翼.李(Skyala.Li)

//*版权:Alisdair

//*译权:Robocode中华联盟www.robochina.org

//*有关翻译中的任何问题请与Skyala.Li联系:robocode@etang.com

//*转载请保留此文件头@2002.1031AllRightsReserved

//*----------------------------------------------------------------------------------------------------------------*//



经典Robocode新手入门例子,包括了移动,雷达,炮管。。。,看完它并应用它,保你Robocode一日千里。

注:翻译风格有所改变,有部分没有进行翻译,有些加入了天翼.李(Skyala.Li)的心得。我们在此只注重原理,不重形式。

大家可自行看看没有翻译的部分,也正好学习外语嘛!最后引入了AboutDuelist,快打到世界第一的机器人发展过程的一段文字。

此物出天上,望君好收藏!源代码也可于此下载(Skyala.li)






 

packagewind;

importrobocode.*;

importjava.awt.Color;

/**

*SnippetBot-arobotbyAlisdairOwens

*Thisbotincludesallsortsofusefulsnippets.Itisnot

*designedtobeagoodfighter(althoughitdoeswell1v1),

*justtoshowhowcertainthingsaredone

*BitsofcodeliftedfromNicatorandChrisbot

*Conventionsinthisbotinclude:Useofradiansthroughout

*Storingabsolutepositionsofenemybotsratherthanrelativeones

*Verylittlecodeinevents

*Theseareallgoodprogrammingpracticesforrobocode

*Theremayalsobemethodsthatarentused;thesemightjustbeusefulforyou.

*/

publicclassSnippetBotextendsAdvancedRobot

{

/**

*run:SnippetBot'sdefaultbehavior

*/

Enemytarget;//ourcurrentenemy代表对手,包括了对手的所有有用参数

finaldoublePI=Math.PI;//justaconstant

intdirection=1;//directionweareheading...1=forward,-1=backwards

//我们坦克车头的方向

doublefirePower;//thepoweroftheshotwewillbeusing-setbydofirePower()设置我们的火力



publicvoidrun()

{

target=newEnemy();//实例化Enemy()类

target.distance=100000;//initialisethedistancesothatwecanselectatarget

setColors(Color.red,Color.blue,Color.green);//setsthecoloursoftherobot

//thenexttwolinesmeanthattheturnsoftherobot,gunandradarareindependant

//让gun,radar独立于坦克车

setAdjustGunForRobotTurn(true);

setAdjustRadarForGunTurn(true);

turnRadarRightRadians(2*PI);//turnstheradarrightaroundtogetaviewofthefield以弧度计算旋转一周



while(true)

{

doMovement();//Movethebot移动机器人

doFirePower();//selectthefirepowertouse选择火力

doScanner();//Oscillatethescanneroverthebot扫描

doGun();//movetheguntopredictwheretheenemywillbe预测敌人,调整炮管

out.println(target.distance);

fire(firePower);//所有动作完成后,开火

execute();//executeallcommands上面使用的都为AdvancedRobot类中的非阻塞调用

//控制权在我们,所有这里用阻塞方法返回控制给机器人

}

}



/*

*Thissimplefunctioncalculatesthefirepowertouse(from0.1to3)

*basedonthedistancefromthetarget.Wewillinvestigatethedatastructure

*holdingthetargetdatalater.

*/

voiddoFirePower()

{

firePower=400/target.distance;//selectsabulletpowerbasedonourdistanceawayfromthetarget

//根据敌人距离来选择火力,因为本身前进,后退为300,所以火力不会过大

}



/*

*Thisisthemovememntfunction.Itwillcauseus

*tocirclestrafetheenemy(iemovebackandforward,

*circlingtheenemy.ifyoudon'tknowwhatstrafingmeans

*playmorequake.

*Thedirectionvariableisglobaltotheclass.Passinga

*negativenumbertosetAheadcausesthebottogobackwards

*以目标主中心来回摆动

*/

voiddoMovement()

{

if(getTime()%20==0)//?过20的倍数时间就反转方向

{

//everytwenty'ticks'

direction*=-1;//reversedirection

setAhead(direction*300);//moveinthatdirection

}

setTurnRightRadians(target.bearing+(PI/2));//everyturnmovetocirclestrafetheenemy

//每一时间周期以敌人为中心绕圆运动

}

/*

*thisscannermethodallowsustomakeourscannertrackourtarget.

*itwilltracktowhereourtargetisatthemoment,andsomefurther

*incasethetargethasmoved.Thiswaywealwaysgetuptotheminute

*informationonourtarget雷达锁定目标

*/

voiddoScanner()

{

doubleradarOffset;//雷达偏移量

if(getTime()-target.ctime>4)//???why来回扫了4个回合都没扫到意味失去了目标,再全扫一遍

{

//ifwehaven'tseenanybodyforabit....

radarOffset=360;//rotatetheradartofindatarget

}

else

{

//nextistheamountweneedtorotatetheradarbytoscanwherethetargetisnow

//通过扫描决定雷达旋转的弧度,"见基本原理方向剖析及目标锁定www.robochina.org".雷达弧度-敌人角度得到两者相差为旋转值

radarOffset=getRadarHeadingRadians()-absbearing(getX(),getY(),target.x,target.y);

//thisaddsorsubtractssmallamountsfromthebearingfortheradartoproducethewobbling

//andmakesurewedon'tlosethetarget

//在得到的角度中加或减一点角度,让雷达很小的范围内摆而不失去目标

if(radarOffset<0)

radarOffset-=PI/8;//(0.375)

else

radarOffset+=PI/8;

}

//turntheradar

setTurnRadarLeftRadians(NormaliseBearing(radarOffset));//左转调整转动角度到PI内

}

/*

*Thissimplemethodmovestheguntothebearingthatwepredictthe

*enemywillbebythetimeourbulletwillgetthere.

*the'absbearing'methodcanbefoundinthehelperfunctionssection

*thenextXandnextYmethodcanbefoundinthe'Enemy'classdescription

*/

voiddoGun()

{

//worksouthowlongitwouldtakeabullettotraveltowheretheenemyis*now*

//thisisthebestestimationwehave

//计算子弹到达目标的时间长speed=20-3*power;有计算公式,距离除速度=时间

longtime=getTime()+(int)(target.distance/(20-(3*firePower)));

//offsetsthegunbytheangletothenextshotbasedonlineartargetingprovidedbytheenemyclass

//以直线为目标,偏移子弹下一次发射的角度。(这样让子弹射空的几率减少。但对付不动的和做圆运动的机器人有问题)

//target.guesssX(),target.guessY()为目标移动后的坐标

doublegunOffset=getGunHeadingRadians()-absbearing(getX(),getY(),target.guessX(time),target.guessY(time));

setTurnGunLeftRadians(NormaliseBearing(gunOffset));//调整相对角度到2PI内

}

/*

*Thissetofhelpermethods.Youmayfindseveraloftheseveryuseful

*Theyincludetheabilitytofindtheangletoapoint.

*/

//ifabearingisnotwithinthe-pitopirange,altersittoprovidetheshortestangle

doubleNormaliseBearing(doubleang)

{

if(ang>PI)

ang-=2*PI;

if(ang<-PI)

ang+=2*PI;

returnang;

}

//ifaheadingisnotwithinthe0to2pirange,altersittoprovidetheshortestangle

doubleNormaliseHeading(doubleang)

{

if(ang>2*PI)

ang-=2*PI;

if(ang<0)

ang+=2*PI;

returnang;

}

//returnsthedistancebetweentwox,ycoordinates'**'

//以两边长求得与对手之间的距离

publicdoublegetrange(doublex1,doubley1,doublex2,doubley2)

{

doublexo=x2-x1;

doubleyo=y2-y1;

doubleh=Math.sqrt(xo*xo+yo*yo);

returnh;

}

//getstheabsolutebearingbetweentox,ycoordinates

//根据x,y的坐标求出绝对角度,见"坐标锁定"利用直角坐标系来反求出角度。???

publicdoubleabsbearing(doublex1,doubley1,doublex2,doubley2)

{

doublexo=x2-x1;

doubleyo=y2-y1;

doubleh=getrange(x1,y1,x2,y2);

if(xo>0&&yo>0)

{

//反正弦定义,对边除斜边得弧度.以robocode中的绝对方向系及坐标系参照

//x,y为正右上角为0-90,x正y负右下角为90-180,x,y负左下角180-270,x负,y正右上角270-360

//此处要理解robocode中的绝对角度是上为0,下为180,如以中心为点划分象限则得到下面的结果

returnMath.asin(xo/h);

}

if(xo>0&&yo<0)

{

returnMath.PI-Math.asin(xo/h);//x为正,y为负第二象限角

}

if(xo<0&&yo<0)

{

returnMath.PI+Math.asin(-xo/h);//第三象限内180+角度

}

if(xo<0&&yo>0)

{

return2.0*Math.PI-Math.asin(-xo/h);//四象限360-角度

}

return0;

}

/**

*onScannedRobot:Whattodowhenyouseeanotherrobot

*扫描事件,也是初始化目标数据的过程

*/

publicvoidonScannedRobot(ScannedRobotEvente)

{

//ifwehavefoundacloserrobot....

if((e.getDistance()<target.distance)||(target.name==e.getName()))

{

//thenextlinegetstheabsolutebearingtothepointwherethebotis

//求得对手的绝对弧度

doubleabsbearing_rad=(getHeadingRadians()+e.getBearingRadians())%(2*PI);

//thissectionsetsalltheinformationaboutourtarget

target.name=e.getName();

//求得对手的x,y坐标,见"robocode基本原理之坐标锁定"文章

target.x=getX()+Math.sin(absbearing_rad)*e.getDistance();//worksoutthexcoordinateofwherethetargetis

target.y=getY()+Math.cos(absbearing_rad)*e.getDistance();//worksouttheycoordinateofwherethetargetis

target.bearing=e.getBearingRadians();

target.head=e.getHeadingRadians();

target.ctime=getTime();//gametimeatwhichthisscanwasproduced扫描到机器人的游戏时间

target.speed=e.getVelocity();//得到敌人速度

target.distance=e.getDistance();

}

}

publicvoidonRobotDeath(RobotDeathEvente)

{

if(e.getName()==target.name)

target.distance=10000;//thiswilleffectivelymakeitsearchforanewtarget

}



}





/*

*Thisclassholdsscandatasothatwecanrememberwhereenemieswere

*andwhattheyweredoingwhenwelastscannedthen.

*Youcouldmakeahashtable(withthenameoftheenemybotaskey)

*oravectorofthesesothatyoucanrememberwhereallofyourenemiesare

*inrelationtoyou.

*ThisclassalsoholdstheguessXandguessYmethods.Thesereturnwhereourtargeting

*systemthinkstheywillbeiftheytravelinastraightlineatthesamespeed

*astheyaretravellingnow.Youjustneedtopassthetimeatwhichyouwanttoknow

*wheretheywillbe.

*保存我们扫描到的目标的所有有用数据,也可用hashtable,vector方法处理所有和我们有关的目标数据(用于群战)

*中间的guessX,guessY方法是针对做直线均速运动机器人一个策略

*/

classEnemy

{

/*

*ok,weshouldreallybeusingaccessorsandmutatorshere,

*(i.egetName()andsetName())butlife'stooshort.

*/

Stringname;

publicdoublebearing;

publicdoublehead;

publiclongctime;//gametimethatthescanwasproduced

publicdoublespeed;

publicdoublex,y;

publicdoubledistance;

publicdoubleguessX(longwhen)

{

//以扫描时和子弹到达的时间差*最大速度=距离,再用对手的坐标加上移动坐标得到敌人移动后的坐标

longdiff=when-ctime;

returnx+Math.sin(head)*speed*diff;//目标移动后的坐标

}

publicdoubleguessY(longwhen)

{

longdiff=when-ctime;

returny+Math.cos(head)*speed*diff;

}

}



/**

*AboutDuelist



IstartedDuelistasageneralpurposebot,basedoffofSnippetBotbyAlisdairOwens.Iquicklyrealizedthatmeleeandduelmatchesweretwocompletelydifferentballgamesandforatimemycodewasriddledwithif(duel)statements.EventuallyIdecidedthatIwouldfocusonduelssincetheypresentamuchsimplerandmoreelegantproblemthanmelee,tomeatleast,andDuelistwasborn.



Duelistusesmanycommonconceptsfoundinthetopbots.Amongthem,itfiresvirtualbullets,theideamadefamousbySandboxLump(writtenbyPaulEvans).Duelistalsousesanti-gravityformovement,thoughithasbeenthoroughlyoverhauledtoeliminatetheproblemswithanti-gravity,suchasgettingstuckinalocalminimum.Ialsokeepstatisticsonhowwellmyvarioustargettingmethodsaredoinginadatastructurethatpersistsfromroundtoround,sothatIcanlearnwhichmethodsworkthebestwithouthavingtoguessrandomlyatthestartofeachround.



SomethingsIthinkI'mtheonlybotouttheredoing:



Conductmyinitialradarsweepbyturningthebody,gun,andradarbeforesettingthemtomoveindependantly.Thissavesabout3turnsinthebeginning.

FiringvirtualbulletsONLYwhenIfirearealone.Althoughthisslowsdownmylearning,there'snobetterwaytolearnthemovementofbotsthatattemptbulletdodging.SincetheymovewhenIfire,Ilearnonlytheirdodgingmovement.

Changingbulletpowerbasedonhowhardtheenemyistohitaswellasthecurrentrange.It'ssillytofirea.5powerbulletatSittingDuckjustbecausehe's900unitsawayfromyou.I'msuresomeoneelseisdoingthisbutIdon'tknowofanypersonallysoI'lllistithere.

Inastraightforwardanti-gravitymovementsystem,youresolvetheforcesandmovealongthevector.Ifyouvisualizethebattlefieldasterrainwithanti-gravitypointsbeinghills,whatyou'redoingisalwaysrollingdownhill.However,youcangettrappedinbadplacesthisway.Forexample,ifyou'recornered,thewallswillberepellingpushingyoutowardstheenemyandtheenemywillpushyoutowardsthewalls,andyou'lljiggleinplacewhileheshootsyouathisleisure.ThemethodthatIusetoavoidthisistotesthowmuchforceisatmanydifferentpointsaroundmeandmovetowardstheonewiththelowestforce.Usingthehillanalogy,ratherthanrollingdownhill,I'mgoingtotheplacewiththelowestelevation...evenifIhavetotraveluphillforawhilebeforeIcangodownhilltogetthere.Iencourageyoutoplaywiththisonyourown,itcertainlyhelpedmybot'sperformance.:-)

ImayaddmoretothispageifIdiscoverthatanyoneisinterested.

*/