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