//*----------------------------------------------------------------------------------------------------------------*//
//*翻译:天翼.李(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.
*/ |