   0      0  
   1      0    PROCEDURE CHASER;
   2      0  
   3      0  {
   4      0  
   5      0  Based on a C-Robot by Kazuhiro Yabe
   6      0  
   7      0  }
   8      0  
   9      0    VAR
  10      0      save_dmg       : Integer;
  11      0      cur_dmg        : Integer;
  12      0      speed          : Integer;
  13      0      dir            : Integer;
  14      0      Range          : Integer;
  15      0      degree         : Integer;
  16      0  
  17      0      PROCEDURE chkdmg;
  18      0      BEGIN 
  19      0        cur_dmg := damage;
  20      3        IF (cur_dmg <> save_dmg) THEN
  21      7          BEGIN
  22      7            save_dmg := cur_dmg;
  23     10            speed := 50; {maximum speed that robot can still turn}
  24     13            dir := Random(359);
  25     17          END;
  26     17      END; {chkdmg}
  27     17  
  28     17      PROCEDURE walking;
  29     18      BEGIN 
  30     18        speed := 50; {maximum speed that robot can still turn}
  31     21        IF (loc_x < 200) THEN dir := 0
  32     27        ELSE IF (loc_x > 800) THEN dir := 180
  33     35        ELSE IF (loc_y < 200) THEN dir := 90
  34     43        ELSE IF (loc_y > 800) THEN dir := 270;
  35     52        drive(dir, speed);
  36     55      END; {walking}
  37     55  
  38     55      PROCEDURE shoot;
  39     56      VAR return     : Boolean;
  40     56      BEGIN 
  41     56        return := False;
  42     59        REPEAT
  43     59          REPEAT
  44     59            Range := scan(degree, 10);
  45     64            IF (Range > 0) THEN
  46     68              BEGIN
  47     68                cannon(degree, Range); {while he's there, shoot at him. }
  48     71                drive(degree, 100); {charge foe at top speed!}
  49     74                return := True;
  50     77              END;
  51     77          UNTIL Range = 0;
  52     81          IF (degree >= 360)
  53     84          THEN degree := 0
  54     87          ELSE degree := degree+20;
  55     94          walking;
  56     97        UNTIL return;
  57     99      END; {shoot}
  58     99  
  59     99    BEGIN {Chaser Main}
  60    100  
  61    100      speed := 50; {maximum speed that robot can still turn}
  62    103      dir := 0;
  63    106      degree := 0;
  64    109      save_dmg := damage;
  65    112  
  66    112      REPEAT { Until Dead or Winner }
  67    112        shoot;
  68    114        chkdmg;
  69    116        walking; { move at max speed that can still turn }
  70    118      UNTIL Dead OR Winner;
  71    122  
  72    122    END; { end of Chaser main }
  73    122  
  74    122  
  75    122  
  76    122    PROCEDURE M66;
  77    123      { Based on C-Robot M66 : programmed by OBI-ONE }
  78    123  
  79    123    VAR
  80    123      drv_dir        : Integer; { drive direction }
  81    123      scn_dir        : Integer; { scan direction }
  82    123      step           : Integer; { scan step }
  83    123      degs           : Integer; { half of scan step }
  84    123      Range          : ARRAY[-2..2] OF Integer; { range to oponent }
  85    123      range_sv       : Integer; { range of last scan }
  86    123      found          : Boolean; { foe found ? }
  87    123      x, y           : Integer;
  88    123  
  89    123      PROCEDURE Move;
  90    123      BEGIN
  91    123        x := loc_x;
  92    126        y := loc_y;
  93    129        IF (x < 200)
  94    132        THEN drv_dir := Random(45)
  95    136        ELSE IF (x > 800) THEN drv_dir := Random(45)+180;
  96    148  
  97    148        IF (y < 200)
  98    151        THEN drv_dir := Random(45)+90
  99    156        ELSE IF (y > 800) THEN drv_dir := Random(45)+270;
 100    169  
 101    169        drive(drv_dir, 100);
 102    172      END; {Move}
 103    172  
 104    172      PROCEDURE attack;
 105    173      VAR I, Pick    : Integer;
 106    173      BEGIN
 107    173        cannon(scn_dir, range_sv); {shoot at last foe postion}
 108    176        Pick := 99;
 109    179        FOR I := -2 TO 2 DO
 110    184          BEGIN
 111    184            Range[I] := scan(scn_dir+step*I, degs);
 112    195            IF Range[I] > 40 THEN
 113    202              BEGIN
 114    202                Pick := I;
 115    205                I := 2;
 116    208              END;
 117    208          END;
 118    209        IF Pick <> 99 THEN
 119    213          BEGIN
 120    213            found := True;
 121    216            range_sv := Range[Pick];
 122    222            scn_dir := scn_dir+step*Pick;
 123    229            cannon(scn_dir, range_sv);
 124    232          END
 125    232        ELSE scn_dir := scn_dir+120;
 126    238      END; {Attack}
 127    238  
 128    238    BEGIN {M66 Main}
 129    239      drv_dir := Random(360); { initialize }
 130    243      scn_dir := drv_dir+120;
 131    248      found := False;
 132    251      range_sv := 700;
 133    254      step := 20;
 134    257      degs := step DIV 2;
 135    262  
 136    262      REPEAT { main loop }
 137    262  
 138    262        { drive at full speed.                       }
 139    262        { when close to wall, turn around at random. }
 140    262  
 141    262        Move;
 142    264  
 143    264        { scan every 20 degrees resolution. }
 144    264        { if you find a foe, then attack it with your cannon. }
 145    264  
 146    264        attack;
 147    266  
 148    266      UNTIL Dead OR Winner; { end of main loop }
 149    270  
 150    270    END; {M66 Main}
 151    270    PROCEDURE Ninja;
 152    271  
 153    271      { Author unknown }
 154    271  
 155    271      { Based on C-Robot Ninja }
 156    271  
 157    271      { Locks on to a target and attacks }
 158    271  
 159    271    VAR vector     : Integer; { current attack vector }
 160    271  
 161    271  
 162    271      PROCEDURE charge(vec, Range, maxspd : Integer); { charge at an enemy }
 163    271        { vec : attack vector to use }
 164    271        { range : range to target }
 165    271        { maxspd : maximum speed to use }
 166    271      BEGIN 
 167    271        IF (Range > 40) AND (Range < 800) THEN { good shooting range }
 168    279          cannon(vec, Range); { fire! }
 169    282        drive(vec, maxspd); { charge! }
 170    285      END; { charge }
 171    285  
 172    285  
 173    285      FUNCTION Pin(vec : Integer) : Integer; { pin down a target }
 174    286        { vec :  initial vector }
 175    286      VAR
 176    286        tv             : Integer; { trial vector }
 177    286        ts             : Integer; { trial scan results }
 178    286        n              : Integer; { index }
 179    286        return         : Integer;
 180    286      BEGIN
 181    286        tv := vec-10; { coarse screen }
 182    291        n := 2;
 183    294        ts := scan(tv, 10);
 184    299        WHILE (n > 0) AND (ts = 0) DO
 185    307          BEGIN
 186    307            tv := tv+20;
 187    312            n := n-1;
 188    317            ts := scan(tv, 10);
 189    322          END;
 190    323        IF ts = 0
 191    325        THEN return := 0
 192    329        ELSE BEGIN
 193    331          charge(tv, ts, 50);
 194    337  
 195    337          tv := tv-10; { medium screen }
 196    342          n := 4;
 197    345          ts := scan(tv, 5);
 198    350          WHILE (n > 0) AND (ts = 0) DO
 199    358            BEGIN
 200    358              tv := tv+10;
 201    363              n := n-1;
 202    368              ts := scan(tv, 5);
 203    373            END;
 204    374  
 205    374          IF ts = 0
 206    376          THEN return := 0
 207    380          ELSE BEGIN
 208    382            charge(tv, ts, 50);
 209    388  
 210    388            tv := tv-4; { fine screen }
 211    393            n := 3;
 212    396            ts := scan(tv, 2);
 213    401            WHILE (n > 0) AND (ts = 0) DO
 214    409              BEGIN
 215    409                tv := tv-4;
 216    414                n := n-1;
 217    419                ts := scan(tv, 2);
 218    424              END;
 219    425  
 220    425            IF ts = 0
 221    427            THEN return := 0
 222    431            ELSE BEGIN { found it! }
 223    433              return := ts; { say how far away it is }
 224    436              vector := tv;
 225    439            END;
 226    439          END; { fine screen }
 227    439        END; { medium screen }
 228    439  
 229    439        Pin := return;
 230    442      END; { Pin }
 231    442  
 232    442  
 233    442      PROCEDURE attack;
 234    443      VAR
 235    443        Range          : Integer; { range to locked target }
 236    443        return         : Boolean;
 237    443      BEGIN
 238    443        return := False;
 239    446        REPEAT
 240    446          Range := scan(vector, 0);
 241    451          IF (Range > 0)
 242    454          THEN charge(vector, Range, 100) { got him! }
 243    459          ELSE IF Pin(vector) = 0 THEN { lost him! }
 244    469            return := True; { can't find him }
 245    472        UNTIL return;
 246    474      END; { Attack }
 247    474  
 248    474  
 249    474      FUNCTION Find  : Integer; { find a new target }
 250    475      VAR
 251    475        off            : Integer; { offset }
 252    475        dir            : Boolean; { direction }
 253    475        tv             : Integer; { trial vector }
 254    475        return         : Integer;
 255    475  
 256    475      BEGIN {Find}
 257    475        off := 180; { half circle sweep }
 258    478        dir := False; { counter-clockwise first }
 259    481        tv := (vector+180) MOD 360; { look behind us first }
 260    488        return := 0; {no target found - default}
 261    491  
 262    491        WHILE (off >= 0) AND (return = 0) DO { full scan }
 263    499          BEGIN
 264    499            IF (scan(tv, 10) > 0) THEN { see anyone? }
 265    505              return := Pin(tv); { nail him! }
 266    511            dir := NOT dir;
 267    515            IF dir { alternate sides }
 268    515            THEN BEGIN
 269    517              off := off-20;
 270    522              tv := vector+off;
 271    527            END
 272    527            ELSE tv := vector-off+360;
 273    535            tv := tv MOD 360;
 274    540          END;
 275    541  
 276    541        Find := return;
 277    544      END; {Find}
 278    544  
 279    544  
 280    544    BEGIN {Ninja Main}
 281    545      vector := Random(360);
 282    549      REPEAT
 283    549        IF (speed = 0) THEN drive(vector, 30)
 284    556        ELSE IF (Find > 0)
 285    561        THEN attack { if we see anyone attack }
 286    562        ELSE vector := Random(360);
 287    569      UNTIL Dead OR Winner;
 2