home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 3
/
CDASC03.ISO
/
maj
/
542
/
sbomber.pr
< prev
next >
Wrap
Text File
|
1993-04-01
|
7KB
|
212 lines
PROCEDURE SBomber; {Stealth Bomber}
{
Author: David Malmberg
Strategy: Place bombs in the middle of the field then go to a random
corner with cloak raised. Scan for an enemy near the bomb. If you
spot one, then detonate the bomb and begin again with another bomb.
If you see an enemy in missile range (but not near the bomb) blast 'em.
}
(* Below are the SBomber options as specified in the SBOMBER.CFG file
Radar := 3;
Fuel := 0;
Engine := 0;
Armor := 0;
Warheads := 1;
Bombs := 1;
Shielding := 0;
Cloaking := 5;
Repairing := 0;
*)
CONST
NW_Corner = 1;
NE_Corner = 2;
SW_Corner = 3;
SE_Corner = 4;
VAR { SBomber "Global" variables }
Angle, { Scanning angle }
Last_Damage, { Robot's Last damage value }
D_Speed, { Robot's desired speed }
D_Heading, { Robot's desired heading }
BombX, BombY, {Bomb's Co-ordinates}
BombAngle, BombRange, {Angle and Distance from current corner to Bomb}
LastTime, { Last Time cycles were measured }
Delta : Integer; { Scanning arc }
CornerX : ARRAY[1..4] OF Integer; {X coordinate of Corners}
CornerY : ARRAY[1..4] OF Integer; {Y coordinate of Corners}
StartAngle : ARRAY[1..4] OF Integer; {Starting scanning angles for Corners}
Corner, { Current Corner }
Range { Range/Distance to foe } : Integer;
BombHasExploded : Boolean;
PROCEDURE Initialize;
BEGIN
CornerX[NW_Corner] := 10;
CornerY[NW_Corner] := 990;
StartAngle[NW_Corner] := 270;
CornerX[NE_Corner] := 990;
CornerY[NE_Corner] := 990;
StartAngle[NE_Corner] := 180;
CornerX[SW_Corner] := 10;
CornerY[SW_Corner] := 10;
StartAngle[SW_Corner] := 0;
CornerX[SE_Corner] := 990;
CornerY[SE_Corner] := 10;
StartAngle[SE_Corner] := 90;
END; {Initialize}
PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
{
Improve aim by doing a binary search of the target area.
I.E., divide the target area in two equal pieces and redefine
the target area to be the piece where the foe is found.
If the foe is not found, expand the search area to the
maximum arc of plus or minus 10 degrees.
}
BEGIN
Arc := Arc DIV 2; { Divide search area in two. }
IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
THEN Ang := Ang-Arc { If foe found, redefine target angle. }
ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle. }
THEN Ang := Ang+Arc { If foe found, redefine target angle. }
ELSE Arc := 10;
{ Foe not found in either piece, expand search area to maximum arc. }
END; {Aim}
PROCEDURE BlastThem;
BEGIN
Angle := 10;
REPEAT
Delta := 10; { Start with widest scanning arc. }
Range := scan(Angle, Delta);
WHILE (Range > 40) AND (ObjectScanned = Enemy)
AND (Range < MaxMissileRange) DO
{ Must be far enough away to avoid self-damage. }
BEGIN
Aim(Angle, Delta); { Improve aim. }
Cannon(Angle, Range); { Fire!! }
Range := scan(Angle, Delta); { Is foe still in sights? }
END;
Angle := Angle+20; { Look in adjacent target area. }
UNTIL Angle > 360;
END;
PROCEDURE GOTO(x, y : Integer);
{ Go to location X,Y on playing field. }
VAR Heading : Integer;
BEGIN
LowerCloak; {Less need for Cloak while moving}
{ Find the heading we need to get to the desired spot. }
Heading := Angle_To(x, y);
{ Keep traveling at top speed until we are within 150 meters }
WHILE (distance(loc_x, loc_y, x, y) > 150) DO
BEGIN
Drive(Heading, MaxSpeed);
BlastThem;
END;
{ Cut speed, and creep the rest of the way. }
WHILE (distance(loc_x, loc_y, x, y) > 20) DO
BEGIN
Drive(Heading, 20);
BlastThem;
END;
{ Stop driving, should coast to a stop. }
Drive(Heading, 0); {I.E., Stop}
RaiseCloak; {Need Cloak while stopped}
END; {GoTo(X,Y)}
FUNCTION Hurt : Boolean;
{ Checks if Robot has incurred at least 5 points of new damage. }
VAR Curr_Damage : Integer;
Answer : Boolean;
BEGIN
Curr_Damage := damage;
Answer := (Curr_Damage > (Last_Damage + 4));
Last_Damage := Curr_Damage;
IF Answer THEN LastTime := Time;
Hurt := Answer;
END; {Hurt}
PROCEDURE PlaceTheBomb;
BEGIN {PlaceTheBomb}
BombHasExploded := FALSE;
GoTo(500,500);
BombX := Loc_X;
BombY := Loc_Y;
PlaceBomb;
END; {PlaceTheBomb}
FUNCTION EnemyNearBomb : Boolean;
CONST PlusMinus = 200;
VAR EnemyDistance : Integer;
Answer : Boolean;
BEGIN
Answer := FALSE;
EnemyDistance := Scan(BombAngle, 10);
IF ObjectScanned <> Enemy THEN EnemyDistance := 0;
IF EnemyDistance > 0
THEN Answer := (EnemyDistance > (BombRange - PlusMinus))
AND (EnemyDistance < (BombRange + PlusMinus));
EnemyNearBomb := Answer;
END; {EnemyNearBomb}
PROCEDURE Do_Corner;
BEGIN {Do_Corner}
Angle := StartAngle[Corner] + 10; {Starting angle for scanning}
REPEAT
IF EnemyNearBomb
THEN BEGIN
Detonate;
BombHasExploded := TRUE;
END;
Range := scan(Angle, Delta);
WHILE (Range > 40) AND (Range < MaxRadarRange) DO
{ Must be far enough away to avoid self-damage. }
BEGIN
IF ObjectScanned = Enemy THEN cannon(Angle, Range); { Fire!! }
Range := scan(Angle, Delta); { Is foe still in sights? }
END;
Angle := Angle + 20; { Look in adjacent target area. }
IF (Angle > (StartAngle[Corner] + 90))
THEN Angle := StartAngle[Corner] + 10;
UNTIL BombHasExploded;
END; {Do_Corner}
BEGIN {SBomber Main}
RaiseCloak;
Initialize;
Delta := 10; { The widest possible scanning arc. }
LastTime := Time;
REPEAT { Until Dead or Winner }
PlaceTheBomb;
Corner := Random(3) + 1; {Pick a corner}
GoTo(CornerX[Corner], CornerY[Corner]);
{ Move to selected corner. }
BombAngle := Angle_To(BombX, BombY);
BombRange := Distance(Loc_X, Loc_Y, BombX, BombY);
{ Determine relative location from corner to Bomb }
Do_Corner;
IF Hurt THEN
IF Fuel > 250
THEN RaiseCloak { Raise cloak and flee! }
ELSE LowerCloak;
UNTIL Dead OR Winner;
END; {SBomber Main}