home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 3
/
CDASC03.ISO
/
maj
/
542
/
hugger.pr
< prev
next >
Wrap
Text File
|
1993-04-01
|
7KB
|
199 lines
(**************************************************************************)
(* W A R N I N G *)
(* *)
(* This Robot does not work correctly. Fixing it is left as an exercise. *)
(**************************************************************************)
PROCEDURE Hugger;
{
Author: David Malmberg
Strategy: Start off by going to the middle of the battlefield
(if possible). Then Scan for Obstructions and
move to an Obstruction and "hide" beside it by "hugging"
its walls. While "protected" by the Obstruction, blast
away at ememies. If no enemies can be found, move to
another Obstruction (it there is one) and blast away
from it. RaiseShield when moving still and lower them
when standing still and being "protected" by the
Obstruction.
This Robot has been designed to utilize Fuel (if it
is available) to power its Shield. It has also been
designed to take advantage of Obstructions.
}
VAR { Hugger "Global" variables }
Angle, { Scanning angle }
StartAngle, { Begining angle for "sizing up" Obstruction }
LowAngle, { Lowest angle for "Arc" of Obstruction }
HighAngle, { Highest angle for "Arc" of Obstruction }
Start, { Starting angle for scanning for enemies }
Finish, { Last angle for scanning for enemies }
Range, { Range/Distance to foe }
Sweep, { "Sweep count" -- when = 18, Robot has scanned 360 degrees }
Delta : Integer; { Scanning arc }
PROCEDURE GOTO(X, Y : Integer);
{ Go to location X,Y on playing field. }
VAR Heading : Integer;
BEGIN
{ WARNING: If the point X,Y is inside an Obstruction then }
{ executing this routine will cause the Robot to commit }
{ suicide by repeatedly running into the wall of the Obstruction. }
{ 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 drive(Heading, 100);
{ Cut speed, and creep the rest of the way. }
WHILE (distance(loc_x, loc_y, x, y) > 20) DO drive(Heading, 20);
{ Stop driving, should coast to a stop. }
drive(Heading, 0); {I.E., Stop}
END; {GoTo(X,Y)}
PROCEDURE Ramble(X, Y : Integer);
{ Move to X, Y (if possible) on the playing field }
{ by avoiding Obstructions - if any. }
VAR Heading, Tries, Dist : Integer;
BEGIN
Tries := 0;
Heading := Angle_To(X, Y);
Drive(Heading, 50); {Start off toward X,Y}
Dist := Scan(Heading, 5);
REPEAT
IF ObjectScanned = Obstruction
THEN BEGIN
REPEAT
Heading := Heading + 10;
Dist := Scan(Heading, 5);
UNTIL ObjectScanned <> Obstruction;
Drive(Heading, 50); {Minimum speed to turn freely}
END;
Heading := Angle_To(X, Y);
Dist := Scan(Heading, 5);
Tries := Tries + 1;
UNTIL (ObjectScanned <> Obstruction) OR (Tries > 20);
IF (ObjectScanned <> Obstruction) THEN GOTO(X,Y);
END; {Ramble}
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
IF ObjectScanned = Enemy
THEN 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
ELSE Arc := 10;
END; {Aim}
PROCEDURE FindArc;
{ Find the "Arc" of the Obstruction -- if any }
VAR Dist : Integer;
BEGIN
Sweep := 0;
REPEAT
Sweep := Sweep + 1;
Start := Start + 20;
Dist := Scan(Start, 10)
UNTIL (ObjectScanned = Obstruction) OR (Sweep > 18);
IF Sweep <= 18 THEN
BEGIN
{Now find "highest" angle of "Arc" of the Obstruction}
HighAngle := Start - 5;
REPEAT
HighAngle := HighAngle + 5;
Dist := Scan(HighAngle,0);
UNTIL ObjectScanned <> Obstruction;
{Now find "Lowest" angle of "Arc" of the Obstruction}
LowAngle := Start + 5;
REPEAT
LowAngle := LowAngle - 5;
Dist := Scan(LowAngle,0);
UNTIL ObjectScanned <> Obstruction; {lowest angle might be negative}
END
ELSE {Sweep > 18 -- No Obstruction found}
BEGIN
LowAngle := 0; {Set to zero if no Obstruction found}
HighAngle := 0;
END;
END; { FindArc }
PROCEDURE GoToObstruction;
{ Go to the Obstruction and "hug" its walls }
VAR Heading, Dist : Integer;
BEGIN {GoToObstruction}
RaiseShield; {Need protection when moving in open territory}
Heading := (HighAngle + LowAngle) DIV 2; {"middle" of Obstruction}
REPEAT
Drive(Heading, 100);
Dist := Scan(Heading,0);
UNTIL (Dist < 2) AND (ObjectScanned = Obstruction); {"Hug" the wall}
StartAngle := Heading;
FindArc; {New LowAngle and HighAngle calculated}
Start := HighAngle - 360; {"Arc" for scanning for enemies}
Finish := LowAngle;
LowerShield; {Obstruction will "protect" robot}
END; {GoToObstruction}
PROCEDURE Blast_Em;
{Scan for enemies and blast 'em}
BEGIN {Blast_Em}
Sweep := 0;
Angle := Start + 10;
REPEAT
Delta := 10; { Start with widest scanning arc. }
Range := scan(Angle, Delta);
WHILE (Range > 40) AND (Range < 700) AND (ObjectScanned = Enemy)
DO { Must be far enough away to avoid self-damage. }
BEGIN
Sweep := 0; {Reset Sweep counter}
Aim(Angle, Delta); { Improve aim. }
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 >= Finish THEN
BEGIN
Angle := Start + 10;
Sweep := Sweep + 1;
END;
UNTIL Sweep > 10; {10 unsuccessful scans of whole area}
END; {Blast_Em}
BEGIN {Hugger Main}
RaiseShield;
Angle := 0;
Ramble(500, 500); { Move to center of field -- if possible. }
REPEAT { Until Dead or Winner }
FindArc; {Find Obstruction}
GoToObstruction; {"Hide" beside Obstruction}
Blast_Em; {Scan and Blast enemies}
UNTIL Dead OR Winner;
END; {Hugger Main}