home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / news / 571 / probot40 / p_robots.doc < prev    next >
Text File  |  1994-05-24  |  135KB  |  3,624 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.                                       P-ROBOTS
  12.  
  13.  
  14.                             A Game For PASCAL Programmers
  15.  
  16.  
  17.                                      Version 4.0
  18.  
  19.  
  20.                                          By
  21.  
  22.  
  23.                                    David Malmberg
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.                                    Distributed by
  32.  
  33.                                       Softworks
  34.                                   829 Fifteenth Street
  35.                             Hermosa Beach, California 90254
  36.  
  37.  
  38.                                     _______
  39.                                ____|__     |               (tm)
  40.                             --|       |    |------------------- 
  41.                               |   ____|__  |  Association of 
  42.                               |  |       |_|  Shareware 
  43.                               |__|   o   |    Professionals 
  44.                             -----|   |   |--------------------- 
  45.                                  |___|___|    MEMBER
  46.  
  47.  
  48.                        Copyrighted 1993 -- All Rights Reserved
  49.                                   By David Malmberg
  50.  
  51.  
  52.  
  53.  
  54.  
  55. JUST WHAT IS P-ROBOTS?
  56.  
  57. P-ROBOTS ("pee-robots") is a game based on computer programming in PASCAL.
  58. The object of the game is to design and program a "robot" that can triumph
  59. over similar robots designed and programmed by others in a real-time battle
  60. of wits and flying missiles.  You control your robot by writing a procedure
  61. in PASCAL to specify your robot's behavior and strategy in its efforts to
  62. vanquish up to three other robots in a battle to the death.  A variety of
  63. pre-defined P-ROBOTS PASCAL functions and procedures allow your robot to
  64. track its position on the battlefield, monitor its health or damage
  65. condition, and calculate the distance and angle to opponents from its
  66. current battlefield position.  Each robot is equipped with a cannon to fire
  67. missiles, and a motorized drive mechanism to either close in for the kill
  68. of a hapless opponent or flee from a fierce foe. Optionally, robots may be
  69. equipped with bombs, a repair kit, different types of armor and warheads, a
  70. deflection shield, and/or a cloaking device.
  71.  
  72. P-ROBOTS is an excellent way for the novice programmer to sharpen his/her
  73. PASCAL skills and have fun at the same time.  However, P-ROBOTS does assumes
  74. that the robot designer/programmer already knows the fundamentals of
  75. programming in PASCAL.  For the experienced programmer, P-ROBOTS offers a
  76. chance to see just how well you program in a programming environment where
  77. "bad" code can lead to graphic and ignoble defeat and "brilliant" code can
  78. bring triumph and glory.
  79.  
  80. In addition to being enjoyed in thousands of homes, P-ROBOTS has been
  81. successfully used in a number of classroom settings -- from high school PASCAL
  82. programming classes to graduate level courses in Artificial Intelligence.  "The
  83. competitive environment that P-ROBOTS creates has really sparked my students'
  84. desire to learn.  Our weekly robot contests are great fun and enjoyed by all --
  85. including me," said one high school PASCAL teacher.  Another teacher has
  86. challenged his PASCAL students by offering a unique reward: any student who can
  87. design and program a robot that can beat the teacher's robot consistently, does
  88. not have to take the final exam.
  89.  
  90. Version 4.0 of P-ROBOTS has a number of significant improvements over prior
  91. versions including an optional "Integrated Development Environment" or IDE,
  92. that can be used to create, edit and test (i.e., compile) your robots.  When
  93. you test/compile a robot using the IDE, the compiler will identify any errors
  94. you have in your robot source code by positioning the cursor within the editor
  95. where the error occurred within your source code -- so you can very easily make
  96. the appropriate correction(s).  The IDE can also be used to set up
  97. "tournaments" of robots, select various match options (such as animation speed,
  98. number of obstacles, unlimited fuel, etc.), and conduct the tournament
  99. according to the robots and options you have selected.
  100.  
  101. P-ROBOTS can be run with as little as 384K of memory and a monochrome or CGA
  102. monitor.  However, if your system has more memory and a better monitor (EGA or
  103. VGA), P-ROBOTS has been designed to take advantage of your hardware's greater
  104. capability.
  105.  
  106.  
  107.  
  108.                                           1
  109.  
  110.  
  111.  
  112.  
  113.  
  114. TABLE OF CONTENTS
  115.  
  116.  
  117. JUST WHAT IS P-ROBOTS?  . . . . . . . . . . . . . . . . . . . . . . . . . .   1
  118.  
  119. TABLE OF CONTENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   2
  120.  
  121. P-ROBOTS REGISTRATION/ORDER FORM  . . . . . . . . . . . . . . . . . . . . .   4
  122.  
  123. LICENSE TERMS (Shareware Rules) . . . . . . . . . . . . . . . . . . . . . .   5
  124.  
  125. DISTRIBUTION OF P-ROBOTS BY DISK VENDORS  . . . . . . . . . . . . . . . . .   6
  126.  
  127. P-ROBOTS PRODUCT/TECHNICAL SUPPORT  . . . . . . . . . . . . . . . . . . . .   7
  128.  
  129. ACKNOWLEDGEMENTS  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   8
  130.  
  131. INTRODUCTION  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   9
  132.  
  133. HARDWARE AND SOFTWARE REQUIREMENTS  . . . . . . . . . . . . . . . . . . . .   9
  134.  
  135. FILES ON THE DISK . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  10
  136.  
  137. GETTING STARTED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  10
  138.  
  139. INVOKING A CONTEST  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  12
  140.  
  141. USING THE "INTEGRATED DEVELOPMENT ENVIRONMENT"  . . . . . . . . . . . . . .  13
  142.  
  143. CONTROLLING YOUR ROBOT'S MOVEMENT . . . . . . . . . . . . . . . . . . . . .  15
  144.  
  145. ATTACKING OTHER ROBOTS  . . . . . . . . . . . . . . . . . . . . . . . . . .  16
  146.  
  147. OTHER SPECIAL P-ROBOTS FUNCTIONS AND PROCEDURES . . . . . . . . . . . . . .  18
  148.      TIME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  149.      DISTANCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  150.      ANGLE_TO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  151.      RANDOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  19
  152.      TRIG FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . .  19
  153.  
  154. INFLICTING DAMAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  19
  155.  
  156. PUTTING IT ALL TOGETHER . . . . . . . . . . . . . . . . . . . . . . . . . .  20
  157.  
  158. ROBOT PROGRAMMING RULES . . . . . . . . . . . . . . . . . . . . . . . . . .  23
  159.  
  160. ADVANCED P-ROBOT FEATURES . . . . . . . . . . . . . . . . . . . . . . . . .  24
  161.      CONTROLLING THE ANIMATION SPEED  . . . . . . . . . . . . . . . . . . .  24
  162.      PROTECTIVE SHIELDS AND CLOAKING  . . . . . . . . . . . . . . . . . . .  25
  163.      FUEL CONSTRAINTS . . . . . . . . . . . . . . . . . . . . . . . . . . .  26
  164.  
  165.                                           2
  166.  
  167.  
  168.  
  169.  
  170.      RUNNING OUT OF FUEL  . . . . . . . . . . . . . . . . . . . . . . . . .  27
  171.      AN EXAMPLE USING A SHIELD AND FUEL . . . . . . . . . . . . . . . . . .  27
  172.      OTHER OPTIONS  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  29
  173.           RADAR RANGE OPTIONS . . . . . . . . . . . . . . . . . . . . . . .  30
  174.           FUEL OPTIONS  . . . . . . . . . . . . . . . . . . . . . . . . . .  30
  175.           ENGINE SIZE AND SPEED OPTIONS . . . . . . . . . . . . . . . . . .  31
  176.           ARMOR OPTIONS . . . . . . . . . . . . . . . . . . . . . . . . . .  31
  177.           MISSILE WARHEAD OPTIONS . . . . . . . . . . . . . . . . . . . . .  32
  178.           ELECTRONIC BOMB OPTIONS . . . . . . . . . . . . . . . . . . . . .  33
  179.           SHIELDING OPTIONS . . . . . . . . . . . . . . . . . . . . . . . .  34
  180.           CLOAKING OPTIONS  . . . . . . . . . . . . . . . . . . . . . . . .  34
  181.           REPAIRING OPTIONS . . . . . . . . . . . . . . . . . . . . . . . .  35
  182.           AN EXAMPLE USING CLOAKING . . . . . . . . . . . . . . . . . . . .  35
  183.           AN EXAMPLE USING BOMBS AND CLOAKING . . . . . . . . . . . . . . .  38
  184.           ROBOT TEAMS . . . . . . . . . . . . . . . . . . . . . . . . . . .  42
  185.           AN EXAMPLE OF A ROBOT TEAM  . . . . . . . . . . . . . . . . . . .  43
  186.           OBSTRUCTIONS ON THE BATTLEFIELD . . . . . . . . . . . . . . . . .  46
  187.           AN EXAMPLE DEALING WITH OBSTRUCTIONS  . . . . . . . . . . . . . .  47
  188.  
  189. APPENDIX I: COMPILER ERRORS . . . . . . . . . . . . . . . . . . . . . . . .  52
  190.  
  191. APPENDIX II: RUN-TIME ERRORS  . . . . . . . . . . . . . . . . . . . . . . .  55
  192.  
  193. APPENDIX III: COMMON PROBLEMS . . . . . . . . . . . . . . . . . . . . . . .  57
  194.  
  195. APPENDIX IV: THE P-ROBOTS PASCAL LANGUAGE . . . . . . . . . . . . . . . . .  58
  196.  
  197. APPENDIX V: A BLATANT "PLUG" FOR ANOTHER SOFTWORKS PRODUCT  . . . . . . . .  62
  198.  
  199. APPENDIX VI: ABOUT THE AUTHOR . . . . . . . . . . . . . . . . . . . . . . .  65
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.                                           3
  223.  
  224.  
  225.  
  226.  
  227.    P-ROBOTS REGISTRATION/ORDER FORM
  228.  
  229.  
  230. **** Good News **** Good News **** Good News **** Good News **** Good News ****
  231.  
  232. P-ROBOTS IS NOW "FREEWARE"
  233.  
  234. P-ROBOTS is now "Freeware."  This means that the author, David Malmberg, still
  235. retains the copyright to P-ROBOTS and all of its related files, such as the
  236. documentation and the IDE.  However, you or any other user may use P-ROBOTS
  237. without paying any royalty or Shareware fees.
  238.  
  239. So enjoy!!
  240.  
  241. Now, the PASCAL source code to P-ROBOTS is also provided as part of the
  242. "Freeware" package.  You should feel free to experiment with the source code
  243. and to build your own expanded/enhanced versions of P-ROBOTS or to build other
  244. PASCAL compiler applications using the P-ROBOTS "compiler engine."  All I ask
  245. is that if you develop an interesting extension/enhancement to P-ROBOTS,
  246. please send me a copy at the following address:
  247.  
  248.     David Malmberg
  249.     829 Fifteenth Street
  250.     Hermosa Beach, CA  90254
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.                                           4
  279.  
  280.  
  281.  
  282.  
  283.  
  284. LICENSE TERMS (Shareware Rules)
  285.  
  286.  
  287. **** Good News **** Good News **** Good News **** Good News **** Good News ****
  288.  
  289. P-ROBOTS IS NOW "FREEWARE"
  290.  
  291. P-ROBOTS is now "Freeware."  This means that the author, David Malmberg, still
  292. retains the copyright to P-ROBOTS and all of its related files, such as the
  293. documentation and the IDE.  However, you or any other user may use P-ROBOTS
  294. without paying any royalty or Shareware fees.
  295.  
  296. So enjoy!!
  297.  
  298. Now, the PASCAL source code to P-ROBOTS is also provided as part of the
  299. "Freeware" package.  You should feel free to experiment with the source code
  300. and to build your own expanded/enhanced versions of P-ROBOTS or to build other
  301. PASCAL compiler applications using the P-ROBOTS "compiler engine."  All I ask
  302. is that if you develop an interesting extension/enhancement to P-ROBOTS,
  303. please send me a copy at the following address:
  304.  
  305.     David Malmberg
  306.     829 Fifteenth Street
  307.     Hermosa Beach, CA  90254
  308.  
  309.  
  310.                                           5
  311.  
  312.  
  313.  
  314.  
  315. DISTRIBUTION OF P-ROBOTS BY DISK VENDORS
  316.  
  317.  
  318. Distributors of "public domain" or user-supported software libraries must
  319. obtain written permission to distribute copies of P-ROBOTS and related robot
  320. game files.  No one may use P-ROBOTS as a promotion for any commercial venture
  321. or as an enticement for the user to pay for any program, product, or service
  322. unless they have received the express written permission of the program's
  323. author.
  324.  
  325. In order to distribute P-ROBOTS, a dealer or disk vendor must comply with the
  326. following conditions:
  327.  
  328.      (1)  You must obtain written permission from Softworks to distribute
  329.           P-ROBOTS.  If you receive no reply, write again: our silence does NOT
  330.           constitute permission, and you may not distribute "pending" receipt
  331.           of permission.
  332.  
  333.      (2)  A fee of not more than $7 may be charged for each disk sold.
  334.           P-ROBOTS may not be included on any disk sold for more than $7,
  335.           including CD-ROM or optical disks, without express written permission
  336.           from Softworks.
  337.  
  338.      (3)  Vendors may not modify or delete ANY files on the disk.  Vendors may
  339.           add a "GO" program, and/or a reasonable number of small text files
  340.           designed to assist or provide a service to the user, but these added
  341.           files must be easily identifiable and end-users must be allowed to
  342.           delete the added files.
  343.  
  344.      (4)  Vendors must make a reasonable effort to distribute only the most
  345.           recent versions of P-ROBOTS.  All vendors who have requested and
  346.           received written permission to distribute P-ROBOTS will be notified
  347.           of updates as they are released.
  348.  
  349.      (5)  All disk vendors must comply with any and all vendor guidelines or
  350.           vendor requirements set forth by the Association of Shareware
  351.           Professionals (ASP); for more information about ASP, contact its
  352.           chairman, Jim Button, at Buttonware in Seattle.  Violation of any ASP
  353.           guideline or requirement automatically revokes permission to
  354.           distribute P-ROBOTS.
  355.  
  356.  
  357.  
  358.                                           6
  359.  
  360.  
  361.  
  362.  
  363. P-ROBOTS PRODUCT/TECHNICAL SUPPORT
  364.  
  365. Since, P-ROBOTS is now "Freeware" -- no technical support will be furnished!
  366.  
  367. Softworks will NOT fix P-ROBOTS bugs, and will NOT help users by answering
  368. technical and other P-ROBOTS related questions.
  369.  
  370. You are on your own.  If your copy of P-ROBOTS breaks, you own both pieces!
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.                                           7
  379.  
  380.  
  381.  
  382.  
  383. ACKNOWLEDGEMENTS
  384.  
  385.  
  386. P-ROBOTS owes a great deal to many people and to several previous programs.
  387.  
  388. The P-Code PASCAL compiler that was used in P-ROBOTS has a long history.  It
  389. was originally developed and published in 1976 by Nicklaus Wirth, the "father"
  390. of PASCAL.  In 1982, M. Ben-Ari developed and published a book describing how
  391. to make the compiler capable of multi-tasking.  Over the years, this compiler
  392. has been converted to many, many different computers and to many different
  393. dialects of PASCAL.  In 1986, Charles Schoening converted the compiler to Turbo
  394. Pascal version 2.0 on the IBM and released his version to the public domain.  I
  395. have enhanced and converted the compiler to the most recent releases of Turbo
  396. Pascal, as well as, to Microsoft's QuickPascal.  This version was then adapted
  397. to be the compiler "engine" for P-ROBOTS.
  398.  
  399. The inspiration for P-ROBOTS and the initial design of the program came from a
  400. similar program called C-ROBOTS by Tom Poindexter, which was first published in
  401. 1985.  As might be expected from the name, C-ROBOTS allows the programmer to
  402. design and program his/her robots in the C language, rather than PASCAL.  If
  403. you are interested in C-ROBOTS, Tom is selling it as Shareware for a $20
  404. registration fee.  The registration fee entitles you to the latest version of
  405. the program, a large collection of excellent robots, and the source code for
  406. the C-ROBOTS (written in C -- of course).  C-ROBOTS can be ordered from Tom at
  407. the following address:
  408.  
  409.              Tom Poindexter
  410.              6864 Amherst Court
  411.              Highlands Ranch, CO
  412.                             80126
  413.  
  414. C-ROBOTS can NOT be ordered from Softworks; it must be ordered from Tom
  415. directly at the above address.
  416.  
  417. In addition, I would especially like to thank Professor B.J. Gleason of Upsala
  418. College and his students.   P-ROBOTS has benefited greatly from their
  419. suggestions.  Professor Gleason and his students also donated some truly
  420. awesome Robots that are included on the current P-ROBOTS disk.
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.                                           8
  436.  
  437.  
  438.  
  439.  
  440. INTRODUCTION
  441.  
  442. P-ROBOTS is a game based on computer programming in PASCAL.  The object of the
  443. game is to design and program a "robot" that can triumph over similar robots
  444. designed and programmed by others in a real-time battle of wits and flying
  445. missiles.  You control your robot by writing a procedure in PASCAL to specify
  446. your robot's behavior and strategy in its efforts to vanquish up to three other
  447. robots in a battle to the death.  A variety of pre-defined P-ROBOTS PASCAL
  448. functions and procedures allow your robot to track its position on the
  449. battlefield, monitor its health or damage condition, and calculate the distance
  450. and angle to opponents from its current battlefield position.  Each robot is
  451. equipped with a cannon to fire missiles, and a motorized drive mechanism to
  452. either close in for the kill of a hapless opponent or flee from a fierce foe.
  453. Optionally, robots may be equipped with bombs, a repair kit, different types of
  454. armor and warheads, a deflection shield, and/or a cloaking device.
  455.  
  456. P-ROBOTS assumes that the robot designer already knows the fundamentals of
  457. programming in PASCAL.  Using P-ROBOTS, PASCAL skills sharpen as good code
  458. guides your robot to victory over the competition.  An individual can challenge
  459. the stable of provided robots.  Groups or classes can have contests among
  460. member-created robots. Going through the manual will get you started using P-
  461. Robots and designing your own robot.  There are helpful appendices you will
  462. want to consult that summarize the P-Robot Pascal Language, help with error
  463. diagnosis, and list common problems.
  464.  
  465. Version 4.0 of P-ROBOTS has a number of significant improvements over prior
  466. versions including an optional "Integrated Development Environment" or IDE that
  467. can be used to create, edit and test (i.e., compile) your robots.  When you
  468. test/compile a robot using the IDE, the compiler will identify any errors you
  469. have in your robot source code by positioning the cursor within the editor
  470. where the error occurred within your source code -- so you can very easily make
  471. the appropriate correction(s).  The IDE can also be used to set up
  472. "tournaments" of robots, select various match options (such as animation speed,
  473. number of obstacles, unlimited fuel, etc.), and conduct the tournament
  474. according to the robots and options you have selected.
  475.  
  476.  
  477. HARDWARE AND SOFTWARE REQUIREMENTS
  478.  
  479. If you intend to run P-ROBOTS on an IBM or compatible computer, you will need
  480. at least 384K of memory and DOS 2.1 or later.  Either a color or monochrome
  481. monitor may be used.  If you are using a color monitor, P-ROBOTS will
  482. automatically detect it and use different colors for each robot.  If you are
  483. using a monochrome monitor, P-ROBOTS will display your robots accordingly.  If
  484. you have an EGA or VGA monitor, P-Robots will automatically detect that and use
  485. these enhanced screen capabilities.
  486.  
  487. If you are using P-ROBOTS' "Integrated Development Environment" or IDE, you
  488. will need at least 512k of memory and a hard disk with at least 512K of free
  489. disk space.  The IDE will use EMS or XMS memory if available for its "swap"
  490. file -- otherwise, the IDE will put its "swap" file on hard disk.
  491.  
  492.                                           9
  493.  
  494.  
  495.  
  496.  
  497. FILES ON THE DISK
  498.  
  499. You should have the following files on your P-ROBOTS disk:
  500.  
  501.           P-ROBOTS.EXE   The is the main program that is executed whenever you
  502.                          hold  a P-ROBOTS contest.
  503.  
  504.           P-ROBOTS.DOC   This file contains the documentation for P-ROBOTS.  It
  505.                          is a text file and can be printed by giving the
  506.                          command at the DOS prompt: TYPE P-ROBOTS.DOC > PRN
  507.  
  508.           PR-DEMO.BAT    This is a file that gives a demonstration of a typical
  509.                          P-ROBOTS contest between three robots.
  510.  
  511.           ????????.PR         These are other PASCAL source code files for
  512.                               other robots.  All P-ROBOTS robots MUST have .PR
  513.                               file extensions.  Without this .PR extension,
  514.                               P-ROBOTS will not compile the robot and enter it
  515.                               in any robot contests.
  516.  
  517. If you are using P-ROBOTS' "Integrated Development Environment" or IDE, you
  518. need the following additional files on your hard disk (on the same directory
  519. where the above files are kept):
  520.  
  521.           IDE.BAT        The batch file used to invoke the P-ROBOTS'
  522.                          "Integrated Development Environment."
  523.  
  524.           PR-SHELL.EXE   The "shell" program with a built-in full-screen editor
  525.                          and a test compiler that can be used to develop and
  526.                          test your robots.  This program is called by IDE.BAT.
  527.  
  528.           POPDOS.EXE     A really "nifty" utility program that can be called by
  529.                          hitting the <Alt><F10> key combination to invoke DOS
  530.                          from within another program.   See POPDOS.DOC for
  531.                          details.  POPDOS is loaded by IDE.BAT and is used to
  532.                          run P-ROBOTS from within the "Integrated Development
  533.                          Environment."
  534.  
  535.           P-ROBOTS.PCX   A graphic title screen for the IDE which will be
  536.                          displayed if you have an EGA or VGA monitor.
  537.  
  538.           *.HLP          Various help files accessed by hitting <F1> from
  539.                          within the IDE.
  540.  
  541.  
  542. GETTING STARTED
  543.  
  544. To see a typical P-ROBOTS contest, just execute the batch file PR-DEMO.  What
  545. you will see will be the PASCAL source code for three robots being read from
  546. the disk and compiled by P-ROBOTS.  After being compiled successfully (without
  547. any errors), you will then see a battle between these three robots.  The battle
  548.  
  549.                                          10
  550.  
  551.  
  552.  
  553.  
  554. will last between one and four minutes and you will be able to see the
  555. individual robots move around the battlefield, fire their missiles and get hit
  556. when the missiles explode too near them on the screen.  The screen and the
  557. battlefield will look something like the following:
  558.  
  559.  
  560.           (x=0,y=999)                        (x=999,y=999)
  561.  
  562.               +------------------------------------+ 1  CHASER F 1156
  563.               |                                    |  D% 015   Sc 218
  564.               |                               1    |  Sp 000   Hd 090
  565.               |                          \^/       |  X= 902   Y= 890
  566.            ^  |     (missile exploding) <-#->      | ------------------
  567.            |  |                          /v\       | 2  M66    F  982
  568.               |                                    |  D% 050   Sc 275
  569.            Y  |              +        (missiles    |  Sp 100   Hd 180
  570.               |                     +   flying)    |  X=  89   Y= 534
  571.            a  |                                    | ------------------
  572.            x  |   2                                | 3  NINJA  F 1192
  573.            i  |                                    |  D% 000   Sc 045
  574.            s  |                                    |  Sp 000   Hd 000
  575.               |                 3                  |  X= 423   Y= 350
  576.               |                /                   | ------------------
  577.               |          (robots)                  |
  578.               |                                    |
  579.               |                                    |
  580.               |                                    |
  581.               |                                    |
  582.               |                                    | CPU
  583.               +------------------------------------+ Cycles:     34512
  584.  
  585.           (x=0,y=0)           X axis -->     (x=999,y=0)
  586.  
  587.  
  588. The battlefield is 1000 meters by 1000 meters with the coordinates 0,0 in the
  589. lower left hand corner of the screen.  The border of the battlefield has a
  590. "fence" or "wall" around it which will cause the robots damage if they run into
  591. it.  Hitting a border of the battlefield will also cause your robot to come
  592. crashing to a halt.  On the battlefield, each robot is represented by a number
  593. from 1 to 4.  (There can be at most four robots in any one contest.)  Flying
  594. missiles will be represented on the screen by + symbols, and explosions by a
  595. flurry of lines and corners -- as can be seen above.
  596.  
  597. Beside the battlefield are several "status" areas where information about each
  598. robot is displayed.  The number that precedes the robot's name is its symbol on
  599. the screen.  For example, the number 2 represents the robot M66 in the above
  600. display.  To the right of the robot's name (and just to the right of the "F")
  601. is the robot's current number of "jiggers" of fuel.  The "D%" field shows the
  602. percentage of damage that the robot has incurred so far.  When the damage
  603. percentage gets to 100% the robot dies.  The "Sc" field shows the direction in
  604. degrees (from 0 to 359) that the robot's scanner is currently pointed.  The
  605.  
  606.                                          11
  607.  
  608.  
  609.  
  610.  
  611. scanner is used to detect the presence of enemy robots and to aim missiles at
  612. them.  The "Sp" field show the robot's current speed.  A speed of zero means
  613. the robot is standing still and the maximum speed is normally 100.  The "Hd"
  614. field show the robot's current heading, i.e., the direction it is moving.  Like
  615. the scanner field, the heading is shown in degrees from 0 to 359.  The "X=" and
  616. "Y=" fields show the robot's current X and Y coordinates on the battlefield,
  617. respectively.  The  X-axis runs from 0 on the left to 999 on the right side of
  618. the battlefield.  The Y-axis runs from 0 at the bottom on the screen to 999 at
  619. the top.
  620.  
  621. All angles/directions in P-ROBOTS are calculated in degrees from 0 to 359 using
  622. the traditional angle directions you undoubted learned in Geometry.  Due east
  623. is zero degrees, north is 90 degrees, etc.:
  624.  
  625.               135    90   45
  626.                   \  |  /
  627.                    \ | /
  628.              180 --- x --- 0
  629.                    / | \
  630.                   /  |  \
  631.               225   270   315
  632.  
  633.  
  634. INVOKING A CONTEST
  635.  
  636. Sooner or later, you are going to get tired just watching the DEMO match and
  637. will want to see contests between other robots -- perhaps even your own robot
  638. creations.  There are two types of contests: single games or matches.  In
  639. single game mode, the game is played with animated "graphics" where the
  640. progress of the battle can be watched on the screen.  Match play is when you
  641. want to run a series of contests (maybe as many as 100) between the same group
  642. of robots to see what the winning percentages are for each contestant.  Match
  643. play does not display the actual battles, but just shows the summary of wins
  644. and loses as each individual game is played.  Match play is ideal for playing
  645. overnight.
  646.  
  647. If you want to stop a P-ROBOTS game (either single game or match), just hit
  648. Control-Break.
  649.  
  650. To run a single game, at the DOS prompt give the command:
  651.  
  652.              P-ROBOTS Robot1 Robot2 .. Robot3
  653.  
  654. For example, to run a single game among the robots NINJA, HOTSHOT, WIMP and
  655. BLASTER you would enter the command:
  656.  
  657.              P-ROBOTS NINJA HOTSHOT WIMP BLASTER
  658.  
  659. Or to run a single game between HOTSHOT and WIMP you would enter the command:
  660.  
  661.              P-ROBOTS HOTSHOT WIMP
  662.  
  663.                                          12
  664.  
  665.  
  666.  
  667.  
  668. It is also possible to test your robot against a "default" robot, named TARGET,
  669. that is built into the P-ROBOTS program.  TARGET just sits in the center of the
  670. battlefield waiting to get shot at.  However, TARGET does shoot back -- so be
  671. warned that beating TARGET is not a totally trivial exercise.  TARGET is an
  672. excellent opponent for testing new robots.  For example, to test a robot named
  673. FRED against TARGET, just give the command:
  674.  
  675.              P-ROBOTS FRED
  676.  
  677. To invoke a series of contests, i.e., match play, append a "/MNNN" behind the
  678. normal single play command, where NNN represents the number of games you wish
  679. to play in the match.  "/M50" would cause 50 games to be played in the match
  680. and "/M100" would cause 100 games to be played.  To initiate a 20 game match
  681. among HOTSHOT, WIMP and BLASTER you would enter the command:
  682.  
  683.              P-ROBOTS NINJA HOTSHOT WIMP BLASTER /M20
  684.  
  685. Or to run a series of 10 games between HOTSHOT and WIMP you would enter the
  686. command:
  687.  
  688.              P-ROBOTS HOTSHOT WIMP /M10
  689.  
  690. IMPORTANT NOTE: The actual files on the disk containing the source code for the
  691. various robots MUST have a .PR file extension.  However, when the game is
  692. invoked, the use of this extension is optional.
  693.  
  694.  
  695. USING THE "INTEGRATED DEVELOPMENT ENVIRONMENT"
  696.  
  697. An optional feature of Version 4.0 of P-ROBOTS is an "Integrated Development
  698. Environment" or IDE that can be used to create, edit and test (i.e., compile)
  699. your robots.  When you test/compile a robot using the IDE, the compiler will
  700. identify any errors you have in your source code by positioning the cursor
  701. within the editor where the error occurred within your source code -- so you
  702. can very easily make the appropriate correction(s).  The IDE can also be used
  703. to set up "tournaments" of robots, select various match options (such as
  704. animation speed, number of obstacles, unlimited fuel, etc.), and conduct the
  705. tournament according to the robots and options you have selected.  The
  706. "Integrated Development Environment" is invoked by giving the command IDE from
  707. the DOS prompt.  In order to use the IDE you must have at least 512K of memory
  708. and a hard disk with at least 512K of free disk space to store the IDE's "swap"
  709. files.
  710.  
  711. The IDE has an easy-to-use menu-driven interface.  The menu options include the
  712. following:
  713.  
  714.      File - Various operations on Robot files (Load, Save, Print, etc.),
  715.      specifically:
  716.  
  717.           New - Create a new robot
  718.           Open - Open an existing robot file
  719.  
  720.                                          13
  721.  
  722.  
  723.  
  724.           Close - Close current robot file (without saving)
  725.           Save As - Save current robot file under a different name
  726.           Print - Print current file on LPT1, LPT2, LPT3 or PRN printer
  727.           About - Information about P-Robots, specifically:
  728.  
  729.                Credits - Display credits for P-Robots
  730.                Print Order Form - Print the P-Robots Order Form on your printer
  731.  
  732.      Edit - Robot source file and Robot option (.CFG) file, specifically:
  733.  
  734.           Edit Robot - Edit current robot program using a full-screen editor
  735.           Edit Configuration - Edit current robots options (i.e., .CFG
  736.           options), including:
  737.  
  738.                Radar - Change Radar points in .CFG file
  739.                Fuel - Change Fuel points in .CFG file
  740.                Engine - Change Engine points in .CFG file
  741.                Armor - Change Armor points in .CFG files
  742.                Warheads - Change Warheads points in .CFG files
  743.                Bombs - Change Bombs points in .CFG files
  744.                Shielding - Change Shielding points in .CFG files
  745.                Cloaking - Change Cloaking points in .CFG file
  746.                Repairing - Change Repairing points in .CFG file
  747.                Save .CFG Options - Save current robot options in .CFG file
  748.  
  749.           Test Compile - Test (by compiling) the current Robot
  750.  
  751.      Tournament - Conduct a Tournament battle of several robots, including
  752.      these choices:
  753.  
  754.           Select Robots - Select up to 4 Robots to battle one another
  755.           Battle Options - Select options (display speed, unlimited fuel, etc.)
  756.           for battle, including:
  757.  
  758.                Speed - Select display Speed option
  759.                Match Play - Select Match Play (and number of matches to play)
  760.                Obstructions - Select Obstruction Play (and enter the number of
  761.                obstructions)
  762.                Unlimited Fuel - Select Unlimited Fuel option
  763.  
  764.           Fight - Start battle of selected robots
  765.  
  766.      Demo -  Conduct a demonstration robot battle
  767.  
  768.      Calculator - An easy-to-use calculator
  769.  
  770.      Quit - the P-Robot Program Shell and return to DOS
  771.  
  772. While using the IDE, you can always get HELP by hitting the F1 key.
  773.  
  774.  
  775.                                          14
  776.  
  777.  
  778.  
  779.  
  780. CONTROLLING YOUR ROBOT'S MOVEMENT
  781.  
  782. To move your robot in P-ROBOTS you must use the special procedure "Drive" that
  783. is built into the P-ROBOTS version of the PASCAL language.  (See Appendix IV
  784. for a summary of all built-in P-ROBOTS functions and procedures.)  The Drive
  785. procedure would be used in your program as:
  786.  
  787.              Drive(degree,speed);
  788.  
  789. This would cause your robot to move in the direction specified by "degree" and
  790. at the speed indicated by the second parameter, "speed".  The direction will be
  791. forced by the Drive procedure to be between 0 and 359 (i.e., degree := degree
  792. MOD 360;) and the speed will be restricted to between 0 and the maximum of the
  793. built-in P-ROBOTS CONST MaxSpeed (which is typically 100).  Calling the Drive
  794. procedure with a speed of zero, will cause your robot to stop.
  795.  
  796. For example:
  797.  
  798.              Drive(90, MaxSpeed);  (* drive north at top speed *)
  799.              Drive(heading,0);     (* slow down and stop *)
  800.  
  801. In an attempt to simulate some degree of reality, a robot's speed does not
  802. change instantly, but rather has to go through periods of acceleration and
  803. deceleration.  For example, to stop a robot traveling at a speed of 100 will
  804. take between 100 and 200 meters.  Conversely, to get up to a speed of 100 from
  805. a standing stop will also take between 100 and 200 meters.
  806.  
  807. Also, your robot will not be able to "turn on a dime".  You must be moving at a
  808. speed of 50 or less to change directions.  Attempting to turn while going over
  809. 50 will cause your robot's drive motor to "over heat" and your robot will just
  810. coast to a stop on its current heading.
  811.  
  812. To monitor the status of your movement on the battlefield, the P-ROBOTS version
  813. of PASCAL has several special built-in functions.
  814.  
  815. The built-in "Speed" function returns the current speed of your robot (from 0
  816. to MaxSpeed).  Remember that the value returned by Speed may not always be the
  817. same as the last parameter used in the last call to Drive, because of
  818. acceleration, deceleration and collisions.
  819.  
  820. An example of how the Speed function might be used is as follows:
  821.  
  822.         Drive(270, MaxSpeed);  (* start driving, due south *)
  823.          ; ; ;                 (* other instructions *)
  824.         IF Speed = 0           (* check if stopped, i.e., current speed = 0 *)
  825.             THEN Drive(90,20); (* Probably, ran into the south border *)
  826.                                (* Go north at speed of 20 *)
  827.  
  828. The built-in "Loc_X" and "Loc_Y" functions return your robots X and Y
  829. coordinates on the battlefield, respectively.  The following shows how these
  830. functions might be used:
  831.  
  832.                                          15
  833.  
  834.  
  835.  
  836.  
  837.        Drive(45,50);   (* start driving in north-easterly direction *)
  838.        WHILE (Loc_X < 900) AND (Loc_Y < 900) DO Drive(45,50);
  839.             (* i.e., just keep driving until we are close to a border *)
  840.        Drive(45,0);    (* slow down and stop *)
  841.  
  842.  
  843. ATTACKING OTHER ROBOTS
  844.  
  845. The main offensive weapons available to your robot are its scanner and its
  846. cannon.  Both of these weapons are controlled by using special built-in
  847. capabilities of the P-ROBOTS PASCAL language.
  848.  
  849. The scanner is an "electronic eye" that enables your robot to look for enemy
  850. robots in any chosen direction from 0 to 359 degrees.  The scanner has a
  851. maximum resolution of +/- 10 degrees.  This allows your robot to quickly scan
  852. the battlefield at a low resolution, then use finer resolution to pinpoint a
  853. foe's precise position.  The scanner would be accessed by a reference to the
  854. "Scan" function, as follows:
  855.  
  856.              Scan(degree,resolution)
  857.  
  858. This function invokes the robot's scanner, at the specified degree and
  859. resolution.  This function returns an integer value of 0 if no enemy robots are
  860. within the scan range or a integer value (greater than 0) representing the
  861. distance to the nearest robot in the scan area.  The value passed as the
  862. parameter "degree" will be forced to be in the range 0 to 359.  Likewise, the
  863. "resolution" will be forced to be in the range of +/- 10 degrees.  The number
  864. returned will range from 0 (if nothing is within scanner range) to a maximum of
  865. "MaxRadarRange".  MaxRadarRange will be determined by the options selected for
  866. the robot.  Robot options will be described later.
  867.  
  868. Some examples:
  869.  
  870.        Enemy := Scan(180,10); (* scans the area from 170 to 190 degrees *)
  871.        Dist_To_Foe := Scan(180,2); (* scans the area from 178 to 182 degrees *)
  872.        Target_Range := Scan(90,0); (* scan 90 degrees, with no variance *)
  873.  
  874. Once an enemy robot is found with the scanner, you would use your robot's
  875. cannon to fire a missile at the enemy.  This is done by using P-ROBOTS special
  876. "Cannon" procedure:
  877.  
  878.              Cannon(degree,range);
  879.  
  880. This will fire a missile in the direction specified by the parameter "degree"
  881. and for a distance specified by the value of "range".  Your robot's cannon has
  882. a maximum range of MaxRadarRange (default is 700) meters.  There are an
  883. unlimited number of missiles -- so you need not worry about running out.
  884. However, it will take some time to reload between firing missiles; so that, the
  885. number of missiles in the air at any one time to limited to two.  The cannon is
  886. mounted on an independent turret, and therefore can fire in any direction,
  887. regardless of the robot's current movement direction.
  888.  
  889.                                          16
  890.  
  891.  
  892.  
  893.  
  894. For example, the following "chunk" of code will cause your robot to constantly
  895. scan for enemies and blast away at them as long as they are in sight.  When
  896. they are no longer in sight (or in range), the scanner will move to the next 20
  897. degree segment of the circle:
  898.  
  899.        Angle := 0; (* initialize to east *)
  900.        REPEAT
  901.          Enemy_Range := Scan(Angle,10); (* Get range to target -- if any *)     
  902.          WHILE (Enemy_Range > 40) AND (Enemy_Range <= MaxRadarRange) DO
  903.            BEGIN (* Enemy in sight and in range *)
  904.              Cannon(Angle,Enemy_Range); (* Blast it! *)
  905.              Enemy_Range := Scan(Angle,10); (* Still there? *)
  906.            END;
  907.            Angle := Angle + 20; (* move search to next segment *)
  908.         UNTIL Dead or Winner;
  909.  
  910. The "Dead" and the "Winner" in the UNTIL statement are special pre-defined
  911. Boolean functions in P-ROBOTS.  Dead will have a value of FALSE while your
  912. robot is still alive (i.e., its damage is less than 100%) and TRUE when it
  913. finally dies.  Similarly, Winner will be TRUE if your robot is the last
  914. survivor of the battle and FALSE otherwise.
  915.  
  916. If your robot utilized the basic "Sitting Duck" strategy given above, its
  917. opponents would undoubtedly make short work of it.  To make the strategy a
  918. little smarter, we need some way to determine if we are under attack.
  919. Fortunately (and not surprisingly), P-ROBOTS has another special function that
  920. can assist us -- the "Damage" function.  Whenever you use this function in your
  921. code, it will return an integer value of your robot's current damage
  922. percentage.  If this value changes, then we know the robot is under attack and
  923. it probably should run for safety.
  924.  
  925. As an example, let's see how the Damage function could be used to make the
  926. above code a little smarter:
  927.  
  928.         Old_Damage := Damage; (* Get initial value of damage *) 
  929.         Angle := 0; (* initialize to east *)
  930.         REPEAT    
  931.           Enemy_Range := Scan(Angle,10); (* Get range to target -- if any *)
  932.           WHILE (Enemy_Range > 40) AND (Enemy_Range <= MaxRadarRange) DO
  933.             BEGIN (* Enemy in sight and in range *)
  934.               Cannon(Angle,Enemy_Range); (* Blast it! *)
  935.               Enemy_Range := Scan(Angle,10); (* Still there? *)      
  936.             END;
  937.           Angle := Angle + 20; (* move search to next segment *)
  938.           IF Damage > Old_Damage THEN
  939.             BEGIN (* Under attack *)
  940.               Old_Damage := Damage; (* Get latest Damage value *)
  941.               Move; (* Get out of here!! *)
  942.             END;
  943.         UNTIL Dead or Winner;
  944.  
  945.  
  946.                                          17
  947.  
  948.  
  949.  
  950.  
  951. The "Move" reference above would call a separate procedure that would move the
  952. robot to another position on the battlefield where it will hopefully be safer.
  953. This procedure will be given a little later as another example.
  954.  
  955.  
  956. OTHER SPECIAL P-ROBOTS FUNCTIONS AND PROCEDURES
  957.  
  958.  
  959. TIME
  960.  
  961. The built-in Time function returns the current time as measured by the
  962. P-ROBOTS' CPU cycles.  By using this function, you should be able to calculate
  963. the speed of your enemies.  The value returned by this function is restricted
  964. to being in the range 0 to 32767 and when it gets to 32767 it starts again at
  965. zero.  An example of how you might get this value is as follows:
  966.  
  967.              Start_Time := Time;
  968.  
  969.  
  970. DISTANCE
  971.  
  972. Since your robot will frequently find it useful to be able to calculate
  973. distances from one point on the battlefield to another, P-ROBOTS provides a
  974. built-in function to do it:
  975.  
  976.              Distance(X1,Y1,X2,Y2)
  977.  
  978. would return the integer distance from the point X1,Y1 to the point X2,Y2.
  979.  
  980.  
  981. ANGLE_TO
  982.  
  983. The Angle_To function will return the angle to a point on the battlefield from
  984. your robot's current position.  The value returned will be an integer in
  985. degrees from 0 to 359.  As an example of how both the Distance and Angle_To
  986. functions might be used, consider the following procedure that will move your
  987. robot to the point X,Y on the battlefield:
  988.  
  989.      PROCEDURE GoTo(X, Y : Integer);(* Go to location X,Y on playing field. *)
  990.        VAR
  991.          Heading  : Integer;
  992.      BEGIN       (* Find the heading we need to get to the desired spot. *)
  993.        Heading := Angle_To(X, Y);
  994.  
  995.        (* Keep traveling at top speed until we are within 150 meters. *)
  996.        WHILE (Distance(Loc_X, Loc_Y, X, Y) > 150) DO Drive(Heading, MaxSpeed);
  997.  
  998.        (* Cut speed, and creep the rest of the way. *)
  999.        WHILE (Distance(Loc_X, Loc_Y, X, Y) > 20) DO Drive(Heading, 20);
  1000.  
  1001.        (* Stop driving, should coast to a stop. *)
  1002.  
  1003.                                          18
  1004.  
  1005.  
  1006.  
  1007.  
  1008.        Drive(Heading, 0); (* i.e., Stop *)
  1009.      END; (* GoTo(X,Y) *)
  1010.  
  1011.  
  1012. RANDOM
  1013.  
  1014. The function Random(limit) returns a random integer between 0 and limit.  As an
  1015. example, the following procedure will cause your robot to move to a random spot
  1016. on the battlefield:
  1017.  
  1018.        PROCEDURE Move; (* Move to a random spot on the playing field. *)
  1019.          VAR
  1020.            x, y       : Integer;
  1021.        BEGIN
  1022.          x := Random(900) + 50;
  1023.          y := Random(900) + 50;
  1024.          GoTo(x, y);
  1025.        END; (* Move *)
  1026.  
  1027. Notice that the Move procedure makes use of the GoTo(X,Y) procedure developed
  1028. in the previous example.
  1029.  
  1030.  
  1031. TRIG FUNCTIONS
  1032.  
  1033. P-ROBOTS has several standard Trig functions that will be of value to a clever
  1034. robot, specifically:
  1035.  
  1036.              Sin(degree)
  1037.  
  1038. will return the real value of the Sin of an angle of degree where degree is an
  1039. integer from 0 to 359.
  1040.  
  1041.              Cos(degree)
  1042.  
  1043. will return the real value of the Cos of an angle of degree where degree is an
  1044. integer from 0 to 359.
  1045.  
  1046.              ArcTan(ratio)
  1047.  
  1048. will the angle in integer degrees that has a Tan of ratio.
  1049.  
  1050.  
  1051. INFLICTING DAMAGE
  1052.  
  1053. Your robot can be damaged by only two things: collisions and explosions.  The
  1054. "normal" level of damage is given by the following table:
  1055.  
  1056.      2%  --    A collision with another robot (both robots in a collision
  1057.                receive damage) or one of the battlefield walls.  A collision
  1058.                also causes the robot to stop cold, i.e., its speed is reduced
  1059.  
  1060.                                          19
  1061.  
  1062.  
  1063.  
  1064.                instantly to 0.
  1065.  
  1066.      3%  --    A missile explodes within a 40 meter radius.
  1067.  
  1068.      5%  --    A missile explodes within a 20 meter radius.
  1069.  
  1070.      10% --    A missile explodes within a 5 meter radius.
  1071.  
  1072. The actual damage is determined by the options (Armor, Shielding, etc.) for the
  1073. robot being attacked as well as by the options of the attacking robots (Missile
  1074. type, Bombs, etc).  The values given above are the defaults for "normally"
  1075. equipped robots.  The impact of the options on the damage will be discussed
  1076. later.
  1077.  
  1078. Damage is inflicted on ALL robots within these distances.  That means that if
  1079. one of your own missiles explodes within 40 meters of your robot, it causes
  1080. damage.  Using sloppy programming logic, it is possible for your robot to
  1081. commit suicide by firing missiles too close to itself.  For example, your robot
  1082. would not last long with this code:
  1083.  
  1084.                   Drive(Angle, 50);
  1085.                   WHILE (Loc_X < 999) DO Cannon(Angle,Scan(Angle,10));
  1086.  
  1087. Damage is cumulative, and cannot be repaired.  However, a robot does not loose
  1088. any mobility, fire potential, etc. at high damage levels.  In other words, a
  1089. robot at 99% damage performs equally as well as a robot with no damage.
  1090. However, when the damage level gets to 100% your robot is dead and it is out of
  1091. the current competition.
  1092.  
  1093.  
  1094. PUTTING IT ALL TOGETHER
  1095.  
  1096. Here is a complete sample robot named HotShot:
  1097.  
  1098.      PROCEDURE HotShot;
  1099.      {
  1100.       Author: David Malmberg
  1101.  
  1102.       Strategy:  Stay in one place.  Find a foe.  Take a shot.
  1103.       Keep improving aim and shooting until foe is lost from sights.
  1104.       Then move sights (scanning) to adjacent target area.  If
  1105.       hit, then move to another random position on playing field.
  1106.       If the Robot scans two complete circles (720 degrees) without
  1107.       finding a foe in shooting range, move to another spot on the
  1108.       field.  (This will avoid "stand-offs" where opponents stay
  1109.       just out of range of one another.)
  1110.  
  1111.       This Robot should be VERY effective against foes which
  1112.       are stopped or are moving slowly.  It will be less effective
  1113.       against Robots traveling at high speeds.
  1114.      }
  1115.  
  1116.                                          20
  1117.  
  1118.  
  1119.  
  1120.  
  1121.      VAR { HotShot "Global" variables }
  1122.  
  1123.        Angle, { Scanning angle }
  1124.        Last_Damage, { Robot's Last damage value }
  1125.        Range, { Range/Distance to foe }
  1126.        Sweep, { "Sweep count" -- when = 36, Robot has scanned 720 degrees }
  1127.        Delta          : Integer; { Scanning arc }
  1128.  
  1129.  
  1130.      PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  1131.    {
  1132.     Improve aim by doing a binary search of the target area,
  1133.     i.e., divide the target area in two equal pieces and redefine
  1134.     the target area to be the piece where the foe is found.
  1135.     If the foe is not found, expand the search area to the
  1136.     maximum arc of plus or minus 10 degrees.
  1137.    }
  1138.        BEGIN
  1139.          Arc := Arc DIV 2; { Divide search area in two. }
  1140.          IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  1141.            THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  1142.            ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle.}
  1143.              THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  1144.              ELSE Arc := 10;
  1145.          { Foe not found in either piece, expand search area to maximum arc. }
  1146.        END; {Aim}
  1147.  
  1148.  
  1149.      PROCEDURE BlastThem;
  1150.        BEGIN
  1151.          Angle := 10;
  1152.          REPEAT
  1153.            Delta := 10; { Start with widest scanning arc. }
  1154.            Range := scan(Angle, Delta);
  1155.            WHILE (Range > 40) AND (ObjectScanned = Enemy)
  1156.              AND (Range < MaxMissileRange) DO
  1157.            { Must be far enough away to avoid self-damage. }
  1158.              BEGIN
  1159.                Aim(Angle, Delta); { Improve aim. }
  1160.                Cannon(Angle, Range); { Fire!! }
  1161.                Range := scan(Angle, Delta); { Is foe still in sights? }
  1162.              END;
  1163.            Angle := Angle+20; { Look in adjacent target area. }
  1164.          UNTIL Angle > 360;
  1165.        END;
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.                                          21
  1173.  
  1174.  
  1175.  
  1176.  
  1177.      PROCEDURE GOTO(x, y : Integer);
  1178.          { Go to location X,Y on playing field. }
  1179.        VAR Heading    : Integer;
  1180.        BEGIN
  1181.          { Find the heading we need to get to the desired spot. }
  1182.          Heading := Angle_To(x, y);
  1183.  
  1184.          { Keep traveling at top speed until we are within 150 meters }
  1185.          WHILE (distance(loc_x, loc_y, x, y) > 150) DO
  1186.            BEGIN
  1187.              Drive(Heading, MaxSpeed);
  1188.              BlastThem;
  1189.            END;
  1190.  
  1191.          { Cut speed, and creep the rest of the way. }
  1192.          WHILE (distance(loc_x, loc_y, x, y) > 20) DO
  1193.            BEGIN
  1194.              Drive(Heading, 20);
  1195.              BlastThem;
  1196.            END;
  1197.  
  1198.          { Stop driving, should coast to a stop. }
  1199.          Drive(Heading, 0); {i.e., Stop}
  1200.        END; {GoTo(X,Y)}
  1201.  
  1202.  
  1203.      FUNCTION Hurt  : Boolean;
  1204.          { Checks if Robot has incurred any new damage. }
  1205.        VAR Curr_Damage : Integer;
  1206.          Answer         : Boolean;
  1207.        BEGIN
  1208.          Curr_Damage := damage;
  1209.          Answer := (Curr_Damage > Last_Damage);
  1210.          Last_Damage := Curr_Damage;
  1211.          Hurt := Answer;
  1212.        END; {Hurt}
  1213.  
  1214.  
  1215.      PROCEDURE Move;
  1216.          { Move to a random spot on the playing field. }
  1217.        VAR x, y       : Integer;
  1218.        BEGIN
  1219.          Sweep := 0; { Reset Sweep counter to zero. }
  1220.          x := Random(900)+50;
  1221.          y := Random(900)+50;
  1222.          GOTO(x, y);
  1223.        END; {Move}
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.                                          22
  1230.  
  1231.  
  1232.  
  1233.      BEGIN {HotShot Main}
  1234.        Angle := Angle_To(500, 500);
  1235.        { Start scanning for foes in center of field. }
  1236.        Sweep := 0; { Initialize Sweep counter to zero. }
  1237.        REPEAT { Until Dead or Winner }
  1238.          Delta := 10; { Start with widest scanning arc. }
  1239.          Range := scan(Angle, Delta);
  1240.          WHILE (Range > 40) AND (Range < 700) DO
  1241.            { Must be far enough away to avoid self-damage. }
  1242.            BEGIN
  1243.              Sweep := 0; { Found foe, so reset Sweep to zero }
  1244.              Aim(Angle, Delta); { Improve aim. }
  1245.              cannon(Angle, Range); { Fire!! }
  1246.              Range := scan(Angle, Delta); { Is foe still in sights? }
  1247.            END;
  1248.          Angle := Angle+20; { Look in adjacent target area. }
  1249.          Sweep := Sweep+1;
  1250.          IF Hurt OR (Sweep = 36) THEN Move;
  1251.          { If hit or have scanned two full circles, move elsewhere. }
  1252.        UNTIL Dead OR Winner;
  1253.      END; (* HotShot Main *)
  1254.  
  1255.  
  1256. ROBOT PROGRAMMING RULES
  1257.  
  1258. There are several things in the above example that you should think of as rules
  1259. that your robots should ALWAYS observe.
  1260.  
  1261.      1.   Your robot should be in a "self-contained" PROCEDURE with the
  1262.           following basic structure:
  1263.  
  1264.                    PROCEDURE RoboName;
  1265.  
  1266.                      {"Global" Variables}
  1267.  
  1268.                      FUNCTION A;
  1269.                         ....
  1270.                      PROCEDURE B;
  1271.                         ....
  1272.                      FUNCTION Z;
  1273.  
  1274.                    BEGIN {RoboName Main}
  1275.                         ....
  1276.                    END; {RoboName Main}
  1277.  
  1278.           Failure to follow this basic structure will cause the P-ROBOTS
  1279.           program and your robot to both meet a fiery death.  Notice that your
  1280.           robot procedure ends with a ";" -- not a "."
  1281.  
  1282.  
  1283.  
  1284.  
  1285.                                          23
  1286.  
  1287.  
  1288.  
  1289.  
  1290.      2.   A robot should have its PROCEDURE named exactly the same name as the
  1291.           file with the code for the robot (except for the .PR extension);
  1292.           i.e., the HotShot robot procedure should be in a  file named
  1293.           HOTSHOT.PR.  Again, failure to follow this rule will cause your robot
  1294.           program to crash.
  1295.  
  1296.      3.   In the "main" routine for your robot, you need to have some kind of
  1297.           "infinite" loop that is repeated endlessly.  In the sample robot,
  1298.           HOTSHOT, this loop is the REPEAT ... UNTIL structure:
  1299.  
  1300.                   REPEAT (* Until Dead or Winner *)
  1301.                     ....
  1302.                   UNTIL Dead OR Winner;
  1303.  
  1304.           Another "infinite" loop that would works equally well is:
  1305.  
  1306.                   WHILE (NOT Dead) AND (NOT Winner) DO
  1307.                     BEGIN
  1308.                       ....
  1309.                     END;
  1310.  
  1311.      4.   Your robot source code should be very well documented with comments.
  1312.  
  1313.  
  1314. ADVANCED P-ROBOT FEATURES
  1315.  
  1316. All of the robot programming ground rules and robot-specific language presented
  1317. up to this point correspond to features found in C-ROBOTS by Tom Poindexter --
  1318. which was the inspiration for P-ROBOTS.  After  P-ROBOTS had been released for
  1319. several months, users began to make suggestions for improvements and new
  1320. features.  In the current version 4.0, I have tried to incorporate the best
  1321. suggestions.  Specifically, version 4.0 adds the following improvements and new
  1322. features:
  1323.  
  1324.              *    Animation Speed Options
  1325.              *    Protective Shields and Cloaking
  1326.              *    Fuel Constraints
  1327.              *    Options for Radar Range, Engine Size, Armor, Missile types,
  1328.                   Bombs and Repairing
  1329.              *    Robot Teams
  1330.              *    Obstructions on the Battlefield
  1331.  
  1332. NOTE: All of these new features are optional.  Your old (Versions 1.0 -- 3.0)
  1333. robots can still be used just as they have always been used.
  1334.  
  1335.  
  1336. CONTROLLING THE ANIMATION SPEED
  1337.  
  1338. Since not all computers operate at the same speed, it is very desirable to be
  1339. able to control the animation speed of the robot contest.  This can be done by
  1340. using another command line parameter, the "/SN" parameter, where N can be
  1341.  
  1342.                                          24
  1343.  
  1344.  
  1345.  
  1346.  
  1347. either 1, 2, 3 ... up to 10.  A value of 1 corresponds to the slowest animation
  1348. speed and 10 is the fastest.  The normal default setting is 7 which will
  1349. normally look fine on a 80286 or 80386 computer.  If you are using a 486
  1350. machine, you will probably want to use one of the slower animation speeds.  For
  1351. example, to run a single game among the robots: NINJA, HOTSHOT, WIMP and
  1352. BLASTER at a moderately slow animation speed (i.e., a speed of 3) you would
  1353. enter the command:
  1354.  
  1355.              P-ROBOTS NINJA HOTSHOT WIMP BLASTER /S3
  1356.  
  1357. If you are playing a series of contests (i.e., match play), you should not slow
  1358. down the speed since these games are not displayed/animated anyway.
  1359.  
  1360.  
  1361. PROTECTIVE SHIELDS AND CLOAKING
  1362.  
  1363. In version 4.0 of P-ROBOTS, your robot can use a protective Shield by using the
  1364. command "RaiseShield".  When your robot's Shield is up, your robot will not
  1365. incur any damage from collisions or missile explosions.  The Shield may be
  1366. lowered by using the command "LowerShield".  The status of your robot's Shield
  1367. can be determined by using the built-in Boolean function, "ShieldRaised" which
  1368. will return a value of TRUE or FALSE based on your robot's shield condition.
  1369. For example, you might want to use the following statement in a robot program:
  1370.  
  1371.              IF NOT ShieldRaised THEN RaiseShield;
  1372.  
  1373. You may also check to see if your robot has a Shield option by using the built-
  1374. in Boolean Function "HaveShield".
  1375.  
  1376. NOTE: Unlike the Starship Enterprise, your robot has only one Shield (i.e.,
  1377. singular) not multiple Shields (plural).  If you use "Shields" (plural) in your
  1378. robot programs, you will get a compiler error for an "Unknown Identifier".
  1379.  
  1380. In version 4.0 of P-ROBOTS, your robot can also use a protective "Cloak" by
  1381. using the command "RaiseCloak".  When your robot's Cloak is up, your robot will
  1382. be invisible to other robot's scanners/radars (except if they are equipped with
  1383. an "Anti-Cloaking" Device).  The Cloak may be lowered by using the command
  1384. "LowerCloak".  You may also check to see if your robot has a Cloak option by
  1385. using the built-in Boolean Function "HaveCloak".
  1386.  
  1387. If your robot has its cloak raised, this fact will be shown by having your
  1388. robot "blink" on the screen.  At the same time, the robots name on the status
  1389. panel will also blink.  When you lower the cloak, the blink will stop.
  1390.  
  1391. Of course, there must be a "catch" to using a Shield or a Cloak -- or there
  1392. would not be any real challenge to a robot contest.  The catch is that Shields
  1393. and Cloaks use scarce fuel resources as explained in the following section.
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.                                          25
  1400.  
  1401.  
  1402.  
  1403.  
  1404. FUEL CONSTRAINTS
  1405.  
  1406. Many people have commented that P-ROBOTS (and C-ROBOTS before it) seemed to
  1407. favor robots that used "brute force" rather than "raw cunning" -- i.e., all
  1408. other things being equal, robots that fired often seem to beat robots that
  1409. fired accurately.  In an effort to create a more level playing field for smart
  1410. robots, I have added fuel constraints to P-ROBOTS.  Under these constraints,
  1411. robots that fire indiscriminately will waste valuable fuel and will ultimately
  1412. run out of fuel and find themselves defenseless and at the mercy of their wiser
  1413. and more fuel efficient opponents.
  1414.  
  1415. When having a robot battle that has fuel constraints, each robot normally
  1416. begins the contest with 1250 "jiggers" of fuel.  Then, during the contest, fuel
  1417. is normally used up at the following rates:
  1418.  
  1419.              *  Firing a missile takes 3 jiggers
  1420.              *  Traveling 100 meters takes 6 jiggers
  1421.              *  Having a shield up for 1000 CPU cycles takes 6 jiggers
  1422.              *  Having a cloak up for 1000 CPU cycles takes 5 jiggers
  1423.  
  1424. These fuel usage rates are the "default" values.  Your robots specific usage
  1425. rates will depend upon the options you have selected for your robots.  The
  1426. details will be explained in the next few sections.
  1427.  
  1428. In addition, if your robot's Shield is up, whenever your robot would have
  1429. incurred damage from a missile or a collision, it uses twice the number of
  1430. jiggers of fuel to absorb the damage as it would have incurred in damage had
  1431. its Shield been down.  For example, when your robot's Shield is up, absorbing a
  1432. direct missile hit uses 20 jiggers of fuel (normally); absorbing the impact of
  1433. a collision with another robot uses 4 jiggers of fuel (normally), etc.  So, it
  1434. is prudent for your robot to take care to avoid missiles and collisions even if
  1435. its Shield is raised.
  1436.  
  1437. The number of jiggers of each robot's fuel is displayed continuously next to
  1438. the robot's name on the screen.  This value may be accessed from within a robot
  1439. program by using the built-in function "Fuel".  For example, you might want to
  1440. use the following logic in a robot program to begin a special "End-Game"
  1441. strategy when your fuel gets low:
  1442.  
  1443.              IF Fuel < 200 THEN End_Game;
  1444.  
  1445. There are several other built-in P-ROBOTS functions that may be useful when you
  1446. have fuel constraints.  Specifically, "LimitedFuel" will return a TRUE or FALSE
  1447. based upon whether the contest your robot is playing in has fuel constraints or
  1448. not.  The built-in function "Meters" is like an Odometer on a car -- only it
  1449. returns the number of meters your robot has traveled since the beginning of the
  1450. contest.  For example, you might wish to use the following command in your
  1451. robot's program to invoke your "End-Game" strategy:
  1452.  
  1453.              IF LimitedFuel
  1454.                 THEN IF (Meters > 20000) OR (Fuel < 200) THEN End_Game;
  1455.  
  1456.                                          26
  1457.  
  1458.  
  1459.  
  1460.  
  1461. To have a robot contest without fuel constraints, you should use a "/U" command
  1462. line parameter when you invoke your contest.  For example, to run a single game
  1463. among the robots: NINJA, WIMP and BLASTER without fuel constraints, you would
  1464. enter the following command at the DOS prompt:
  1465.  
  1466.              P-ROBOTS NINJA WIMP BLASTER /U
  1467.  
  1468. If you wish to have a series of 50 matches without fuel constraints among the
  1469. same group of robots, you would add a "/M50" parameter to the command as
  1470. follows:
  1471.  
  1472.              P-ROBOTS NINJA WIMP BLASTER /U /M50
  1473.  
  1474.  
  1475. RUNNING OUT OF FUEL
  1476.  
  1477. When your robot runs out of fuel it does everything you might expect: it stops
  1478. cold and can no longer move; it can no longer fire its cannon; and it can no
  1479. longer maintain a raised shield.  In other words, it is totally and absolutely
  1480. defenseless.  Other robots which still have fuel will make quick work of any
  1481. robot that is unfortunate enough to become a sitting duck by running out of
  1482. fuel.  If all of the robots in the game run out of fuel, the game is over and
  1483. the robot with the least damage (i.e., the strongest of the survivors) is
  1484. declared the winner.
  1485.  
  1486.  
  1487. AN EXAMPLE USING A SHIELD AND FUEL
  1488.  
  1489. Here is an example of how the previous example robot, HOTSHOT, might be
  1490. modified to use its Shield and consider Fuel constraints:
  1491.  
  1492.  
  1493.      PROCEDURE HotShot2;
  1494.      {
  1495.       Author: David Malmberg
  1496.  
  1497.       Strategy:  Stay in one place.  Find a foe.  Take a shot.
  1498.       Keep improving aim and shooting until foe is lost from sights.
  1499.       Then move sights (scanning) to adjacent target area.
  1500.       If the Robot scans a complete circle (360 degrees) without
  1501.       finding a foe in shooting range, move to another spot on the
  1502.       field.  (This will avoid "stand-offs" where opponents stay
  1503.       just out of range of one another.)  RaiseShield when standing
  1504.       still and lower them when moving.
  1505.  
  1506.       When damage gets to 70 (or more) or fuel (if using fuel) gets
  1507.       below 200 adopt an "End-Game" strategy of moving to the lower
  1508.       left corner, lower shield, and continue to scan and shoot in
  1509.       the corner's 90 degree range.
  1510.  
  1511.       This Robot should be VERY effective against foes which
  1512.  
  1513.                                          27
  1514.  
  1515.  
  1516.  
  1517.  
  1518.       are slow and/or tend to stay in one place.}
  1519.  
  1520.      PROCEDURE GOTO(x, y : Integer);
  1521.          { Go to location X,Y on playing field. }
  1522.        VAR Heading    : Integer;
  1523.        BEGIN
  1524.          { Find the heading we need to get to the desired spot. }
  1525.          Heading := Angle_To(x, y);
  1526.  
  1527.          { Keep traveling at top speed until we are within 150 meters }
  1528.          WHILE (distance(loc_x, loc_y, x, y) > 150) DO
  1529.            BEGIN
  1530.              Drive(Heading, MaxSpeed);
  1531.              BlastThem;
  1532.            END;
  1533.  
  1534.          { Cut speed, and creep the rest of the way. }
  1535.          WHILE (distance(loc_x, loc_y, x, y) > 20) DO
  1536.            BEGIN
  1537.              Drive(Heading, 20);
  1538.              BlastThem;
  1539.            END;
  1540.  
  1541.          { Stop driving, should coast to a stop. }
  1542.          Drive(Heading, 0); {i.e., Stop}
  1543.        END; {GoTo(X,Y)}
  1544.  
  1545.      PROCEDURE Move;
  1546.          { Move to a random spot on the playing field. }
  1547.        VAR x, y       : Integer;
  1548.        BEGIN
  1549.          Sweep := 0; { Reset Sweep counter to zero. }
  1550.          x := Random(900)+50;
  1551.          y := Random(900)+50;
  1552.          GOTO(x, y);
  1553.        END; {Move}
  1554.  
  1555.  
  1556.      PROCEDURE End_Game;
  1557.      BEGIN {End_Game}
  1558.        GoTo(0,0); {Lower Left Corner}
  1559.        Angle := 10; {Sweep arc from 0 to 90 degrees only}
  1560.        REPEAT
  1561.          Delta := 10; { Start with widest scanning arc. }
  1562.          Range := scan(Angle, Delta);
  1563.          WHILE (Range > 40) AND (Range < MaxRadarRange) DO
  1564.            { Must be far enough away to avoid self-damage. }
  1565.            BEGIN
  1566.              Aim(Angle, Delta); { Improve aim. }
  1567.              cannon(Angle, Range); { Fire!! }
  1568.              Range := scan(Angle, Delta); { Is foe still in sights? }
  1569.  
  1570.                                          28
  1571.  
  1572.  
  1573.  
  1574.  
  1575.            END;
  1576.          Angle := Angle+20; { Look in adjacent target area. }
  1577.          IF Angle > 90 THEN Angle := 10;
  1578.        UNTIL Dead OR Winner;
  1579.      END; {End_Game}
  1580.  
  1581.  
  1582.      BEGIN {HotShot2 Main}
  1583.        RaiseShield;
  1584.        Angle := 0;
  1585.        GoTo(500, 500); { Move to center of field. }
  1586.        Sweep := 0; { Initialize Sweep counter to zero. }
  1587.        REPEAT { Until Dead or Winner }
  1588.          Delta := 10; { Start with widest scanning arc. }
  1589.          Range := scan(Angle, Delta);
  1590.          WHILE (Range > 40) AND (Range < MaxRadarRange) DO
  1591.            { Must be far enough away to avoid self-damage. }
  1592.            BEGIN
  1593.              Sweep := 0; { Found foe, so reset Sweep to zero }
  1594.              Aim(Angle, Delta); { Improve aim. }
  1595.              cannon(Angle, Range); { Fire!! }
  1596.              Range := scan(Angle, Delta); { Is foe still in sights? }
  1597.            END;
  1598.          Angle := Angle+20; { Look in adjacent target area. }
  1599.          Sweep := Sweep+1;
  1600.          IF Sweep >= 18 THEN
  1601.            BEGIN { If robot has scanned a full circle, move elsewhere. }
  1602.              LowerShield; {Don't need shield (as much) when moving}
  1603.              Move;
  1604.            END;
  1605.  
  1606.          RaiseShield; {Standing still so use shield}
  1607.  
  1608.          {"End" game strategy}
  1609.          IF (Fuel < 200) OR (Damage > 70) THEN End_Game;
  1610.  
  1611.        UNTIL Dead OR Winner;
  1612.  
  1613.      END; {HotShot2 Main}
  1614.  
  1615.  
  1616. OTHER OPTIONS
  1617.  
  1618. One of the best suggestions that I received from previous users of P-ROBOTS was
  1619. the idea of allowing robots with different configurations and/or options.  This
  1620. capability has been added to version 4.0.  Specifically, with the latest
  1621. version of P-ROBOTS, it is possible to allocate a total of 10 "configuration
  1622. points" to select among options for : Radar Range, Fuel Capacity, Engine Size
  1623. and Speed, Armor, Missile Warheads, Electronic Bombs, Shielding, Cloaking, and
  1624. Repairing.  These configuration points are specified in a separate .CFG file
  1625. for your robot.  For example, if your robot is named BOMBER, then you would
  1626.  
  1627.                                          29
  1628.  
  1629.  
  1630.  
  1631.  
  1632. create a separate BOMBER.CFG file that contained something like the following
  1633. lines:
  1634.  
  1635.         {Option Points must total 10 points!!}
  1636.         Radar := 2;          {Maximum range for robot's scanner -- 600 meters}
  1637.         Fuel := 2;           {Maximum fuel for robot's -- 1250 "jiggers"}
  1638.         Engine := 2;         {Type of engine for robot -- Standard engine}
  1639.         Armor := 1;          {Type of Armor for robot -- Medium armor}
  1640.         Warheads := 1;       {Type of Missile for robot -- Normal warheads}
  1641.         Bombs := 0;          {Determines the number of Bombs for robot -- no
  1642.         bombs}
  1643.         Shielding := 2;      {Default -- Robot has Shielding}
  1644.         Cloaking := 0;       {Default -- Robot has NO Cloaking}
  1645.         Repairing := 0;      {Default -- Robot has NO Repair Kit}
  1646.  
  1647. Incidently, the above option values are the normal defaults.  Specifically, if
  1648. you do not specify different options in a separate .CFG file, your robot will
  1649. have the above options.  These defaults were chosen to be consistent with both
  1650. C-ROBOTS and version 1.0 of P-ROBOTS -- so your "old" robots do not need a
  1651. separate .CFG file (except, of course, if you want to change their
  1652. configuration to something new).
  1653.  
  1654. Each of these options will be discussed in separate sections below.
  1655.  
  1656.  
  1657. RADAR RANGE OPTIONS
  1658.  
  1659. You can allocate from 0 to 5 points for differently equipped radars as follows:
  1660.  
  1661.      0 points -- Radar range is limited to 200 meters
  1662.      1 points -- Radar range is limited to 400 meters
  1663.      2 points -- Radar range is limited to 600 meters  <-- Default value
  1664.      3 points -- Radar range is limited to 800 meters
  1665.      4 points -- Radar range is limited to 1000 meters
  1666.      5 points -- Radar range is limited to 1200 meters -- with Anti-Cloaking
  1667.  
  1668. If you allocate 5 points (out of your total possible of 10) to your radar, you
  1669. will get a "bonus" Anti-Cloaking Device that will enable your robot to
  1670. scan/detect enemy robots even if they are Cloaked.
  1671.  
  1672. Your robot's maximum radar range is specified within your robot program by the
  1673. built-in P-ROBOTS function MaxRadarRange.
  1674.  
  1675.  
  1676. FUEL OPTIONS
  1677.  
  1678. You can allocate from 0 to 5 points for different "gas tanks" and fuel capacity
  1679. as follows:
  1680.  
  1681.  
  1682.  
  1683.  
  1684.                                          30
  1685.  
  1686.  
  1687.  
  1688.  
  1689.         0 points -- Fuel capacity is 750 "jiggers"
  1690.         1 points -- Fuel capacity is 1000 "jiggers"
  1691.         2 points -- Fuel capacity is 1250 "jiggers"  <-- Default value
  1692.         3 points -- Fuel capacity is 1500 "jiggers"
  1693.         4 points -- Fuel capacity is 1750 "jiggers"
  1694.         5 points -- Fuel capacity is 2000 "jiggers"
  1695.  
  1696. Your robot's current fuel level is specified within your robot program by the
  1697. built-in P-ROBOTS function Fuel.
  1698.  
  1699.  
  1700. ENGINE SIZE AND SPEED OPTIONS
  1701.  
  1702. You can allocate from 0 to 4 points for different robot engines as follows:
  1703.  
  1704.         0 points -- Economy engine -- maximum speed of 60
  1705.         1 points -- Compact engine -- maximum speed of 80
  1706.         2 points -- Standard engine -- maximum speed of 100  <-- Default value
  1707.         3 points -- Large engine -- maximum speed of 120
  1708.         4 points -- Extra-Large engine -- maximum speed of 140
  1709.  
  1710. Bigger engines not only go faster, but they burn fuel faster.  Specifically,
  1711. below are the number of "jiggers" of fuel that each type of engine uses to
  1712. travel 100 meters:
  1713.  
  1714.         Economy engine -- 4 "jiggers"
  1715.         Compact engine -- 5 "jiggers"
  1716.         Standard engine -- 6 "jiggers"  <-- Default value
  1717.         Large engine -- 7 "jiggers"
  1718.         Extra-Large engine -- 8 "jiggers"
  1719.  
  1720. Your robot's engine type can be determined within your robot program by the
  1721. built-in P-ROBOTS function Engine which will return one of the built-in P-
  1722. ROBOTS CONST values: Economy, Compact, Standard, Large, or ExtraLarge.
  1723.  
  1724. Your robot's maximum speed is specified within your robot program by the built-
  1725. in P-ROBOTS function MaxSpeed.
  1726.  
  1727.  
  1728. ARMOR OPTIONS
  1729.  
  1730. You can allocate from 0 to 2 points for different armor options as follows:
  1731.  
  1732.         0 points -- Light armor
  1733.         1 points -- Medium armor  <-- Default value
  1734.         2 points -- Heavy armor
  1735.  
  1736. As might be expected, heavier armor provides greater protection against damage
  1737. from collisions and missile explosions as given by the following table:
  1738.  
  1739.  
  1740.  
  1741.                                          31
  1742.  
  1743.  
  1744.  
  1745.  
  1746.                                                   DAMAGE PERCENT
  1747.                                      ----------------------------------------
  1748.                                      Light Armor   Medium Armor   Heavy Armor
  1749.                                      -----------   ------------   -----------
  1750.         Explosion within 5 meters       16              8             4
  1751.         Explosion within 20 meters       8              4             2
  1752.         Explosion within 40 meters       4              2             1
  1753.         Collision                        3              2             1
  1754.  
  1755. For example, with light armor a robot would suffer 8 units (i.e., percent) of
  1756. damage if a missile exploded within 20 meters of the robot -- versus only 2
  1757. units of damage if the same robot were equipped with heavy armor.
  1758.  
  1759. However, not surprisingly, there are trade-offs with heavier armor.
  1760. Specifically, the type of armor has the following effect on the maximum speed
  1761. of the robot:
  1762.  
  1763.                  MAXIMUM SPEED ADJUSTMENT
  1764.         ----------------------------------------
  1765.         Light Armor   Medium Armor   Heavy Armor
  1766.         -----------   ------------   -----------
  1767.            + 25         none or 0       - 25
  1768.  
  1769.  
  1770. For example, a robot with an extra-large engine that would normally have a
  1771. maximum speed of 140 would be slowed down to a maximum speed of 115 if it were
  1772. equipped with heavy armor (i.e., 140 - 25).  Conversely, the same robot would
  1773. have a maximum speed of 165 if it were equipped with light armor (i.e., 140 +
  1774. 25).
  1775.  
  1776. Your robot's maximum speed is specified within your robot program by the built-
  1777. in P-ROBOTS function MaxSpeed.  Your robot's armor type can be determined
  1778. within your robot program by using the built-in P-ROBOTS function Armor which
  1779. will return one of the built-in P-ROBOTS CONST values: Light, Medium, or Heavy.
  1780.  
  1781.  
  1782. MISSILE WARHEAD OPTIONS
  1783.  
  1784. You can allocate from 0 to 2 points for different missile warheads as follows:
  1785.  
  1786.         0 points -- "Wimp" warheads
  1787.         1 points -- "Normal" warheads  <-- Default value
  1788.         2 points -- "Premium" warheads
  1789.  
  1790. Naturally, different types of warheads have different missile ranges:
  1791.  
  1792.              MAXIMUM MISSILE RANGE
  1793.         -----------------------------
  1794.         "Wimp"   "Normal"   "Premium"
  1795.         ------   --------   ---------
  1796.           350      700        1500
  1797.  
  1798.                                          32
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804. Not unexpectedly, different types of warheads also cause different levels of
  1805. damage -- depending upon the kind of armor the robot being attacked has.
  1806. Specifically, the following units (percent) of damage are added to the damage
  1807. normally incurred:
  1808.  
  1809.                                          ADDITIONAL DAMAGE DUE TO WARHEAD
  1810.                                      ----------------------------------------
  1811.                                        "Wimp"        "Normal"      "Premium"
  1812.                                      -----------   ------------   -----------
  1813.         Explosion within 5 meters       0              3             6
  1814.         Explosion within 20 meters      0              2             4
  1815.         Explosion within 40 meters      0              1             2
  1816.  
  1817.  
  1818. For example, a robot with light armor would suffer 12 units (i.e., 8 + 4) of
  1819. damage if a "premium" missile exploded within 20 meters of it -- versus 8 units
  1820. (i.e., 8 +0) of damage if it was hit with a "wimp" missile.
  1821.  
  1822. Your robot's maximum missile range is specified within your robot program by
  1823. the built-in P-ROBOTS function MaxMissileRange.  Your robot's warhead type can
  1824. be determined within your robot program by the built-in P-ROBOTS function
  1825. Warheads which will return one of the built-in P-ROBOTS CONST values: Wimp,
  1826. Normal, or Premium.
  1827.  
  1828.  
  1829. ELECTRONIC BOMB OPTIONS
  1830.  
  1831. You can allocate from 0 to 5 points for electronic bombs as follows:
  1832.  
  1833.         0 points -- Robot is equipped with 0 bombs  <-- Default value
  1834.         1 points -- Robot is equipped with 3 bombs
  1835.         2 points -- Robot is equipped with 6 bombs
  1836.         3 points -- Robot is equipped with 9 bombs
  1837.         4 points -- Robot is equipped with 12 bombs
  1838.         5 points -- Robot is equipped with 15 bombs
  1839.  
  1840. These bombs attack the robot's electronics.  As a result, shields, cloaks and
  1841. armor offer no defense against these bombs.  The amount of damage incurred by a
  1842. robot within the 300 meter range of one of these electronic bombs is given by
  1843. following formula:
  1844.  
  1845.         Damage points = 75 - (Distance from explosion)/4
  1846.  
  1847. For example, a direct hit (i.e., the distance from the explosion is zero)
  1848. causes 75 (i.e., 75 - 0/4) units of damage.  At 100 meters, a robot would incur
  1849. 50 (i.e., 75 - 100/4) units of damage from an electronic bomb.  No damage is
  1850. caused if the robot is more than 300 meters away from the bomb explosion.
  1851.  
  1852. NOTE:  Like missile explosions, electronic bombs cause damage to all robots in
  1853. the explosion area -- whether they are friend or foe.
  1854.  
  1855.                                          33
  1856.  
  1857.  
  1858.  
  1859.  
  1860. Your robot's number of bombs (currently left) can be determined within your
  1861. robot program by the built-in P-ROBOTS function BombsLeft.  Bombs are placed at
  1862. the robot's current location by invoking the built-in P-ROBOTS procedure
  1863. PlaceBomb.  Once a bomb has been placed, the bomb will be shown on the screen
  1864. as a blinking "male" symbol, i.e., a small circle with a curved "fuse" sticking
  1865. out of it.  Bombs are exploded at the bomb's location (where previously placed
  1866. using PlaceBomb) by invoking the built-in P-ROBOTS procedure Detonate.
  1867. Warning:  Be sure to have your robot over 300 meters away from its bomb when
  1868. you Detonate the bomb.
  1869.  
  1870.  
  1871. SHIELDING OPTIONS
  1872.  
  1873. You can allocate from 0 or 2 points for Shielding as follows:
  1874.  
  1875.         0 points -- Robot has no shielding capability
  1876.         2 points -- Robot is with a Shield  <-- Default value
  1877.  
  1878. NOTE:  The above is not a "typo" -- it takes 2 points to get a Shield!
  1879.  
  1880. Keeping the Shield up uses fuel.  The amount of fuel used (per 1000 CPU cycles)
  1881. depends on the type of armor the robot has, as follows:
  1882.  
  1883.         FUEL USED FOR SHIELD PER 1000 CPU CYCLES
  1884.         ----------------------------------------
  1885.         Light Armor   Medium Armor   Heavy Armor
  1886.         -----------   ------------   -----------
  1887.              3             6              9
  1888.  
  1889. Your robot should raise (or lower) its Shield by invoking the built-in P-ROBOTS
  1890. procedure RaiseShield (or LowerShield).  Whether or not your robot has a Shield
  1891. can be determined by using the built-in Boolean function HaveShield.
  1892.  
  1893.  
  1894. CLOAKING OPTIONS
  1895.  
  1896. You can allocate from 0 or 5 points for Cloaking as follows:
  1897.  
  1898.         0 points -- Robot has no Cloak  <-- Default value
  1899.         5 points -- Robot is equipped with a Cloak
  1900.  
  1901. NOTE:  The above is not a "typo" -- it takes 5 points to get equipped with a
  1902. Cloak!
  1903.  
  1904. Like Shields, Cloaks use fuel.  Specifically, cloaking uses 5 "jiggers" of fuel
  1905. per 1000 CPU cycles -- regardless of the kind of armor the robot has.
  1906.  
  1907. When a robot has it Cloak raised, it is "invisible" to other robot's radar
  1908. scanners (except in the case of a robot equipped with an "Anti-Cloaking"
  1909. device).  However, unlike shielding, a Cloak will not protect a robot from
  1910. damage.
  1911.  
  1912.                                          34
  1913.  
  1914.  
  1915.  
  1916.  
  1917. Your robot should raise (or lower) its Cloak by invoking the built-in P-ROBOTS
  1918. procedure RaiseCloak (or LowerCloak).  Whether or not your robot has a Cloak
  1919. can be determined by using the built-in Boolean function HaveCloak.
  1920.  
  1921. If your robot has its cloak raised, this fact will shown by having your robot
  1922. "blink" on the screen.  At the same time, the robots name on the status panel
  1923. will also blink.  When you lower the cloak, the blink will stop.
  1924.  
  1925.  
  1926. REPAIRING OPTIONS
  1927.  
  1928. You can allocate from 0 or 2 points for Repairing as follows:
  1929.  
  1930.         0 points -- Robot has no capability to repair itself  <-- Default value
  1931.         2 points -- Robot can repair itself
  1932.  
  1933. NOTE:  The above is not a "typo" -- it takes 2 points to get a Repair "Kit!"
  1934.  
  1935. In order to make repairs, the robot must be stopped (i.e., its speed must be
  1936. zero) and its repair "kit" must be activated.  While making repairs, the robot
  1937. reduces damage by converting fuel.  Specifically, it takes 4 "jiggers" of fuel
  1938. to reduce the robot's damage by 1 point.  It also takes time to make these
  1939. repairs -- each 1 unit of damage being repaired takes 100 CPU cycles.
  1940.  
  1941. Your robot should make (or stop) Repairs to itself by invoking the built-in P-
  1942. ROBOTS procedure MakeRepairs (or StopRepairs).  Whether or not your robot has a
  1943. Repair "Kit" can be determined by using the built-in Boolean function
  1944. HaveRepairKit.
  1945.  
  1946.  
  1947. AN EXAMPLE USING CLOAKING
  1948.  
  1949. Here is an example of a robot that uses Cloaking, named (aptly enough) Stealth
  1950. Fighter.
  1951.  
  1952.  
  1953.      PROCEDURE SFighter;  {Stealth Fighter}
  1954.      {
  1955.       Author: David Malmberg
  1956.  
  1957.       Strategy:  Move slowly around the field -- bouncing off of walls,
  1958.       obstructions, and other robots -- as necessary.  If you find a foe,
  1959.       take a shot and keep improving aim and shooting until foe is
  1960.       lost from sights.  Then move sights (scanning) to adjacent target
  1961.       area.
  1962.  
  1963.       When robot incurs damage, raise cloak and move away.  Keep cloak
  1964.       raised until robot has not had any damage for at least 3000 cycles.
  1965.      }
  1966.  
  1967.  
  1968.  
  1969.                                          35
  1970.  
  1971.  
  1972.  
  1973.  
  1974.    (* Below are the SFighter options as specified in the SFIGHTER.CFG file
  1975.  
  1976.    REMEMBER THIS IS A SEPARATE FILE THAT YOU MUST CREATE!!!
  1977.  
  1978.    Radar := 2;          {Maximum range for robot's scanner -- 600 meters}
  1979.    Fuel := 2;           {Maximum fuel for robot -- 1250 jiggers}
  1980.    Engine := 0;         {Type of engine for robot -- Economy}
  1981.    Armor := 0;          {Type of Armor for robot -- Light}
  1982.    Warheads := 1;       {Type of Missile for robot -- Normal - 700 meter range}
  1983.    Bombs := 0;          {Determines the number of Bombs for robot}
  1984.    Shielding := 0;      {Default -- Robot has Shielding}
  1985.    Cloaking := 5;       {Default -- Robot has Cloaking}
  1986.    Repairing := 0;      {Default -- Robot has NO Repair Kit}
  1987.  
  1988.    *)
  1989.  
  1990.      VAR { SFighter "Global" variables }
  1991.  
  1992.        Angle, { Scanning angle }
  1993.        Range, { Scanning range to foe -- hopefully! }
  1994.        Last_Damage, { Robot's Last damage value }
  1995.        D_Speed, { Robot's desired speed }
  1996.        D_Heading, { Robot's desired heading }
  1997.        LastTime, { Last Time cycles were measured }
  1998.        Delta          : Integer; { Scanning arc }
  1999.  
  2000.  
  2001.      PROCEDURE Bounce;
  2002.          { If stopped, then move away at an angle.  Designed to allow
  2003.            robot to "bounce" off of walls, obstructions and other robots. }
  2004.        BEGIN
  2005.          IF Speed = 0
  2006.            THEN BEGIN
  2007.              D_Heading := D_Heading + 120; { Bounce off at an angle }
  2008.              Drive(D_Heading, D_Speed);
  2009.            END;
  2010.        END; {Bounce}
  2011.  
  2012.  
  2013.      FUNCTION Hurt  : Boolean;
  2014.          { Checks if Robot has incurred any new damage. }
  2015.        VAR Curr_Damage : Integer;
  2016.          Answer         : Boolean;
  2017.        BEGIN
  2018.          Curr_Damage := damage;
  2019.          Answer := (Curr_Damage > Last_Damage);
  2020.          Last_Damage := Curr_Damage;
  2021.          IF Answer THEN LastTime := Time;
  2022.          Hurt := Answer;
  2023.        END; {Hurt}
  2024.      
  2025.  
  2026.                                          36
  2027.  
  2028.  
  2029.  
  2030.      PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  2031.    {Improve aim by doing a binary search of the target area;
  2032.     i.e., divide the target area in two equal pieces and redefine
  2033.     the target area to be the piece where the foe is found.
  2034.     If the foe is not found, expand the search area to the
  2035.     maximum arc of plus or minus 10 degrees.}
  2036.        BEGIN
  2037.          Arc := Arc DIV 2; { Divide search area in two. }
  2038.          IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  2039.            THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  2040.            ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle.}
  2041.              THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  2042.              ELSE Arc := 10;
  2043.          { Foe not found in either piece, expand search area to maximum arc. }
  2044.        END; {Aim}
  2045.  
  2046.      BEGIN {SFighter Main}
  2047.        Angle := Angle_To(500, 500);
  2048.        D_Heading := Angle;
  2049.        D_Speed := 50;
  2050.        { Start scanning for foes and moving to center of field. }
  2051.        LowerCloak; { Start off with Cloak DOWN! }
  2052.        LastTime := Time;
  2053.        REPEAT { Until Dead or Winner }
  2054.          Bounce; { If stopped, move off at angle }
  2055.          IF Fuel < 250 THEN LowerCloak;
  2056.          IF NOT Hurt {If not hurt and no damage for 3000 cycles}
  2057.            THEN IF (Time > (LastTime + 3000))
  2058.              THEN BEGIN {Safe to lower cloak and slow down}
  2059.                LowerCloak;
  2060.                D_Speed := 50;
  2061.              END;
  2062.          Delta := 10; { Start with widest scanning arc. }
  2063.          Range := scan(Angle, Delta);
  2064.          WHILE (Range > 40) AND (ObjectScanned = Enemy) DO
  2065.            { Must be far enough away to avoid self-damage. }
  2066.            BEGIN
  2067.              Aim(Angle, Delta); { Improve aim. }
  2068.              Cannon(Angle, Range); { Fire!! }
  2069.              Range := scan(Angle, Delta); { Is foe still in sights? }
  2070.            END;
  2071.          Angle := Angle+20; { Look in adjacent target area. }
  2072.          IF Hurt THEN { Raise cloak and flee! }
  2073.            BEGIN
  2074.              IF Fuel > 250 THEN RaiseCloak;
  2075.              D_Heading := Angle + 180; { Run away from foe! }
  2076.              D_Speed := MaxSpeed;
  2077.              Drive(D_Heading, D_Speed);
  2078.            END;
  2079.        UNTIL Dead OR Winner;
  2080.      END; {SFighter Main}
  2081.  
  2082.                                          37
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088. AN EXAMPLE USING BOMBS AND CLOAKING
  2089.  
  2090. Here is an example of a robot that uses Electronic Bombs and Cloaking, named
  2091. (again aptly) Stealth Bomber.
  2092.  
  2093.      PROCEDURE SBomber;  {Stealth Bomber}
  2094.      {
  2095.       Author: David Malmberg
  2096.  
  2097.       Strategy:  Place bombs in the middle of the field then go to a random
  2098.       corner with cloak raised.  Scan for an enemy near the bomb.  If you
  2099.       spot one, then detonate the bomb and begin again with another bomb.
  2100.  
  2101.       If you see an enemy in missile range (but not near the bomb) blast 'em.
  2102.      }
  2103.  
  2104.    (* Below are the SBomber options as specified in the SBOMBER.CFG file
  2105.  
  2106.    REMEMBER THIS IS A SEPARATE FILE THAT YOU MUST CREATE!!!
  2107.  
  2108.       Radar := 3;
  2109.       Fuel := 0;
  2110.       Engine := 0;
  2111.       Armor := 0;
  2112.       Warheads := 1;
  2113.       Bombs := 1;
  2114.       Shielding := 0;
  2115.       Cloaking := 5;
  2116.       Repairing := 0;
  2117.    *)
  2118.  
  2119.      CONST
  2120.        NW_Corner = 1;
  2121.        NE_Corner = 2;
  2122.        SW_Corner = 3;
  2123.        SE_Corner = 4;
  2124.  
  2125.      VAR { SBomber "Global" variables }
  2126.  
  2127.        Angle, { Scanning angle }
  2128.        Last_Damage, { Robot's Last damage value }
  2129.        D_Speed, { Robot's desired speed }
  2130.        D_Heading, { Robot's desired heading }
  2131.        BombX, BombY, {Bomb's Co-ordinates}
  2132.        BombAngle, BombRange, {Angle and Distance from current corner to Bomb}
  2133.        LastTime, { Last Time cycles were measured }
  2134.        Delta          : Integer; { Scanning arc }
  2135.  
  2136.        CornerX : ARRAY[1..4] OF Integer; {X coordinate of Corners}
  2137.        CornerY : ARRAY[1..4] OF Integer; {Y coordinate of Corners}
  2138.  
  2139.                                          38
  2140.  
  2141.  
  2142.  
  2143.  
  2144.        StartAngle : ARRAY[1..4] OF Integer; {Starting scanning angles}
  2145.  
  2146.        Corner, { Current Corner }
  2147.        Range   { Range/Distance to foe }  : Integer;
  2148.        BombHasExploded : Boolean;
  2149.  
  2150.      PROCEDURE Initialize;
  2151.        BEGIN
  2152.          CornerX[NW_Corner] := 10;
  2153.          CornerY[NW_Corner] := 990;
  2154.          StartAngle[NW_Corner] := 270;
  2155.  
  2156.          CornerX[NE_Corner] := 990;
  2157.          CornerY[NE_Corner] := 990;
  2158.          StartAngle[NE_Corner] := 180;
  2159.  
  2160.          CornerX[SW_Corner] := 10;
  2161.          CornerY[SW_Corner] := 10;
  2162.          StartAngle[SW_Corner] := 0;
  2163.  
  2164.          CornerX[SE_Corner] := 990;
  2165.          CornerY[SE_Corner] := 10;
  2166.          StartAngle[SE_Corner] := 90;
  2167.        END; {Initialize}
  2168.  
  2169.      PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  2170.    {
  2171.     Improve aim by doing a binary search of the target area;
  2172.     i.e., divide the target area in two equal pieces and redefine
  2173.     the target area to be the piece where the foe is found.
  2174.     If the foe is not found, expand the search area to the
  2175.     maximum arc of plus or minus 10 degrees.
  2176.    }
  2177.        BEGIN
  2178.          Arc := Arc DIV 2; { Divide search area in two. }
  2179.          IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  2180.            THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  2181.            ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle.}
  2182.              THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  2183.              ELSE Arc := 10;
  2184.          { Foe not found in either piece, expand search area to maximum arc. }
  2185.        END; {Aim}
  2186.  
  2187.      PROCEDURE BlastThem;
  2188.        BEGIN
  2189.          Angle := 10;
  2190.          REPEAT
  2191.            Delta := 10; { Start with widest scanning arc. }
  2192.            Range := scan(Angle, Delta);
  2193.            WHILE (Range > 40) AND (ObjectScanned = Enemy)
  2194.              AND (Range < MaxMissileRange) DO
  2195.  
  2196.                                          39
  2197.  
  2198.  
  2199.  
  2200.  
  2201.            { Must be far enough away to avoid self-damage. }
  2202.              BEGIN
  2203.                Aim(Angle, Delta); { Improve aim. }
  2204.                Cannon(Angle, Range); { Fire!! }
  2205.                Range := scan(Angle, Delta); { Is foe still in sights? }
  2206.              END;
  2207.            Angle := Angle+20; { Look in adjacent target area. }
  2208.          UNTIL Angle > 360;
  2209.        END;
  2210.  
  2211.  
  2212.      PROCEDURE GOTO(x, y : Integer);
  2213.          { Go to location X,Y on playing field. }
  2214.        VAR Heading    : Integer;
  2215.        BEGIN
  2216.          LowerCloak; {Less need for Cloak while moving}
  2217.  
  2218.          { Find the heading we need to get to the desired spot. }
  2219.          Heading := Angle_To(x, y);
  2220.  
  2221.          { Keep traveling at top speed until we are within 150 meters }
  2222.          WHILE (distance(loc_x, loc_y, x, y) > 150) DO
  2223.            BEGIN
  2224.              Drive(Heading, MaxSpeed);
  2225.              BlastThem;
  2226.            END;
  2227.  
  2228.          { Cut speed, and creep the rest of the way. }
  2229.          WHILE (distance(loc_x, loc_y, x, y) > 20) DO
  2230.            BEGIN
  2231.              Drive(Heading, 20);
  2232.              BlastThem;
  2233.            END;
  2234.  
  2235.          { Stop driving, should coast to a stop. }
  2236.          Drive(Heading, 0); {i.e., Stop}
  2237.          RaiseCloak; {Need Cloak while stopped}
  2238.        END; {GoTo(X,Y)}
  2239.  
  2240.  
  2241.      FUNCTION Hurt  : Boolean;
  2242.          { Checks if Robot has incurred at least 5 points of new damage. }
  2243.        VAR Curr_Damage : Integer;
  2244.          Answer         : Boolean;
  2245.        BEGIN
  2246.          Curr_Damage := damage;
  2247.          Answer := (Curr_Damage > (Last_Damage + 4));
  2248.          Last_Damage := Curr_Damage;
  2249.          IF Answer THEN LastTime := Time;
  2250.          Hurt := Answer;
  2251.        END; {Hurt}
  2252.  
  2253.                                          40
  2254.  
  2255.  
  2256.  
  2257.  
  2258.    PROCEDURE PlaceTheBomb;
  2259.      BEGIN {PlaceTheBomb}
  2260.        BombHasExploded := FALSE;
  2261.        GoTo(500,500);
  2262.        BombX := Loc_X;
  2263.        BombY := Loc_Y;
  2264.        PlaceBomb;
  2265.      END; {PlaceTheBomb}
  2266.  
  2267.  
  2268.    FUNCTION EnemyNearBomb : Boolean;
  2269.    CONST PlusMinus = 200;
  2270.    VAR EnemyDistance : Integer;
  2271.        Answer : Boolean;
  2272.      BEGIN
  2273.        Answer := FALSE;
  2274.        EnemyDistance := Scan(BombAngle, 10);
  2275.        IF ObjectScanned <> Enemy THEN EnemyDistance := 0;
  2276.        IF EnemyDistance > 0
  2277.           THEN Answer := (EnemyDistance > (BombRange - PlusMinus))
  2278.                             AND (EnemyDistance < (BombRange + PlusMinus));
  2279.        EnemyNearBomb := Answer;
  2280.      END; {EnemyNearBomb}
  2281.  
  2282.  
  2283.    PROCEDURE Do_Corner;
  2284.      BEGIN {Do_Corner}
  2285.        Angle := StartAngle[Corner] + 10; {Starting angle for scanning}
  2286.        REPEAT
  2287.          IF EnemyNearBomb
  2288.            THEN BEGIN
  2289.              Detonate;
  2290.              BombHasExploded := TRUE;
  2291.            END;
  2292.          Range := scan(Angle, Delta);
  2293.          WHILE (Range > 40) AND (Range < MaxRadarRange) DO
  2294.            { Must be far enough away to avoid self-damage. }
  2295.            BEGIN
  2296.              IF ObjectScanned = Enemy THEN cannon(Angle, Range); { Fire!! }
  2297.              Range := scan(Angle, Delta); { Is foe still in sights? }
  2298.            END;
  2299.          Angle := Angle + 20; { Look in adjacent target area. }
  2300.          IF (Angle > (StartAngle[Corner] + 90))
  2301.            THEN Angle := StartAngle[Corner] + 10;
  2302.        UNTIL BombHasExploded;
  2303.      END; {Do_Corner}
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.                                          41
  2311.  
  2312.  
  2313.  
  2314.      BEGIN {SBomber Main}
  2315.        RaiseCloak;
  2316.        Initialize;
  2317.        Delta := 10; { The widest possible scanning arc. }
  2318.        LastTime := Time;
  2319.        REPEAT { Until Dead or Winner }
  2320.          PlaceTheBomb;
  2321.          Corner := Random(3) + 1; {Pick a corner}
  2322.          GoTo(CornerX[Corner], CornerY[Corner]);
  2323.          { Move to selected corner. }
  2324.          BombAngle := Angle_To(BombX, BombY);
  2325.          BombRange := Distance(Loc_X, Loc_Y, BombX, BombY);
  2326.          { Determine relative location from corner to Bomb }
  2327.          Do_Corner;
  2328.          IF Hurt THEN
  2329.             IF Fuel > 250
  2330.               THEN RaiseCloak { Raise cloak and flee! }
  2331.               ELSE LowerCloak;
  2332.        UNTIL Dead OR Winner;
  2333.      END; {SBomber Main}
  2334.  
  2335.  
  2336. ROBOT TEAMS
  2337.  
  2338. One of the most intriguing suggestions that I received from previous users of
  2339. P-ROBOTS was the idea of allowing two robots to act as members of the same team
  2340. and to communicate with each other during the course of the battle.  This
  2341. option has been included in the current version of P-ROBOTS.
  2342.  
  2343. NOTE: For consistency and better understanding, if your robot is a member of a
  2344. two robot team, the other team member is referred to as your robot's "Ally".
  2345. Similarly, within your Ally's robot program, your robot would be referred to as
  2346. its Ally.
  2347.  
  2348. Robot teams may use the following special built-in P-ROBOTS functions:
  2349.  
  2350.           AllyLoc_X -- returns the current X coordinate of your Ally
  2351.  
  2352.           AllyLoc_Y -- returns the current Y coordinate of your Ally
  2353.  
  2354.           AllyDamage -- returns your Ally's current Damage level
  2355.  
  2356.           AllySpeed -- returns your Ally's current Speed
  2357.  
  2358.           AllyHeading -- returns your Ally's current Heading
  2359.  
  2360.           AllyMeters -- returns your Ally's current Meters
  2361.  
  2362.           AllyFuel -- returns your Ally's current Fuel level
  2363.  
  2364.  
  2365.  
  2366.                                          42
  2367.  
  2368.  
  2369.  
  2370.           AllyShieldRaised -- returns TRUE or FALSE depending upon whether your
  2371.           Ally's shield is raised or not
  2372.  
  2373.           AllyDead -- returns TRUE or FALSE depending upon whether your Ally is
  2374.           Dead or not
  2375.  
  2376.           AllyAlive -- returns TRUE or FALSE depending upon whether your Ally
  2377.           is Alive or not
  2378.  
  2379. In addition to using these built-in functions to learn about your Ally's
  2380. status, it is also possible for robots to exchange information by accessing the
  2381. "global" array COMM[1..20].  All robots may access this array and both retrieve
  2382. and store values to any of its 20 elements.  Be warned however, that stuffing
  2383. "garbage" into COMM's elements to sabotage the communication between opposing
  2384. team members is NOT considered to be fair play!!
  2385.  
  2386. One other piece of information is necessary in order for two robots to work
  2387. together effectively as a team -- there must be some way to tell if a robot is
  2388. friend or foe.  The way this is done is to define a special function called
  2389. "ObjectScanned" which is reset whenever your robot scans the battlefield.  The
  2390. value returned by ObjectScanned will be one of four specially defined
  2391. values/constants:  Nothing, Ally, Enemy or Obstruction.  For example, to make
  2392. sure that you only fire your cannon at enemy robots when you are part of a
  2393. team, you might want to use statements like the following:
  2394.  
  2395.              Dist := Scan(Angle, Delta);
  2396.              IF ObjectScanned = Enemy THEN Cannon(Angle, Dist); {Blast 'Em!!}
  2397.  
  2398. To tell the P-ROBOTS compiler that you have an Ally and are part of a team, you
  2399. need to include a statement within your robot's program that looks like:
  2400.  
  2401.              TeamAlly = "Blaster";
  2402.  
  2403. This statement tells the P-ROBOTS compiler that your Ally is named "Blaster".
  2404. To work correctly, the robot "Blaster" must have a similar statement within its
  2405. program that identifies your robot's name as its Ally.
  2406.  
  2407.  
  2408. AN EXAMPLE OF A ROBOT TEAM
  2409.  
  2410. Here is an example of one member of a robot team.  Notice, that this robot and
  2411. its Ally (named "TagTeam2") communicate by passing information through COMM[10]
  2412. and COMM[11].
  2413.  
  2414.  
  2415.      PROCEDURE TagTeam1;
  2416.  
  2417.      TeamAlly = "TagTeam2";
  2418.  
  2419.  
  2420.  
  2421.  
  2422.                                          43
  2423.  
  2424.  
  2425.  
  2426.  
  2427.   {
  2428.    Author: David Malmberg
  2429.  
  2430.    Strategy: Go to a random corner, raise shield, and blast away at any
  2431.              robot in range.  Improve aim after every successful scan. If the
  2432.              robot scans 20 times unsuccessfully, move to another random
  2433.              corner.  Lower shields when moving; raise them when stopped.
  2434.  
  2435.              This robot can act individually or as part of a team with another
  2436.              robot that follows an identical strategy, i.e., TagTeam2.  If
  2437.              operating as a team, the two robots communicate their corners
  2438.              to each other by setting COMM[10] to TagTeam1's corner and
  2439.              COMM[11] to TagTeam2's corner.  They try to always pick different
  2440.              random corners.
  2441.  
  2442.              WARNING: This Robot has not been designed to deal with
  2443.              Obstructions effectively.
  2444.   }
  2445.  
  2446.      CONST
  2447.        NW_Corner = 1;
  2448.        NE_Corner = 2;
  2449.        SW_Corner = 3;
  2450.        SE_Corner = 4;
  2451.  
  2452.      VAR { TagTeam1 "Global" variables }
  2453.  
  2454.        CornerX : ARRAY[1..4] OF Integer; {X coordinate of Corners}
  2455.        CornerY : ARRAY[1..4] OF Integer; {Y coordinate of Corners}
  2456.        StartAngle : ARRAY[1..4] OF Integer; {Starting scanning angles}
  2457.  
  2458.        Corner, { Current Corner }
  2459.        Times,  { Number of times robot as scanned without success for enemy }
  2460.        Angle,  { Scanning angle }
  2461.        Delta,  { Scanning angle width }
  2462.        Range   { Range/Distance to foe }  : Integer;
  2463.  
  2464.  
  2465.      PROCEDURE Initialize;
  2466.        BEGIN
  2467.          CornerX[NW_Corner] := 10;
  2468.          CornerY[NW_Corner] := 990;
  2469.          StartAngle[NW_Corner] := 270;
  2470.  
  2471.          CornerX[NE_Corner] := 990;
  2472.          CornerY[NE_Corner] := 990;
  2473.          StartAngle[NE_Corner] := 180;
  2474.  
  2475.          CornerX[SW_Corner] := 10;
  2476.          CornerY[SW_Corner] := 10;
  2477.          StartAngle[SW_Corner] := 0;
  2478.  
  2479.                                          44
  2480.  
  2481.  
  2482.  
  2483.          CornerX[SE_Corner] := 990;
  2484.          CornerY[SE_Corner] := 10;
  2485.          StartAngle[SE_Corner] := 90;
  2486.        END; {Initialize}
  2487.  
  2488.  
  2489.      PROCEDURE GOTO(x, y : Integer);
  2490.          { Go to location X,Y on playing field. }
  2491.        VAR Heading    : Integer;
  2492.        BEGIN
  2493.          LowerShield; {Moving target is hard to hit - so lower shield}
  2494.  
  2495.          { Find the heading we need to get to the desired spot. }
  2496.          Heading := Angle_To(x, y);
  2497.  
  2498.          { Keep traveling at top speed until we are within 150 meters }
  2499.          WHILE (distance(loc_x,loc_y,x,y) > 150) DO Drive(Heading, MaxSpeed);
  2500.  
  2501.          { Cut speed, and creep the rest of the way. }
  2502.          WHILE (distance(loc_x, loc_y, x, y) > 20) DO Drive(Heading, 20);
  2503.  
  2504.          { Stop driving, should coast to a stop. }
  2505.          Drive(Heading, 0); {i.e., Stop}
  2506.  
  2507.          RaiseShield; {Still target is easy to hit - so raise shield}
  2508.        END; {GoTo(X,Y)}
  2509.  
  2510.  
  2511.      PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  2512.    {
  2513.     Improve aim by doing a binary search of the target area;
  2514.      i.e., divide the target area in two equal pieces and redefine
  2515.     the target area to be the piece where the foe is found.
  2516.     If the foe is not found, expand the search area to the
  2517.     maximum arc of plus or minus 10 degrees.
  2518.    }
  2519.  
  2520.        BEGIN
  2521.          Times := 0; { Found enemy -- so set unsuccessful scan count to zero )
  2522.          Arc := Arc DIV 2; { Divide search area in two. }
  2523.          IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  2524.          THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  2525.          ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle. }
  2526.          THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  2527.          ELSE Arc := 10;
  2528.          { Foe not found in either piece, expand search area to maximum arc. }
  2529.        END; {Aim}
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.                                          45
  2536.  
  2537.  
  2538.  
  2539.  
  2540.    PROCEDURE Do_Corner;
  2541.      BEGIN {Do_Corner}
  2542.        Times := 0; {Count of unsuccessful scans}
  2543.        Angle := StartAngle[Corner] + 10; {Starting angle for scanning}
  2544.        REPEAT
  2545.          Delta := 10; { Start with widest scanning arc. }
  2546.          Range := scan(Angle, Delta);
  2547.          WHILE (Range > 40) AND (Range < MaxMissileRange) DO
  2548.            { Must be far enough away to avoid self-damage. }
  2549.            BEGIN
  2550.              Aim(Angle, Delta); { Improve aim. }
  2551.              IF ObjectScanned = Enemy THEN cannon(Angle, Range); { Fire!! }
  2552.              Range := scan(Angle, Delta); { Is foe still in sights? }
  2553.            END;
  2554.          Angle := Angle + 20; { Look in adjacent target area. }
  2555.          IF (Angle > (StartAngle[Corner] + 90))
  2556.            THEN Angle := StartAngle[Corner] + 10;
  2557.          Times := Times + 1;
  2558.        UNTIL Times > 20; { Leave after 20 unsuccessful scans }
  2559.      END; {Do_Corner}
  2560.  
  2561.  
  2562.      BEGIN {TagTeam1 Main}
  2563.        Initialize;
  2564.        COMM[11] := 0; {Set Ally's corner (if any) to zero}
  2565.        COMM[10] := 0; {Communicate My corner to Ally}
  2566.        REPEAT
  2567.          REPEAT
  2568.            Corner := Random(3) + 1; {Pick a corner}
  2569.          UNTIL Corner <> COMM[11]; {Need different corner than Ally}
  2570.          COMM[10] := Corner; {Communicate My corner to Ally (if any)}
  2571.          GoTo(CornerX[Corner], CornerY[Corner]);
  2572.          { Move to selected corner. }
  2573.          Do_Corner;
  2574.        UNTIL Dead OR Winner;
  2575.  
  2576.      END; {TagTeam1 Main}
  2577.  
  2578.  
  2579. OBSTRUCTIONS ON THE BATTLEFIELD
  2580.  
  2581. Another new feature included in version 4.0 of P-ROBOTS is the possibility of
  2582. randomly placed Obstructions on the battlefield.  This option is selected by
  2583. using the "/ON" command line parameter, where N can be 1, 2 up to 5 --
  2584. corresponding to 1, 2 up to 5 Obstructions.  Each Obstruction will be a
  2585. randomly sized and placed rectangle.
  2586.  
  2587. Be warned however, that using Obstructions in your battles will slow down the
  2588. speed of the battle.  The logic required for P-ROBOTS to deal with Obstructions
  2589. is fairly extensive and very computationally intense.  So the more Obstructions
  2590. your battle has, the slower it will run.
  2591.  
  2592.                                          46
  2593.  
  2594.  
  2595.  
  2596.  
  2597. If your robot runs into one of these Obstructions, it will be stopped cold and
  2598. incur Damage (if its Shield is down) -- just as if it ran into one of the
  2599. battlefield walls.  A scanner will not be able to see beyond an Obstruction;
  2600. nor will it be possible to shoot a missile past an Obstruction.  Therefore, it
  2601. will be possible for a robot to "hide" from enemy scanners and missile by
  2602. "hugging" the walls of an Obstruction.  More often than not, a scanner will
  2603. only "see" the Obstruction and not the robot.
  2604.  
  2605. Obstructions add a whole new dimension to the possible problems and
  2606. opportunities that a robot may face!!
  2607.  
  2608. Your robot will be able to determine where the Obstructions are by scanning and
  2609. then checking the value returned by the function "ObjectScanned".  For example,
  2610. you might use the following Boolean function to determine if the direction your
  2611. robot is traveling (denoted below by the variable "Heading") is clear of
  2612. Obstructions for the next 100 meters:
  2613.  
  2614.              FUNCTION ClearAhead : Boolean;
  2615.              BEGIN
  2616.                ClearAhead := (Scan(Heading,2) > 100)
  2617.                               OR (ObjectScanned <> Obstruction);
  2618.              END; {ClearAhead}
  2619.  
  2620.  
  2621. AN EXAMPLE DEALING WITH OBSTRUCTIONS
  2622.  
  2623. Below is our old friend, HOTSHOT, adapted to deal with the problem of
  2624. Obstructions by using logic to move around them.  Notice, that we can no longer
  2625. use the same routine we have been using to go to a point X, Y on the
  2626. battlefield -- because that point might be inside an Obstruction or in a direct
  2627. line beyond an obstruction -- in which case our robot would commit suicide by
  2628. repeatedly "banging its head" against the wall of the Obstruction.  To see how
  2629. this problem is overcome, see the Procedure "Ramble" in the listing.
  2630.  
  2631.  
  2632.      PROCEDURE HotShot3;
  2633.      {
  2634.       Author: David Malmberg
  2635.  
  2636.       Strategy:  Stay in one place.  Find a foe.  Take a shot.
  2637.       Keep improving aim and shooting until foe is lost from sights.
  2638.       Then move sights (scanning) to adjacent target area.
  2639.       If the Robot scans a complete circle (360 degrees) without
  2640.       finding a foe in shooting range, move to another spot on the
  2641.       field.  (This will avoid "stand-offs" where opponents stay
  2642.       just out of range of one another.)  RaiseShield when standing
  2643.       still and lower them when moving.
  2644.  
  2645.       When damage gets to 70 (or more) or fuel (if using fuel) gets
  2646.       below 200 adopt an "End-Game" strategy of moving to the lower
  2647.       left corner, lower shield, and continue to scan and shoot in
  2648.  
  2649.                                          47
  2650.  
  2651.  
  2652.  
  2653.  
  2654.       the corner's 90 degree range.
  2655.  
  2656.       This Robot should be VERY effective against foes which
  2657.       are stopped or are moving slowly.  It will be less effective
  2658.       against Robots traveling at high speeds.
  2659.  
  2660.       This Robot has been designed to utilize Fuel (if it is available)
  2661.       to power its Shield.  It has also been designed to deal with
  2662.       Obstructions (if any) by moving around them.
  2663.      }
  2664.  
  2665.  
  2666.      VAR { HotShot3 "Global" variables }
  2667.  
  2668.        Angle, { Scanning angle }
  2669.        Last_Damage, { Robot's Last damage value }
  2670.        Range, { Range/Distance to foe }
  2671.        Sweep, { "Sweep count" -- when = 18, Robot has scanned 360 degrees }
  2672.        Delta          : Integer; { Scanning arc }
  2673.  
  2674.  
  2675.      PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
  2676.    {
  2677.     Improve aim by doing a binary search of the target area;
  2678.     i.e., divide the target area in two equal pieces and redefine
  2679.     the target area to be the piece where the foe is found.
  2680.     If the foe is not found, expand the search area to the
  2681.     maximum arc of plus or minus 10 degrees.
  2682.    }
  2683.        BEGIN
  2684.          Arc := Arc DIV 2; { Divide search area in two. }
  2685.          IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
  2686.            THEN Ang := Ang-Arc { If foe found, redefine target angle. }
  2687.            ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle.}
  2688.              THEN Ang := Ang+Arc { If foe found, redefine target angle. }
  2689.              ELSE Arc := 10;
  2690.          { Foe not found in either piece, expand search area to maximum arc. }
  2691.        END; {Aim}
  2692.  
  2693.  
  2694.      PROCEDURE BlastThem;
  2695.        BEGIN
  2696.          Angle := 10;
  2697.          REPEAT
  2698.            Delta := 10; { Start with widest scanning arc. }
  2699.            Range := scan(Angle, Delta);
  2700.            WHILE (Range > 40) AND (ObjectScanned = Enemy)
  2701.              AND (Range < MaxMissileRange) DO
  2702.            { Must be far enough away to avoid self-damage. }
  2703.              BEGIN
  2704.                Aim(Angle, Delta); { Improve aim. }
  2705.  
  2706.                                          48
  2707.  
  2708.  
  2709.  
  2710.                Cannon(Angle, Range); { Fire!! }
  2711.                Range := scan(Angle, Delta); { Is foe still in sights? }
  2712.              END;
  2713.            Angle := Angle+20; { Look in adjacent target area. }
  2714.          UNTIL Angle > 360;
  2715.        END;
  2716.  
  2717.  
  2718.      PROCEDURE GOTO(x, y : Integer);
  2719.          { Go to location X,Y on playing field. }
  2720.        VAR Heading    : Integer;
  2721.        BEGIN
  2722.          { WARNING:  If the point X,Y is inside an Obstruction then }
  2723.          { executing this routine will cause the Robot to commit }
  2724.          { suicide by repeatedly running into the wall of the Obstruction. }
  2725.          { First, find the heading we need to get to the desired spot. }
  2726.          Heading := Angle_To(x, y);
  2727.  
  2728.          { Keep traveling at top speed until we are within 150 meters }
  2729.          WHILE (distance(loc_x, loc_y, x, y) > 150) DO
  2730.            BEGIN
  2731.              Drive(Heading, MaxSpeed);
  2732.              BlastThem;
  2733.            END;
  2734.  
  2735.          { Cut speed, and creep the rest of the way. }
  2736.          WHILE (distance(loc_x, loc_y, x, y) > 20) DO
  2737.            BEGIN
  2738.              Drive(Heading, 20);
  2739.              BlastThem;
  2740.            END;
  2741.  
  2742.          { Stop driving, should coast to a stop. }
  2743.          Drive(Heading, 0); {i.e., Stop}
  2744.        END; {GoTo(X,Y)}
  2745.  
  2746.  
  2747.      PROCEDURE Ramble(X, Y : Integer);
  2748.          { Move to X, Y (if possible) on the playing field }
  2749.          { by avoiding Obstructions - if any.              }
  2750.        VAR Heading, Tries, Dist : Integer;
  2751.        BEGIN
  2752.          Tries := 0;
  2753.          Heading := Angle_To(X, Y);
  2754.          Drive(Heading, 100); {Start off at maximum speed}
  2755.          Dist := Scan(Heading, 5);
  2756.          REPEAT
  2757.            IF ObjectScanned = Obstruction
  2758.              THEN BEGIN
  2759.                REPEAT
  2760.                  Heading := Heading + 10;
  2761.  
  2762.                                          49
  2763.  
  2764.  
  2765.  
  2766.                  Dist := Scan(Heading, 5);
  2767.                UNTIL ObjectScanned <> Obstruction;
  2768.                Drive(Heading, 50); {Minimum speed to turn freely}
  2769.              END;
  2770.            Heading := Angle_To(X, Y);
  2771.            Dist := Scan(Heading, 5);
  2772.            Tries := Tries + 1;
  2773.          UNTIL (ObjectScanned <> Obstruction) OR (Tries > 20);
  2774.          IF (ObjectScanned <> Obstruction) THEN GOTO(X,Y);
  2775.        END; {Ramble}
  2776.  
  2777.  
  2778.      PROCEDURE Move;
  2779.          { Move to a random spot on the playing field. }
  2780.        VAR x, y       : Integer;
  2781.        BEGIN
  2782.          Sweep := 0; { Reset Sweep counter to zero. }
  2783.          x := Random(900)+50;
  2784.          y := Random(900)+50;
  2785.          Ramble(x, y);
  2786.        END; {Move}
  2787.  
  2788.  
  2789.      PROCEDURE End_Game;
  2790.      BEGIN {End_Game}
  2791.        Ramble(0,0); {Lower Left Corner}
  2792.        Angle := 10; {Sweep arc from 0 to 90 degrees only}
  2793.        REPEAT
  2794.          Delta := 10; { Start with widest scanning arc. }
  2795.          Range := scan(Angle, Delta);
  2796.          WHILE (Range > 40) AND (Range < 700) AND (ObjectScanned = Enemy)
  2797.            DO { Must be far enough away to avoid self-damage. }
  2798.            BEGIN
  2799.              Aim(Angle, Delta); { Improve aim. }
  2800.              IF ObjectScanned = Enemy
  2801.                THEN cannon(Angle, Range); { Fire!! }
  2802.              Range := scan(Angle, Delta); { Is foe still in sights? }
  2803.            END;
  2804.          Angle := Angle+20; { Look in adjacent target area. }
  2805.          IF Angle > 90 THEN Angle := 10;
  2806.        UNTIL Dead OR Winner;
  2807.      END; {End_Game}
  2808.  
  2809.  
  2810.      BEGIN {HotShot3 Main}
  2811.        RaiseShield;
  2812.        Angle := 0;
  2813.        Ramble(500, 500); { Move to center of field -- if possible. }
  2814.        Sweep := 0; { Initialize Sweep counter to zero. }
  2815.        REPEAT { Until Dead or Winner }
  2816.          Delta := 10; { Start with widest scanning arc. }
  2817.  
  2818.                                          50
  2819.  
  2820.  
  2821.  
  2822.          Range := scan(Angle, Delta);
  2823.          WHILE (Range > 40) AND (Range < MaxMissileRange)
  2824.            AND (ObjectScanned = Enemy)
  2825.            DO { Must be far enough away to avoid self-damage. }
  2826.            BEGIN
  2827.              Sweep := 0; { Found foe, so reset Sweep to zero }
  2828.              Aim(Angle, Delta); { Improve aim. }
  2829.              IF ObjectScanned = Enemy
  2830.                THEN cannon(Angle, Range); { Fire!! }
  2831.              Range := scan(Angle, Delta); { Is foe still in sights? }
  2832.            END;
  2833.          Angle := Angle+20; { Look in adjacent target area. }
  2834.          Sweep := Sweep+1;
  2835.          IF Sweep = 18 THEN
  2836.            BEGIN { If robot has scanned a full circle, move elsewhere. }
  2837.              LowerShield; {Don't need shield (as much) when moving}
  2838.              Move;
  2839.            END;
  2840.  
  2841.          RaiseShield; {Standing still so use shield}
  2842.  
  2843.          {"End" game strategy}
  2844.          IF (Fuel < 200) OR (Damage > 70) THEN End_Game;
  2845.  
  2846.        UNTIL Dead OR Winner;
  2847.      END; {HotShot3 Main}
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.                                          51
  2875.  
  2876.  
  2877.  
  2878. APPENDIX I: COMPILER ERRORS
  2879.  
  2880. The PASCAL compiler in P-ROBOTS will report any syntax or logic errors that it
  2881. encounters during the compilation process.  The program will then terminate
  2882. without playing the game.  A listing of the robot(s) source code with the
  2883. errors marked in the source will then be found in a file named LISTING.TXT on
  2884. the disk/directory where P-ROBOTS is being run.  Because P-ROBOTS is going to
  2885. write to the disk, you must NOT have a "write-protect" tab on the disk or you
  2886. will get a fatal error whenever you try to run the program.  This file should
  2887. be printed out and studied and your corrections made to your robot source
  2888. files.  Do NOT make your corrections on the LISTING.TXT file!  The compiler
  2889. only compiles robot files (i.e., files with a ".PR" extension).
  2890.  
  2891. If your robot(s) source code did not have any errors (that the compiler could
  2892. detect) there will not be a LISTING.TXT file created and the P-ROBOTS program
  2893. will execute normally and the contest between the various robots will be
  2894. played.
  2895.  
  2896. The compiler will report the following errors by number:
  2897.  
  2898.              0.   UNDEFINED IDENTIFIER
  2899.              1.   MULTIPLE DEFINITION OF THIS IDENTIFIER
  2900.              2.   EXPECTED AN IDENTIFIER
  2901.              3.   PROGRAM MUST BEGIN WITH "PROGRAM"
  2902.              4.   EXPECTED CLOSING PARENTHESIS ")"
  2903.              5.   EXPECTED A COLON ":"
  2904.              6.   INCORRECTLY USED SYMBOL
  2905.              7.   EXPECTED IDENTIFIER OR THE SYMBOL "VAR"
  2906.              8.   EXPECTED THE SYMBOL "OF"
  2907.              9.   EXPECTED AN OPENING PARENTHESIS "("
  2908.              10.  EXPECTED IDENTIFIER, "ARRAY" OR "RECORD"
  2909.              11.  EXPECTED AN OPENING BRACKET "["
  2910.              12.  EXPECTED A CLOSING BRACKET "]"
  2911.              13.  EXPECTED ".." WITHOUT INTERVENING BLANKS
  2912.              14.  EXPECTED A SEMICOLON ";"
  2913.              15.  BAD RESULT TYPE FOR A FUNCTION
  2914.              16.  EXPECTED AN EQUAL SIGN "="
  2915.              17.  EXPECTED BOOLEAN EXPRESSION
  2916.              18.  CONTROL VARIABLE OF THE WRONG TYPE
  2917.              19.  MUST BE MATCHING TYPES
  2918.              20.  "OUTPUT" IS REQUIRED IN PROGRAM HEADING
  2919.              21.  THE NUMBER IS TOO LARGE
  2920.              22.  EXPECT PERIOD ".", CHECK BEGIN-END PAIRS
  2921.              23.  BAD TYPE FOR A CASE STATEMENT
  2922.              24.  ILLEGAL CHARACTER
  2923.              25.  ILLEGAL CONSTANT OR CONSTANT IDENTIFIER
  2924.              26.  ILLEGAL ARRAY SUBSCRIPT (CHECK TYPE)
  2925.              27.  ILLEGAL BOUNDS FOR AN ARRAY INDEX
  2926.              28.  INDEXED VARIABLE MUST BE AN ARRAY
  2927.              29.  EXPECTED A TYPE IDENTIFIER
  2928.              30.  UNDEFINED TYPE
  2929.  
  2930.                                          52
  2931.  
  2932.  
  2933.  
  2934.              31.  VAR WITH FIELD SELECTOR MUST BE RECORD
  2935.              32.  EXPECTED TYPE "BOOLEAN"
  2936.              33.  ILLEGAL TYPE FOR ARITHMETIC EXPRESSION
  2937.              34.  EXPECTED INTEGER FOR "DIV" OR "MOD"
  2938.              35.  INCOMPATIBLE TYPES FOR COMPARISON
  2939.              36.  PARAMETER TYPES DO NOT MATCH
  2940.              37.  EXPECTED A VARIABLE
  2941.              38.  A STRING MUST HAVE ONE OR MORE CHAR
  2942.              39.  NUMBER OF PARAMETERS DO NOT MATCH
  2943.              40.  INVALID "TeamAlly" NAME FORMAT
  2944.              41.  ILLEGAL PARAMETERS TO "WRITE"
  2945.              42.  PARAMETER MUST BE OF TYPE "REAL"
  2946.              43.  PARAMETER MUST BE OF TYPE "INTEGER"
  2947.              44.  EXPECTED VARIABLE OR CONSTANT
  2948.              45.  EXPECTED A VARIABLE OR PROCEDURE
  2949.              46.  TYPES MUST MATCH IN AN ASSIGNMENT
  2950.              47.  CASE LABEL NOT SAME TYPE AS CASE CLAUSE
  2951.              48.  ARGUMENT TO STD. FUNCTION OF WRONG TYPE
  2952.              49.  THE PROGRAM REQUIRES TOO MUCH STORAGE
  2953.              50.  ILLEGAL SYMBOL FOR A CONSTANT
  2954.              51.  EXPECTED BECOMES ":="
  2955.              52.  EXPECTED "THEN"
  2956.              53.  EXPECTED "UNTIL"
  2957.              54.  EXPECTED "DO"
  2958.              55.  EXPECTED "TO" OR "DOWNTO"
  2959.              56.  EXPECTED "BEGIN"
  2960.              57.  EXPECTED "END"
  2961.              58.  EXPECTED ID, CONST, "NOT" OR "("
  2962.              59.  "INPUT"  IS REQUIRED IN PROGRAM HEADING
  2963.              60.  ILLEGAL (CONTROL) CHARACTER PRESENT IN SOURCE
  2964.  
  2965. Not all of the above error messages will be used in P-ROBOTS because the
  2966. compiler has been modified to not allow certain kinds of PASCAL statements.
  2967. For example, since P-ROBOTS does not allow READs and WRITEs you will not get
  2968. the above error messages that are normally associated with READ and WRITE.  If
  2969. you attempt to READ or WRITE in a P-ROBOTS program you will get an error
  2970. message number zero -- "UNDEFINED IDENTIFIER".
  2971.  
  2972. Remember not to use PASCAL "reserved" words as variable or procedure names.
  2973. Variables named BEGIN, ARRAY, DO, FOR, etc. will cause strange error messages.
  2974.  
  2975. On very rare occasions, you may get another kind of compiler error if the
  2976. robots' source code you are currently trying to compile is so "verbose" that it
  2977. causes  one of the compiler's tables to overflow.  When this happens, you will
  2978. be given an error message which identifies which specific table has been over
  2979. flowed.  The limits for these tables are as follows:
  2980.  
  2981.  
  2982.  
  2983.  
  2984.  
  2985.  
  2986.                                          53
  2987.  
  2988.  
  2989.  
  2990.  
  2991.         400    Identifiers (Variables, Constants, Procedure and Function names)
  2992.          40    Procedures or Functions
  2993.          40    Real Constants 
  2994.          60    Arrays
  2995.           7    Levels of "Nested" Procedures or Functions
  2996.        5000    "Compiled" P-Code instructions
  2997.  
  2998. These limits apply to the total number of identifiers (etc.) for all of the
  2999. robots you have in the current contest.
  3000.  
  3001.  
  3002.  
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.  
  3009.  
  3010.  
  3011.  
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.  
  3038.  
  3039.  
  3040.  
  3041.  
  3042.  
  3043.                                          54
  3044.  
  3045.  
  3046.  
  3047.  
  3048. APPENDIX II: RUN-TIME ERRORS
  3049.  
  3050.  
  3051. When using P-ROBOTS it is possible to get two kinds of run-time errors.  The
  3052. first kind (and probably the most frequent) is an error that occurs within the
  3053. P-ROBOTS program itself when you try to do something that the P-Code compiler
  3054. within P-ROBOTS objects to -- like trying to divide by zero.  The second kind
  3055. of run-time error is generated by Turbo Pascal.  These errors are due to
  3056. situations like not having enough memory or disk space to run the P-ROBOTS
  3057. program.  Each of these types of errors will be discussed below.
  3058.  
  3059.  
  3060. P-ROBOTS RUN-TIME ERRORS
  3061.  
  3062. It is possible that the P-ROBOTS compiler will detect an error during the game.
  3063. These are known as "run-time" errors and they will cause the game to terminate
  3064. and an error message to be printed.  The following kinds of run-time errors
  3065. will be caught and reported:
  3066.  
  3067.      1.   DIVIDE BY 0
  3068.  
  3069.           For example, if Delta_X had a value of zero in the following program
  3070.           statement, you would get a "DIVIDE BY 0" error:
  3071.  
  3072.                Target_Angle := ArcTan(Delta_Y/Delta_X);
  3073.  
  3074.      2.   UNDEFINED CASE
  3075.  
  3076.           In the example below, if the variable X had a value of 12 below you
  3077.           would get an "UNDEFINED CASE" error:
  3078.  
  3079.                CASE X OF
  3080.                   1 : .....
  3081.                   2 : .....
  3082.                   3 : .....
  3083.                       .
  3084.                       .
  3085.                  10 : .....
  3086.                END; {CASE}
  3087.  
  3088.      3.   INVALID INDEX
  3089.  
  3090.           An example of an invalid index would be a reference to the tenth
  3091.           element of an array (i.e., Spot[10]) that was only defined to have
  3092.           the elements one through five (i.e., Spot : ARRAY[1..5] OF INTEGER;)
  3093.           would cause an "INVALID INDEX" error.
  3094.  
  3095.  
  3096.  
  3097.  
  3098.  
  3099.  
  3100.                                          55
  3101.  
  3102.  
  3103.  
  3104.  
  3105.      4.   STORAGE OVERFLOW
  3106.  
  3107.           You would only get a "STORAGE OVERFLOW" error if one (or more) of
  3108.           your robots in the current contest was making too many recursive
  3109.           calls to the same procedure or function or was evaluating a large
  3110.           number of very, very complex assignment statements so that the
  3111.           robot's "stack" space was exceeded.  If you get this error, check
  3112.           your overall robot logic -- there must be a better way!
  3113.  
  3114.  
  3115. TURBO PASCAL RUN-TIME ERRORS
  3116.  
  3117. Here are the run-time errors that might be generated by Turbo Pascal:
  3118.  
  3119.      101  "Disk Write Error" -- You would get this error (probably) because you
  3120.           do not have enough room on your disk to contain the complete
  3121.           LISTING.TXT file (i.e., the error listing) or you do not have enough
  3122.           room on your disk (at least 512K) for the "swap" file if you are
  3123.           using the IDE.
  3124.  
  3125.      203  "Heap Overflow Error" -- You probably don't have enough free memory.
  3126.           P-ROBOTS needs at least 384K of free memory (i.e, after counting all
  3127.           of the memory residents programs).
  3128.  
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.                                          56
  3158.  
  3159.  
  3160.  
  3161. APPENDIX III: COMMON PROBLEMS
  3162.  
  3163.  
  3164. If P-ROBOTS is not doing what you think it should do, check for these common
  3165. problems:
  3166.  
  3167.      1.   Leaving a "write-protect" tab on the game disk will cause a fatal
  3168.           crash.  There needs to be a way for the LISTING.TXT file (i.e., the
  3169.           error listing) to be written on the disk.  Also, make sure you have
  3170.           enough disk space to contain the LISTING.TXT file.  20K of available
  3171.           disk space should be plenty of room.
  3172.  
  3173.      2.   Your robot must be a self-contained PASCAL PROCEDURE with the same
  3174.           name as the file (but without the .PR extension).
  3175.  
  3176.      3.   Your robot must have an "infinite" loop in the "main" routine.
  3177.  
  3178.      4.   Don't commit robot "suicide" by firing your cannon for a range of
  3179.           zero.  For example:
  3180.  
  3181.                   Drive(Angle,100);
  3182.                   WHILE (Loc_X < 999) DO Cannon(Angle,Scan(Angle,10));
  3183.  
  3184.           will cause your robot to commit suicide.
  3185.  
  3186.      5.   You need to have at least 384K of free memory in order to run P-
  3187.           ROBOTS.  If you don't have enough memory, you will get a Turbo Pascal
  3188.           run-time error number 203.
  3189.  
  3190.      6.   Are you playing a game with Obstacles with robots that have not been
  3191.           designed to properly deal with Obstacles?  Do your robots "bang their
  3192.           heads" against the Obstacles, or waste all of their missiles blasting
  3193.           away at the Obstacles?  Reprogram your robots, or stop playing with
  3194.           the Obstacles option!
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.  
  3211.  
  3212.  
  3213.                                          57
  3214.  
  3215.  
  3216.  
  3217.  
  3218. APPENDIX IV: THE P-ROBOTS PASCAL LANGUAGE
  3219.  
  3220.  
  3221. "NORMAL" PASCAL
  3222.  
  3223. P-ROBOTS allows a relatively rich subset of the "normal" PASCAL language.
  3224.  
  3225. Predefined types include REAL, INTEGER, and BOOLEAN.  CONSTants, RECORDs and
  3226. user-defined TYPEs are allowed.  ARRAYs are allowed.
  3227.  
  3228. Comments may be added to a program by enclosing text with braces { }, or (* *)
  3229. pairs.
  3230.  
  3231. Variable and other identifier names may have up to 10 significant characters.
  3232.  
  3233. Arithmetic operators include: +, -, *, /, DIV and MOD.  Comparison operators
  3234. include: >, <, <>, =, <=, and >=.  Boolean operators include: AND, OR, and NOT.
  3235.  
  3236. Control statements/structures include:  CASE, FOR-TO-DO, FOR-DOWNTO-DO,
  3237. IF-THEN, IF-THEN-ELSE, REPEAT-UNTIL, and WHILE-DO.
  3238.  
  3239. Functions and Procedures may or may not have parameters.  If a Function or a
  3240. Procedure has parameters, these parameters may be passed by value or by
  3241. reference (i.e., a VAR parameter).  Procedures and Functions may be "nested" to
  3242. a maximum of seven levels.  Recursion is allowed.
  3243.  
  3244. Pre-defined Functions include: TRUE, FALSE, ABS, SQR, ODD, SUCC, PRED, ROUND,
  3245. TRUNC, SIN, COS, EXP, LN, SQRT, ARCTAN, and RANDOM.  All of these Functions
  3246. have the same interpretation in P-ROBOTS as in standard PASCAL, except for the
  3247. various Trig functions which use degrees in P-ROBOTS, rather than radians.
  3248.  
  3249. The following are NOT allowed in P-ROBOTS and will generate error messages:
  3250. CHAR, STRING, enumerated types, subranges, pointers, variant records, PACKED,
  3251. sets, IN, files, input, output, GET, PUT, READ, WRITE, WITH, LABEL, GOTO.
  3252.  
  3253.  
  3254. UNIQUE P-ROBOTS PASCAL PROCEDURES AND FUNCTIONS
  3255.  
  3256. Alive -- returns a TRUE or FALSE depending upon whether your robot is alive or
  3257. not.
  3258.  
  3259. Ally -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3260. by the "ObjectScanned" function.
  3261.  
  3262. AllyAlive -- returns TRUE or FALSE depending upon whether your Ally is Alive or
  3263. not.
  3264.  
  3265. AllyDamage -- returns your Ally's current Damage level.
  3266.  
  3267. AllyDead -- returns TRUE or FALSE depending upon whether your Ally is Dead or
  3268. not.
  3269.  
  3270.                                          58
  3271.  
  3272.  
  3273.  
  3274.  
  3275. AllyFuel -- returns your Ally's current Fuel level.
  3276.  
  3277. AllyHeading -- returns your Ally's current Heading.
  3278.  
  3279. AllyLoc_X -- returns the current X coordinate of your Ally.
  3280.  
  3281. AllyLoc_Y -- returns the current Y coordinate of your Ally.
  3282.  
  3283. AllyMeters -- returns your Ally's current Meters.
  3284.  
  3285. AllyShieldRaised -- returns TRUE or FALSE depending upon whether your Ally's
  3286. shield is raised or not.
  3287.  
  3288. AllySpeed -- returns your Ally's current Speed.
  3289.  
  3290. Angle_To(X, Y) -- returns angle in degrees from your robot's current position
  3291. to the point X, Y on the battlefield.
  3292.  
  3293. Armor -- returns the type of armor with which your robot is equipped.  The
  3294. result returned can have the "constant" values: Light, Medium or Heavy.
  3295.  
  3296. BombsLeft -- returns the number of bombs that your robot currently has.  If
  3297. your robot does not select the electronic bombs option, the returned value will
  3298. be zero (obviously).
  3299.  
  3300. Compact -- a pre-defined P-ROBOTS "constant" which is one of the values
  3301. returned by the "Engine" function.
  3302.  
  3303. Cannon(degree, range); -- fires a missile at an angle of "degree" and for a
  3304. distance of "range".
  3305.  
  3306. Damage -- returns the value of your robot's current damage level.
  3307.  
  3308. Dead -- returns a TRUE or FALSE depending upon whether your robot is dead or
  3309. not.
  3310.  
  3311. Detonate; -- causes the bomb your robot had previous "dropped" or placed (using
  3312. the PlaceBomb procedure) to explode.
  3313.  
  3314. Distance(X1, Y1, X2, Y2) -- returns the distance in meters from the point X1,
  3315. Y1 on the battle field to the point X2, Y2.
  3316.  
  3317. Drive(degree, speed); -- causes your robot to move in the direction given by
  3318. "degree" at a specified "speed".
  3319.  
  3320. Economy -- a pre-defined P-ROBOTS "constant" which is one of the values
  3321. returned by the "Engine" function.
  3322.  
  3323. Enemy -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3324. by the "ObjectScanned" function.
  3325.  
  3326.  
  3327.                                          59
  3328.  
  3329.  
  3330.  
  3331.  
  3332. Engine -- returns the type of engine that your robot is equipped with.  The
  3333. result returned can have the "constant" values: Economy, Compact, Standard,
  3334. Large, or ExtraLarge.
  3335.  
  3336. ExtraLarge -- a pre-defined P-ROBOTS "constant" which is one of the values
  3337. returned by the "Engine" function.
  3338.  
  3339. Fuel -- returns the current value of your robot's fuel level in "jiggers".
  3340.  
  3341. HaveCloak -- returns TRUE or FALSE depending upon whether your robot is
  3342. equipped with a cloak.
  3343.  
  3344. HaveRepairKit -- returns TRUE or FALSE depending upon whether your robot is
  3345. equipped with a repair kit.
  3346.  
  3347. HaveShield -- returns TRUE or FALSE depending upon whether your robot is
  3348. equipped with a shield.
  3349.  
  3350. Heavy -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3351. by the "Armor" function.
  3352.  
  3353. Large -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3354. by the "Engine" function.
  3355.  
  3356. Light -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3357. by the "Armor" function.
  3358.  
  3359. LimitedFuel -- returns TRUE or FALSE depending upon whether your current battle
  3360. has fuel constraints or not.
  3361.  
  3362. LowerCloak; -- causes your robot's cloak to be lowered.
  3363.  
  3364. LowerShield; -- causes your robot's shield to be lowered.
  3365.  
  3366. MakeRepairs; -- causes your robot to begin repairing itself.
  3367.  
  3368. MaxRadarRange -- returns the maximum range (in meters) for your robot's radar.
  3369.  
  3370. MaxSpeed -- returns the maximum speed for your robot.
  3371.  
  3372. Medium -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3373. by the "Armor" function.
  3374.  
  3375. Meters -- returns the cumulative number of meters that your robot has traveled
  3376. during the current battle.
  3377.  
  3378. Normal -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3379. by the "Warheads" function.
  3380.  
  3381. Nothing -- a pre-defined P-ROBOTS "constant" which is one of the values
  3382. returned by the "ObjectScanned" function.
  3383.  
  3384.                                          60
  3385.  
  3386.  
  3387.  
  3388.  
  3389. ObjectScanned -- returns the type of object that was found by the most recent
  3390. "Scan" call (if any).  The result returned can have the "constant" values:
  3391. Nothing, Ally, Enemy or Obstruction.
  3392.  
  3393. Obstruction -- a pre-defined P-ROBOTS "constant" which is one of the values
  3394. returned by the "ObjectScanned" function.
  3395.  
  3396. PlaceBomb; -- causes your robot to "drop" or place an electronic bomb at the
  3397. current location.
  3398.  
  3399. Premium -- a pre-defined P-ROBOTS "constant" which is one of the values
  3400. returned by the "Warheads" function.
  3401.  
  3402. RaiseCloak; -- causes your robot's cloak to be raised.
  3403.  
  3404. RaiseShield; -- causes your robot's shield to be raised.
  3405.  
  3406. Random(limit) -- returns a random integer in the range of zero to "limit".
  3407.  
  3408. Scan(degree, resolution) -- returns the distance in meters to any other robot
  3409. or obstruction that is within the "viewing" arc/angle of "degree" +/-
  3410. "resolution".  If nothing is scanned then the function "Scan" returns a value
  3411. of zero.
  3412.  
  3413. ShieldRaised -- returns TRUE or FALSE depending upon whether your robot's
  3414. shield is up or down.
  3415.  
  3416. Standard -- a pre-defined P-ROBOTS "constant" which is one of the values
  3417. returned by the "Engine" function.
  3418.  
  3419. StopRepairs; -- causes your robot to stop repairing itself.
  3420.  
  3421. Time -- returns the current CPU cycle count.  This function can be used to time
  3422. various events, speeds, etc., within your robot program.
  3423.  
  3424. Warheads -- returns the type of warheads with which your robot is equipped.
  3425. The result returned can have the "constant" values: Wimp, Normal, or Premium.
  3426.  
  3427. Wimp -- a pre-defined P-ROBOTS "constant" which is one of the values returned
  3428. by the "Warheads" function.
  3429.  
  3430. Winner -- returns TRUE or FALSE depending upon your robot winning the battle.
  3431.  
  3432.  
  3433.  
  3434.  
  3435.  
  3436.  
  3437.  
  3438.  
  3439.  
  3440.  
  3441.                                          61
  3442.  
  3443.  
  3444.  
  3445.  
  3446. APPENDIX V: A BLATANT "PLUG" FOR ANOTHER SOFTWORKS PRODUCT
  3447.  
  3448. The MASTER'S EDITION of ADVENTURE GAME TOOLKIT (AGT) lets you design and write
  3449. your own high-quality text adventure games.  Using AGT's English-like language,
  3450. you can concentrate on the creative side of game writing. even adding optional
  3451. graphic illustrations, pop-up hints, sound effects, and music.  The high power
  3452. of the Master's Edition gives you sophisticated, professional results.  Your
  3453. adventure game can be shared with and enjoyed by others -- even if they do not
  3454. have a copy of the Adventure Game Toolkit themselves.
  3455.  
  3456.  
  3457. FEATURES OF MASTER'S EDITION OF THE ADVENTURE GAME TOOLKIT
  3458.  
  3459. The Master's Edition of AGT has a number of features that make it the most
  3460. comprehensive text adventure game creation product currently available.  Some
  3461. of these key features are:
  3462.  
  3463. *    Default "look-and-feel" of Infocom adventure games with similar screen
  3464.      layout and standard vocabulary and routines.
  3465.  
  3466. *    Large standard vocabulary with potential to define many more words unique
  3467.      to a specific adventure.  Typical games can have a vocabulary of 1000
  3468.      words or more.
  3469.  
  3470. *    Sophisticated parser that can understand (1) complex input commands
  3471.      including pronouns (IT, HIM, HER, THEM, MY and ITS), and (2) compound
  3472.      commands separated by AND or THEN or punctuation symbols, and (3) commands
  3473.      addressed to characters within the game.  Here are a few examples of
  3474.      commands AGT can handle with ease:
  3475.  
  3476.      GET THE FLASH LIGHT AND THEN SWITCH IT ON
  3477.      PUT ON THE CLOAK, THEN EXAMINE IT; READ ITS LABEL
  3478.      PLACE THE GREEN ROCK AND THE SMALL PEBBLE BEHIND THE TREE
  3479.      ENTER THE HOUSE; GET ALL; EXIT; SOUTH; SOUTH THEN DOWN
  3480.      SULU, SET A COURSE FOR ALPHA 14
  3481.      SCOTTY, BEAM DOWN A TRICORDER AND THE QWERTY MODULE
  3482.      DROP THE FOOD, THE KEY AND THE BOTTLE THEN UNLOCK THE DOOR WITH THE
  3483.           BRASS KEY AND THEN LEAVE
  3484.  
  3485. *    Function and cursor keys predefined to input frequently used commands and
  3486.      move directions.  Function keys may also be redefined to input frequently
  3487.      used commands like THROW AXE AT DWARF or GIVE MILK BOTTLE  TO BABY.
  3488.  
  3489. *    An OOPS feature that allows you to edit/correct your input commands.
  3490.  
  3491. *    SCRIPT and UNSCRIPT commands to echo game output to printer.
  3492.  
  3493. *    Optional graphic illustrations using PCX formatted pictures for display on
  3494.      CGA, EGA or VGA screens.  The PCX format is the most widely available of
  3495.      any picture format and is supported by most PAINT and/or DRAW programs.
  3496.      Plus -- a great deal of PCX "clip-art" is  available.
  3497.  
  3498.                                          62
  3499.  
  3500.  
  3501.  
  3502.  
  3503. *    Optional music and sound effects that can be played in the "background"
  3504.      during the game.  These sound effects use the PC's internal speaker and do
  3505.      not require any special "sound card."
  3506.  
  3507. *    Optional user-definable "look-and-feel" interface including a menu-driven
  3508.      player input option that displays feasible commands for the player to pick
  3509.      from.
  3510.  
  3511. *    Optional "pop-up" hints available when the <Alt> and <h> keys are pressed.
  3512.  
  3513. *    Optional fonts (EGA and VGA monitors only) that can be changed to suit the
  3514.      needs of the game.  The Master's Edition comes with over 30 sample fonts
  3515.      including Old English, Scrawl, Computereze.  A  Font Editor is provided
  3516.      that allows you to create your own unique fonts.
  3517.  
  3518. WHAT THE REVIEWERS HAVE SAID ABOUT THE ADVENTURE GAME TOOLKIT
  3519.  
  3520. "Using the Adventure Game Toolkit, anyone with an ounce of imagination can
  3521. create a text adventure game ... similar in layout and sophistication to those
  3522. made by Infocom and other commercial developers."
  3523.         -- Donald B. Trivette in PC Magazine
  3524.  
  3525. "The Adventure Game Toolkit (AGT) acts as a compiler which allows for creating
  3526. remarkably complex and sophisticated games in a fairly simple way .... AGT's
  3527. parser reminds me of Infocom's."
  3528.         -- Scorpia in Computer Gaming World
  3529.  
  3530. "If you have ever wondered what it is like to create your own adventure games,
  3531. but didn't have the programming knowledge to do it, this product is for you
  3532. .... The process is easy ... and you'll have hours of fun doing it."
  3533.         -- Resul DeMaria in Public Domain Software & Shareware
  3534.  
  3535. "The Adventure Game Toolkit from Softworks ... provides all the tools you need
  3536. to build your own text based adventure games .... The Adventure Game Toolkit is
  3537. an extremely powerful development package."
  3538.         -- Bob Napp in "The Big Blue Disk"
  3539.  
  3540. The Adventure & Strategy Club (of England) recently selected the Adventure Game
  3541. Toolkit as the Best Utility of 1992.
  3542.  
  3543. WHAT YOU PAY AND WHAT YOU GET
  3544.  
  3545. The Master's Edition of AGT is also "Freeware."  Look for it on CompuServe,
  3546. GEnie, various BBSs or from disk vendors.
  3547.  
  3548.                                          63
  3549.  
  3550.  
  3551.  
  3552. HOW TO GET A COPY OF THE ADVENTURE GAME TOOLKIT
  3553.  
  3554. The Master's Edition of AGT is also "Freeware."  Look for it on CompuServe,
  3555. GEnie, various BBSs or from disk vendors.
  3556.  
  3557.  
  3558.                                          64
  3559.  
  3560.  
  3561.  
  3562.  
  3563. APPENDIX VI: ABOUT THE AUTHOR
  3564.  
  3565.  
  3566. Dave Malmberg has been active in the world of personal computer since 1977.  He
  3567. is the author or co-author of seven published software products.  His most
  3568. recent software product is the Master's Edition of the Adventure Game Toolkit.
  3569.  
  3570. His most successful products were the Turtle Graphics series published by
  3571. HESware.  These two programs have sold over 80,000 copies world-wide, were
  3572. translated into Spanish, and won two Consumer Electronic Software Showcase
  3573. awards as some of the best software of 1983.  These programs were widely used
  3574. in schools to teach computer literacy to children and other computer novices.
  3575.  
  3576. Dave has also published numerous articles and programs in various computer
  3577. magazines.  He has been a Contributing Editor of both COMPUTE!'s HOME &
  3578. EDUCATIONAL COMPUTING and MICRO magazines.  He was one of the principal authors
  3579. of COMPUTE!'s FIRST BOOK OF VIC, the best selling computer book of 1983.  He
  3580. has written regular columns on educational uses of computers and on LOGO for
  3581. COMMODORE and POWER/PLAY magazines. He was delighted to receive recognition
  3582. from abroad when the British-based Adventure & Strategy Club honored him with
  3583. their Golden Chalice Award in 1992 for his adventure game system.
  3584.  
  3585.  
  3586.  
  3587.  
  3588.  
  3589.  
  3590.  
  3591.  
  3592.  
  3593.  
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.                                          65
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.