Продолжая все те же темы, связанные с захватывающими соревнованиями, проводимыми компанией MailRu Group, а именно с "Russian AI Cup 2012 - CodeTanks", решил поделиться стратегией боя на Pascal. Любителям Delphi посвящается сий кусок годного кода. Стратегия не самая лучшая, к победе без доработок не приведет, но это очень хорошая база для старта, особенно начинающим. Более того. эта стратегия способна Вас даже поднять на достойную позицию и даже может помочь пройти в 1й раунд, если повезет
Пишем стратегию для Russian AI Cup - CodeTanks на Pascal:
unit MyStrategy; interface uses StrategyControl, TankControl, WorldControl, MoveControl, BonusControl, ShellControl, ObstacleControl, PlayerContextControl, PlayerControl, UnitControl; type TMyStrategy = class(TStrategy) public procedure Move(me: TTank; world: TWorld; var move: TMove); override; function SelectTank(tankIndex: longint; teamSize: longint) : TTankType; override; end; implementation uses Math; const minAngle = pi/6; MinAngleToEnemy = pi/180; procedure MoveToBonus(BA: TBonusArray; k: integer; me: TTank; world: TWorld; var move: TMove); var u: extended; begin if k <> length(BA) then begin u:= me.getangleto(BA[k]); if u > minAngle then begin if u < (pi - minAngle) then begin move.SetLeftTrackPower(0.75); move.SetRightTrackPower(-1.0); end else begin move.SetLeftTrackPower(-1.0); move.SetRightTrackPower(-1.0); end end else if u < -minAngle then begin if u > (-pi + minAngle) then begin move.SetLeftTrackPower(-1.0); move.SetRightTrackPower(0.75); end else begin move.SetLeftTrackPower(-1.0); move.SetRightTrackPower(-1.0); end end else begin move.SetLeftTrackPower(1.0); move.SetRightTrackPower(1.0); end; end; end; function BonusPriority (BA:TBonusArray; me: TTank; world: TWorld; var move: TMove):TBonusType; begin if (me.GetCrewHealth<75) or (me.GetHullDurability<150) then begin result:=MEDIKIT; if (me.GetHullDurability<100) then result:=REPAIR_KIT; end else Result:=AMMO_CRATE; end; procedure ShootToEnemy(TA:TTankArray; t:Integer; me:TTank; world:TWorld; var move:TMove); begin if me.GetTurretAngleTo(TA[t]) > MinAngleToEnemy then Move.SetTurretTurn(1.0) else if me.GetTurretAngleTo(TA[t]) < -MinAngleToEnemy then Move.SetTurretTurn(-1.0) else move.SetFireType(PREMIUM_PREFERRED); end; procedure BACKCOMEBACK(Me:TTank; World:TWorld; var move:TMove); var i:Integer; MinDist:extended; begin MinDist:=1e20; i:=1; if me.getDistanceTo(World.GetHeight, 0)<MinDist then begin minDist:= me.getDistanceTo(World.GetHeight, 0); i:=2; end; if me.getDistanceTo(0, World.GetWidth)<MinDist then begin MinDist:= me.getDistanceTo(0, World.GetWidth); i:=3; end; if me.getDistanceTo(World.GetHeight, World.GetWidth) < MinDist then begin MinDist:=me.getDistanceTo(World.GetHeight, World.GetWidth) ; i:=4; end; if (World.GetTick<50) then case i of 1: begin move.SetLeftTrackPower(0.3); move.SetRightTrackPower(-0.7); end; 2: begin move.SetLeftTrackPower(-0.7); move.SetRightTrackPower(0.3); end; 3: begin move.SetLeftTrackPower(-0.7); move.SetRightTrackPower(0.3); end; 4: begin move.SetLeftTrackPower(0.3); move.SetRightTrackPower(-0.7); end; end else begin move.SetLeftTrackPower(-1.0); move.SetRightTrackPower(-1.0); end; end; procedure TMyStrategy.Move(me: TTank; world: TWorld; var move: TMove); var BA: TBonusArray; TA: TTankArray; i,TakeThis,k,ShootHim: integer; MinDistance,TrueMinAngleToEnemy: extended; begin BA:= World.GetBonuses; TA:= World.GetTanks; i:= 0; k:= 0; TakeThis:= length(BA); ShootHim:= Length(TA); MinDistance:=1500; TrueMinAngleToEnemy:=1e20; BACKCOMEBACK(me,world,Move); while i < length(BA) do begin if BA[i].GetType = BonusPriority(BA, me, world, move) then if me.getDistanceTo(BA[i])<MinDistance then begin Mindistance:=me.getdistanceto(BA[i]); TakeThis:= i; break; end; i:=i+1; end; MoveToBonus(BA, TakeThis, me, world, move); while k < length(TA) do begin if (me.GetTurretAngleTo(TA[k])< TrueMinAngleToEnemy) and ((TA[k].GetCrewHealth>0) and (TA[k].GetHullDurability>0)) then begin TrueMinAngleToEnemy:=Abs(me.GetTurretAngleTo(TA[k])); ShootHIM:=k; break; end; k:=k+1; end; ShootToEnemy(TA, ShootHim, me, world, move); end; function TMyStrategy.SelectTank(tankIndex: longint; teamSize: longint) : TTankType; begin Result := Medium; end; end.
Имхо, комментариев в коде не хватает. Не все пишут на Pascal'e.
ОтветитьУдалитьЧто например делает метод BACKCOMEBACK(...) ?
Ну, так есть примеры на других языках :)
Удалитьhttp://majorov.blogspot.ru/search/label/russian%20ai%20cup
Ну а вообще, это такой способ "ныкаться" по углам. Логика без интеллекта. Едем задом если нет бонусов и ездим за бонусами если они есть. В начала раунда ныкаемся сразу в угол.