home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-04-09 | 59.6 KB | 1,622 lines |
-
-
-
-
-
-
-
-
-
-
-
- _____________________________________________________________
- | |
- |: :|
- | ##### ###### ####### ###### ####### ####### ##### |
- | # # # # # # # # # # # # # |
- | # # # # # # # # # # # |
- | # ###### # # ###### # # # ##### |
- | # # # # # # # # # # # |
- | # # # # # # # # # # # # # |
- | ##### # # ####### ###### ####### # ##### |
- |: :|
- |_____________________________________________________________|
-
-
- ___ ____ ___
- / \ /\ /\ * / \ / \
- / \ / V \ _ | / \
- | | | | | | | _ | |
- |-----| | | | | | \ |-----|
- | | | |V| | | | | | | |
- | | |_| |_| |_| \_____/ | |
-
-
-
- (C) Copyright 1985, Tom Poindexter
- (C) Copyright 1989-90, David Wright - Amiga Version
-
-
- David Wright
- 4262 Bennington
- Brunswick, OH 44212
- USA
- (216) 273-1064
- davewt@NCoast.ORG
- uunet!hal!ncoast!davewt
- uunet!cwjcc!ncoast!davewt (prefered)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _1_. _D_i_s_t_r_i_b_u_t_i_o_n _a_g_r_e_e_m_e_n_t_:
-
- You may make copies of this program, manual, and other files and
- give them to your friends, upload it to bulletin boards, or include
- it in the library of a non-profit computer club. In short, you are
- free to distribute at will with the exception of distribution for
- profit.
-
- _2_. _I_n_t_r_o_d_u_c_t_i_o_n
-
- _2_-_1_. _D_e_s_c_r_i_p_t_i_o_n
-
- CRobots ("see-robots") is a game based on computer programming.
- Unlike arcade type games which require human input controlling some
- object, all strategy in CRobots must be complete before the actual
- game begins. Game strategy is condensed into a C language program
- that you design and write. Your program controls a robot whose
- mission is to seek out, track, and destroy other robots, each
- running different programs. Each robot is equally equipped, and up
- to four robots may compete at once. CRobots is best played among
- several people, each refining their own robot program, then
- matching program against program.
-
- CRobots consists of a C compiler, a virtual computer, and
- battlefield display. The CRobots compiler accecpts a limited (but
- useful) subset of the C language. The robot programs are aided by
- hardware functions to scan for opponents, start and stop drive
- mechanisms, fire cannons, etc. After the programs are compiled and
- loaded into separate robots, the battle is observed. Robots moving,
- missiles flying and exploding, and certain status information are
- displayed on the screen, in real-time.
-
-
- _2_-_2_. _I_n_t_e_n_d_e_d _a_u_d_i_e_n_c_e
-
- CRobots will most likely appeal to programmers (especially those
- who think they can write the "best" programs), computer game
- enthusiasts, people wishing to learn the C language, and those who
- are interested in compiler design and virtual computer
- interpreters.
-
-
- _2_-_3_. _M_a_c_h_i_n_e _a_n_d _s_o_f_t_w_a_r_e _r_e_q_u_i_r_e_m_e_n_t_s
-
- - Amiga 500, 1000, 2000, 2500
- - 512k of RAM
- - DOS 1.3 or higher
- - ARP 1.3 or higher
- - Monochrome or Color monitor
- - Text editor (UE, TxEd, or your own favorite)
-
-
-
-
- Page 1
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- NOTE FOR 512K 1000 & 500 USERS: I have tested version 2.3 on a
- 512k 1000, and was able to get it to work. If you have problems,
- try setting the stack size to 25 or 30k. I was able to get it to
- run by breaking out of the startup-sequence, setting the stack to
- 30k, and then running it. It might work with WB loaded, but with
- only 512k it might be tight, and you might need to remove any
- external drives.
-
- _2_-_4_. _U_s_e_r _i_n_t_e_r_f_a_c_e
-
- At the present time CRobots does not use menus, windows, pop-ups
- (other than a file requester), or any other user-friendly
- interface. Since the emphasis is on designing and writing robot
- control programs, CRobots is usually started as a compiler is, from
- the AmigaDOS command line, although a WorkBench interface is
- available.
-
-
- _3_. _T_y_p_e_s _o_f _p_l_a_y
-
- CRobots can either run one match (single play), in which the
- realtime battlefield simulator is used, or several matches (match
- play), in which only the name of the winner is printed after each
- match. Single play is the default. Match play is intended to see
- how robot programs perform on the average. Match play can consume
- several hours of computer time depending on the number of matches
- and cpu cycle limit, and can be run overnight.
-
-
- _4_. _R_u_n_n_i_n_g _C_R_o_b_o_t_s
-
- _4_-_1_. _C_o_m_m_a_n_d _l_i_n_e _o_p_t_i_o_n_s
-
- CRobots can be started from the CLI or a WorkBench icon. If it
- is started from the CLI you may also specify several options.
-
- Sample command line:
-
- 1>crobots [options] [robot-program-1 ... robot-program-n]
-
- Valid options are:
-
- TO file Save the output from the compile listing ("COMPILE"
- option) or record matches ("MATCH" option) to <file>.
-
- COMPILE Compile only, and produce virtual machine assembler
- code and symbol tables. You must have the source code
- (.r file) for a robot to use this function.
-
-
-
-
-
-
- Page 2
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- DEBUG Compile one program, and invoke machine level
- single step tracing. You must have the source code
- (.r file) for a robot to use this function.
-
- MATCH xxx Run a series of matches, where "xxx" is the number
- of matches. If "MATCH" is NOT specified, then the
- default is to run one match and display the
- battlefield in realtime. If the MATCH option IS
- selected, all the robots must be pre-compiled.
-
- LIMIT xxx Limit the number of machine cpu cycles per match
- when "MATCH" is specified. The default cycle limit
- is 500,000.
-
- NOSHOW Turn off compilation display to increase speed.
-
- NOWAIT Turn off the "press any key" messages. Used mainly
- when running a series of matches and output is
- directed to a file with the TO option.
-
- robot-programs The file name of the CRobots source program(s).
- (Wildcards allowed) Up to four files may be
- specified. If only one file is specified, it will
- be "cloned" into another, so that two robots
- (running the same program) will compete. Any file
- name may be used, but for consistency please use
- '.r' as an extension for source code. If you do
- not give any robot file names, all the names you
- give can't be found, or you run CRobots from the
- WorkBench, the ARP file requester will come up
- and allow you to select up to 4 robots.
- If you do not wish to load 4 robots, just click
- the CANCEL gadget after selecting the last robot
- you want to load.
-
- Note that some of these options are mutually-exclusive, and that
- others will have no effect depending on the mode you are in.
-
- _4_-_2_. _E_x_a_m_p_l_e_s_:
-
- 1) Watch three robots compete with full display:
- 1>crobots robot1.cr robot2.cr robot3.cr
-
- 2) Compile one robot, and save the listing:
- 1>crobots COMPILE TO robot1.lst robot1.r
-
- 3) Debug a robot (first get an assembler code listing,
- as in example 2:
- 1>crobots DEBUG robot1.r
-
- 4) Run 50 matches, limiting total cpu cycles to 200,000
- (per match), and save results:
-
-
- Page 3
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- 1>crobots MATCH 50 LIMIT 200000 TO save rbt1.cr rbt2.cr
-
- 5) Display command line options
- 1>crobots ?<return>?<return>
-
-
- _4_-_3_. _R_u_n_n_i_n_g _C_R_o_b_o_t_s _f_r_o_m _t_h_e _W_o_r_k_B_e_n_c_h
-
- If you wish you may start CRobots from the WorkBench by clicking
- on it's icon. You may also specify some of the options that were
- available from the CLI by using the icon's "tool types" array. You
- can edit this array by clicking on the CRobots icon _o_n_c_e and then
- selecting the menu option "Info". You will see a blank line that
- has ADD and DEL gadgets to the right of it. Click the ADD gadget
- and a cursor will appear at the start of the blank line. Type in
- one of the following keywords followed by an equals sign, and the
- value you want (value limits are the same as for the CLI options
- above):
-
- MATCHES
- LIMIT
- NOSHOW
-
- Matches and limit take numeric arguments, as under the CLI,
- while the noshow option should be followed by a YES if you wish to
- turn the option on (see above for what the noshow flag does).
- You may add as many of these options as you wish, but you must
- use the ADD gadget to create each new option, and the DEL gadget to
- delete options that you no longer want.
- Once you have added/deleted the options that you want, click the
- SAVE gadget to exit and save them to disk.
-
- _4_-_4_. _W_o_r_k_b_e_n_c_h _e_x_a_m_p_l_e_s
-
- 1) Set the number of matches to 3, with a limit of
- 20,000 cycles per match:
- MATCHES=3
- LIMIT=20000
-
- 2) Turn off screen output of robot compilations:
- NOSHOW=YES
-
-
- _5_. _G_a_m_e _p_a_r_a_m_e_t_e_r_s
-
- _5_-_1_. _B_a_t_t_l_e_f_i_e_l_d
-
- The battlefield is a 1,000 by 1,000 meter square. A wall
- surrounds the perimeter, so that a robot running into the wall will
- incur damage. Note that as screen resolution is obviously less than
- 1000x1000, there is bound to be some error is scaling which will
- make robots appear to be hit by pulses when they take no damage.
-
-
- Page 4
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- Robots may also appear to go over each other, and take damage from
- hitting walls when they appear to be a slight distance away from
- them.
-
- The lower left corner has the coordinates x = 0, y = 0; the
- upper right corner has the coordinates x = 999, y = 999. There are
- grids on the floor of the battlefield, and emitter/detector pairs
- on the bottom of the robot which allow it to keep track of it's
- position much like an optical mouse.
-
- The compass system is oriented so that due east (right) is 0
- degrees, 90 is north, 180 is west, 270 is south. One degree below
- due east is 359.
-
-
- 135 90 45
- \ | /
- \ | /
- 180 --- x --- 0
- / | \
- / | \
- 225 270 315
-
-
- _5_-_2_. _R_o_b_o_t _o_f_f_e_n_s_e
-
- The main offensive weapons are the phased particle cannon (PPC)
- and scanner. The PPC has a range of 700 meters. The PPC may be
- fired an unlimited number of times, but a recharging factor
- effectively limits the number of pulses in the air at any one time
- to two. The PPC is mounted on an independent turret, and therefore
- can fire any direction, 0-359, regardless of robot heading.
-
- The scanner is an optical device that can instantly scan any
- chosen heading, 0-359. The scanner has a maximum resolution of +/-
- 10 degrees. This enables the robot to quickly scan the field at a
- low resolution, then use maximum resolution to pinpoint an
- opponent.
-
-
- _5_-_3_. _R_o_b_o_t _d_e_f_e_n_s_e
-
- The only defenses available are the motor drive and status
- registers. The motor can be engaged on any heading, 0-359, in
- speeds from 0-100 percent of power. Robot mass is considerable, so
- there are acceleration and deacceleration delay factors. A speed of
- 0 stops the motor. Turns can be negotiated at speeds of 50% and
- less, in any direction. Of course, the motor drive can be engaged
- any time, and is necessary on offense when a target is beyond the
- 700 meter range of the PPC.
-
- There are several embedded controllers in the robot which
-
-
- Page 5
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- utilize a shared memory system (18 DMA channels) to update certain
- status registers without tying up the primary robot CPU. The
- primary registers indicate the percent of damage, and current x and
- y locations on the battlefield. Another register provides the
- current drive speed.
-
-
- _5_-_4_. _D_i_s_a_b_l_i_n_g _o_p_p_o_n_e_n_t_s
-
- A robot is considered dead when the damage reaches 100%. Percent
- of damage inflicted is as follows:
-
- 2% - collision into another robot (both robots in a
- collision receive damage) or into a wall. A
- collision also causes the motor drive to disengage,
- and speed is reduced to 0.
-
- 3% - a pulse impacting within a 40 meter radius.
-
- 5% - a pulse impacting within a 20 meter radius.
-
- 10% - a pulse impacting within a 5 meter radius.
-
-
- Damage is cumulative, and cannot be repaired. However, a robot
- does not lose any mobility, firing potential, etc. at high damage
- levels. In other words, a robot at 99% damage performs just as well
- as a robot with no damage.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 6
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _5_-_5_. _S_a_m_p_l_e _d_i_s_p_l_a_y
-
-
- (Status
- (x=999,y=999) blocks)
-
- +------------------------------------+ 1 fubar.r
- | | D% 015 Sc 218
- | \|/ 1 | Sp 000 Hd 090
- | (pulse impacting) -#- | ------------------
- | /|\ | 2 snafu.r
- (y | | D% 050 Sc 275
- | + -------(particle | Sp 100 Hd 180
- a | + --pulses) | ------------------
- x | 2 | 3 bimbo.r
- i | | D% 000 Sc 045
- s) | 3 | Sp 000 Hd 000
- | / | ------------------
- | (robots) ----\ | 4 kumquat.r
- | 4 | D% 100 Sc 050
- | | Sp 000 Hd 335
- | |
- | |
- +------------------------------------+ CPU Cycle: 4500
-
- (x=0,y=0) (x axis)
-
- The CRobots battle console consists of several color CRT's and
- an LCD counter. The largest CRT is the primary battle display, and
- displays the battle in real-time. The smaller CRT's are status
- blocks for each robot.
-
- Each status block shows the file name of the robot, the damage
- incurred (D%), the current scan degrees (Sc), the speed (Sp), and
- heading (Hd). Robots are represented on the field by a graphic
- item, which is also displayed to the left of the name in the status
- block for reference. If Damage is below 90%, it will be displayed
- in green. If damage is between 90 & 100% it will be displayed in
- red. When damage reaches 100%, it will be displayed in black.
-
- The number of elapsed robot cpu cycles is shown in an LCD
- display below the status blocks.
-
- The CRobots program can be aborted at any time by pressing the
- ESC key. It may also be paused at almost any time by pressing SPACE
- or CTRL-S, and restarted by pressing SPACE again or CTRL-Q.
-
-
-
-
-
-
-
-
- Page 7
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _5_-_6_. _T_a_b_l_e _o_f _T_i_m_e _C_o_s_t_s
-
- As just a few CPU cycles can make the difference between a
- winner and loser, following is a table of the cost in CPU cycles of
- various actions:
-
- Action Cpu Cycles
- ----------------------------------
- Recharge PPC 150
- Acc/Decellerate 10% 10
- Pulse traveling 50
- meters 10
- Robot move 7 meters
- at 100% speed 1
-
-
- _6_. _C_R_o_b_o_t_s _C_P_U
-
- The robot cpu is a simple stack-oriented computer. It operates
- at very slow speeds (on a 7.8 MHz 68000 Amiga with an average
- amount of background tasks running and with two robots loaded, the
- average speed is 309 instructions per second, .000309 mips!!). The
- word size is 32 bits, allowing integer values from -2,147,483,648
- to 2,147,483,647. There are internal pointer registers that manage
- stack usage, but are not accessible from a robot program. The same
- is true for an implicit accumulator.
-
- The maximum code space is 1,000 instructions. All instructions
- are equal in length. The maximum stack size is 500 words, which is
- used for data and function call/returns. The stack grows upward for
- data usage, and downward (from the end) for function call/returns.
- Three words are used for each function call, and are released upon
- the function return. The data portion and call/return portion are
- managed by separate internal stack pointers.
-
- If the data stack pointer and call/return stack pointer collide,
- a stack overflow occurs. In this case, the robot is restarted at
- the 'main' function, with the stack reset to all zeros.
-
- For more information, see the section on machine instructions
- and theory.
-
-
- _7_. _C_R_o_b_o_t_s _C _c_o_m_p_i_l_e_r
-
- _7_-_1_. _D_e_s_c_r_i_p_t_i_o_n
-
- The CRobots compiler accepts a limited subset of the C
- language. There is no provision for separate compilation, i.e.,
- all modules of a program must be in one file. No preprocessor is
- provided for "#define", "#include", etc. Identifiers are
- significant to 7 characters, although any length may be used. The
-
-
- Page 8
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- compiler will compile any file, but will convert any existing
- extension to (or add the extension) ".cr". CRobots reserves the
- extension ".cr" for "Compiled Robot", and will not like other files
- using the same names. For consistency, use the extension ".r" for
- robot source code files, and let the compiler convert them to
- ".cr".
-
- _7_-_2_. _F_e_a_t_u_r_e_s _m_i_s_s_i_n_g _f_r_o_m _s_t_a_n_d_a_r_d _C
-
- Major language features missing from K&R are: floating point
- variables, structures, unions, pointers, initializers, arrays,
- character data, typedefs, for statement, do..while statement,
- switch..case statement, break, continue, gotos and labels, ternary
- and comma operators, octal and hexadecimal constants, no parameters
- to main(), no I/O functions, and all preprocessor directives.
-
-
- _7_-_3_. _C_R_o_b_o_t_s _l_a_n_g_u_a_g_e
-
- The language features that are present are entirely suitable for
- writing robot control programs. Basic programming constructs of
- if..then..else, while, and function calls can be used freely. Full
- expression evaluation is also provided, so that statements such as:
-
- if ((x = func1(y,1,++z,func2(c))) > 0)
- a = 0;
- else
- a = x;
-
- are perfectly legal. Ifs and whiles may be nested, and recursion is
- supported. Variables declared outside a function definition are
- global in scope, whereas variables declared inside a function
- definition are local to that function.
-
-
- The following keywords are recognized:
-
- ccoommmmeennttss::
- "/* ... */" comments cannot be nested
-
- ccoonnssttaannttss::
- any decimal digits, optionally preceeded with a '-'
-
- ddeeccllaarraattiioonnss::
- "int" variable declare
- "long" same as int
- "auto" default storage scope, optional
- "register" legal, but ignored, same as auto
- "function (parms,.....)" function definition
-
-
-
-
-
- Page 9
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- llooggiicc ccoonnttrrooll::
- "if (expr) STMT else STMT"
-
- iitteerraattiioonn::
- "while (expr) STMT"
-
- ffuunnccttiioonn rreettuurrnn::
- "return" return
- "return expr" return with a value
-
- aassssiiggnnmmeenntt ooppeerraattoorrss::
- "=" assignment
- ">>=" assignment shift right
- "<<=" assignment shift left
- "+=" assignment addition
- "-=" assignment subtraction
- "*=" assignment multiplication
- "/=" assignment division
- "%=" assignment modulo
- "&=" assignment and
- "^=" assignment exclusive or
- "|=" assignment inclusive or
-
- bbiitt--wwiissee ooppeerraattoorrss::
- ">>" shift right
- "<<" shift left
- "&" and
- "!" unary not
- "~" unary one's complement
- "^" exclusive or
- "|" inclusive or
-
- iinnccrreemmeenntt//ddeeccrreemmeenntt ooppeerraattoorrss::
- "++" prefix or postfix increment
- "--" prefix or postfix decrement
-
- llooggiiccaall ooppeerraattoorrss::
- "&&" logical and
- "||" logical or
- "<=" logical less than or equal
- ">=" logical greater than or equal
- "==" logical equal
- "!=" logical not equal
- "<" logical less than
- ">" logical greater than
-
-
-
-
-
-
-
-
-
- Page 10
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- aarriitthhmmeettiicc ooppeerraattoorrss::
- "-" subtraction or unary negation
- "+" addition
- "*" multiplication
- "/" division
- "%" modulo
-
- mmiisscc::
- ";" statement terminator or null statement
- "{ }" compound statement
- "," parameter separator in function definition or call
- "( )" expression or function definition or call
-
- Precedence and order of evaluation are the same as in K&R.
-
- Operator Associativity
- () left to right
- ! ~ ++ -- - right to left
- * / % left to right
- + - " " "
- << >> " " "
- < <= => > " " "
- == != " " "
- & " " "
- ^ " " "
- | " " "
- && " " "
- || " " "
- = -= += etc. right to left
-
-
- Major derivations from K&R:
-
- -Local variables need not be declared before reference, i.e., any
- undeclared variable will default to a local variable.
-
- -Intrinsic function names are reserved.
-
-
- _7_-_4_. _C_o_m_p_i_l_e_r _l_i_m_i_t_s
-
- defined functions: 64
- local variables per function: 64
- external variables: 64
- if nest level: 16
- while nest level: 16
- line length 2000 bytes
-
-
-
-
-
-
-
- Page 11
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _7_-_5_. _C_o_m_p_l_i_e_r _e_r_r_o_r _a_n_d _w_a_r_n_i_n_g _m_e_s_s_a_g_e_s_:
-
- The compiler has no error recovery and will stop on the first
- error found. Warning messages do not stop the compiler.
-
- EErrrroorr mmeessssaaggeess
-
- "syntax error" - Any input that results in improper C syntax will
- yield "syntax error", with an indicator pointing to the
- unrecognizable input.
-
- "instruction space exceeded" - compiler tried to generate more than
- 1000 machine instructions.
-
- "symbol pool exceeded" - the maximum local variable, external
- variable, or function definition symbol table was exceeded.
-
- "function referenced but not found" - a function was referenced
- that was not defined in the input file or is not an intrinsic
- function.
-
- "main not defined" - the input file did not define a 'main()'
- function.
-
- "function definition same as intrinsic" - a function was defined
- with the same name as an intrinsic function, which is
- reserved.
-
- "if nest level exceeded" - more than 16 'if's were nested.
-
- "while nest level exceeded" - more than 16 'while's were nested.
-
- "yacc stack overflow" - the compiler's parser overflowed, probably
- due to complex expressions and/or extreme nesting.
-
- WWaarrnniinngg mmeessssaaggeess
-
- These messages will not cause the compiler to fail, but may
- cause the program to execute unexpectedly.
-
- "unsupported initializer" - variable declares cannot include an
- initializer. For future releases.
-
- "unsupported break" - the 'break' statement was found and ignored.
- For future releases.
-
- "n undeclared variables" - one or more variables were implicitly
- declared.
-
- "code utilization: n%" - reports the capacity of machine
- instructions generated.
-
-
-
- Page 12
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _7_-_6_. _C_o_m_p_i_l_e_r _N_o_t_e_s_:
-
- The version 2.3 compiler will generate the postfix increment /
- decrement operators, but you should be aware of the size penalty
- when using them. Prefix operators only generate 3 instructions,
- while postfix operations generate 5 instructions.
-
- _8_. _C_R_o_b_o_t_s _C _I_n_t_r_i_n_s_i_c _F_u_n_c_t_i_o_n _L_i_b_r_a_r_y
-
- The intrinsic function library provides machine level control
- and certain arithmetic functions. These functions do not consume
- any of the program code space or data stack, except for the three
- words for call/return sequences. No explicit linking is required to
- use any intrinsic function.
-
-
- scan (degree,resolution)
-
- The scan() function invokes the robot's scanner, at a specified
- degree and resolution. scan() returns 0 if no robots are within the
- scan range or a positive integer representing the range to the
- closest robot. Degree should be within the range 0-359, otherwise
- degree is forced into 0-359 by a modulo 360 operation, and made
- positive if necessary. Resolution controls the scanner's sensing
- resolution, up to +/- 10 degrees. Examples:
- range = scan(45,0); /* scan 45, with no variance */
- range = scan(365,10); /* scans the range from 355 to 15 */
-
-
- cannon (degree,range)
-
- The cannon() function fires the PPC at a specified range and
- direction. cannon() returns 1 (true) if a pulse was discharged, or
- 0 (false) if the PPC is recharging. Degree is forced into the range
- 0-359 as in scan(). Range can be 0-700, with greater ranges
- truncated to 700. Examples:
- degree = 45; /* set a direction to test */
- if ((range=scan(degree,2)) > 0) /* see if a target is there */
- cannon(degree,range); /* fire a missile */
-
-
- drive (degree,speed)
-
- The drive() function activates the robot's drive mechanism, on a
- specified heading and speed. Degree is forced into the range 0-359
- as in scan(). Speed is expressed as a percent, with 100 as maximum.
- A speed of 0 disengages the drive. Changes in direction can be
- negotiated at speeds of less than 50 percent. Examples:
- drive(0,100); /* head due east, at maximum speed */
- drive(90,0); /* stop motion */
-
-
-
-
- Page 13
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- damage()
-
- The damage() function returns the current amount of damage
- incurred. damage() takes no arguments, and returns the percent of
- damage, 0-99. (100 percent damage means the robot is completely
- disabled, thus no longer running!) Examples:
- d = damage(); /* save current state */
- ; ; ; /* other instructions */
- if (d != damage()) /* compare current state to prior state */
- {
- drive(90,100); /* robot has been hit, start moving */
- d = damage(); /* get current damage again */
- }
-
-
- speed ()
-
- The speed() function returns the current speed of the robot.
- speed() takes no arguments, and returns the percent of speed,
- 0-100. Note that speed() may not always be the same as the last
- drive(), because of acceleration and deacceleration delays.
- Examples:
- drive(270,100); /* start drive, due south */
- ; ; ; /* other instructions */
- if (speed() == 0) /* check current speed */
- {
- drive(90,20); /* ran into the south wall, or another robot*/
- }
-
-
-
- loc_x () loc_y ()
-
- The loc_x() function returns the robot's current x axis
- location. loc_x() takes no arguments, and returns 0-999. The
- loc_y() function is similar to loc_x(), but returns the current y
- axis position.
- Examples:
- drive (180,50); /* start heading for west wall */
- while (loc_x() > 20)
- ; /* do nothing until we are close */
- drive (180,0); /* stop drive */
-
-
- rand (limit)
-
- The rand() function returns a random number between 0 and limit,
- up to 32767.
- Examples:
- degree = rand(360); /* pick a random starting point */
- range = scan(degree,0); /* and scan */
-
-
-
- Page 14
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
-
- sqrt (number)
-
- The sqrt() returns the square root of a number. Number is made
- positive, if necessary.
- Examples:
- x = x1 - x2; /* compute the classical distance formula */
- y = y1 - y2; /* between two points (x1,y1) (x2,y2) */
- distance = sqrt((x*x) - (y*y));
-
-
- sin (degree) cos (degree) tan (degree) atan (ratio)
-
- These functions provide trigonometric values. sin(), cos(), and
- tan(), take a degree argument, 0-359, and returns the trigonometric
- value times 100,000. The scaling is necessary since the robot cpu
- is an integer only machine, and trig values are between 0.0 and
- 1.0. atan() takes a ratio argument that has been scaled up by
- 100,000, and returns a degree value, between -90 and +90. The
- resulting calculation should not be scaled to the actual value
- until the final operation, as not to lose accuracy. See
- programming examples for usage.
-
-
- _9_. _C_R_o_b_o_t_s _C _P_r_o_g_r_a_m _S_t_r_u_c_t_u_r_e
-
- _9_-_1_. _B_a_s_i_c _p_r_o_g_r_a_m _s_t_r_u_c_t_u_r_e
-
- CRobots programs are not unlike other C programs. The minimum
- CRobots program consist of a function named "main". Additionally,
- other functions can be defined, along with external variables.
- There is one restriction about robot source files. The first 2
- lines are reserved for the "Company" which produces a robot, and
- the "Author" of the robot, respectively. As an example, a club may
- use the same "company" name, while putting the programmer for each
- robot in the "author" spot. This lets you share your robot with
- other players, and still get credit for writing it. Both "company"
- and "author" may be up to 15 characters long. If you do not want
- these fields, you _M_U_S_T make the first 2 lines blank.
-
- When a .r file is compiled, a file with the extension of .cr
- will be created. This is the robot in a compiled and encrypted
- format. You can give this file out for competition (as mentioned
- above) without giving out your source code. Additionally, each .cr
- file keeps track of wins and losses since the robot was last
- compiled (needless to say, but to prevent major lawsuits,
- recompiling a robot will clear out the stats).
-
-
-
-
-
-
-
- Page 15
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- _9_-_2 _"_s_n_i_p_e_r_._r_"
-
- The following CRobots program is provided as an example.
-
- CRobots, Inc.
- T. Poindexter
- /* sniper */
- /* strategy: since a scan of the entire battlefield can be done in 90 */
- /* degrees from a corner, sniper can scan the field quickly. */
-
- /* external variables, that can be used by any function */
- int corner; /* current corner 0, 1, 2, or 2 */
- int c1x, c1y; /* corner 1 x and y */
- int c2x, c2y; /* " 2 " " " */
- int c3x, c3y; /* " 3 " " " */
- int c4x, c4y; /* " 4 " " " */
- int s1, s2, s3, s4; /* starting scan position for corner 1 - 4 */
- int sc; /* current scan start */
- int d; /* last damage check */
-
- /* main */
- main()
- {
- int closest; /* check for targets in range */
- int range; /* range to target */
- int dir; /* scan direction */
-
- /* initialize the corner info */
- /* x and y location of a corner, and starting scan degree */
- c1x = 10; c1y = 10; s1 = 0;
- c2x = 10; c2y = 990; s2 = 270;
- c3x = 990; c3y = 990; s3 = 180;
- c4x = 990; c4y = 10; s4 = 90;
- closest = 9999;
- new_corner(); /* start at a random corner */
- d = damage(); /* get current damage */
- dir = sc; /* starting scan direction */
-
- while (1) { /* loop is executed forever */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 16
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- while (dir < sc + 90) { /* scan through 90 degree range */
- range = scan(dir,1); /* look at a direction */
- if (range <= 700 && range > 0) {
- while (range > 0) { /* keep firing while in range */
- closest = range; /* set closest flag */
- cannon(dir,range); /* fire! */
- range = scan(dir,1); /* check target again */
- if (d + 15 > damage()) /* sustained several hits, */
- range = 0; /* goto new corner */
- }
- dir -= 10; /* back up scan, in case */
- }
-
- dir += 2; /* increment scan */
- if (d != damage()) { /* check for damage incurred */
- new_corner(); /* we're hit, move now */
- d = damage();
- dir = sc;
- }
- }
-
- if (closest == 9999) { /* check for any targets in range */
- new_corner(); /* nothing, move to new corner */
- d = damage();
- dir = sc;
- } else /* targets in range, resume */
- dir = sc;
- closest = 9999;
- }
-
- } /* end of main */
-
- /* new corner function to move to a different corner */
- new_corner() {
- int x, y;
- int angle;
- int new;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 17
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- new = rand(4); /* pick a random corner */
- if (new == corner) /* but make it different than the */
- corner = (new + 1) % 4;/* current corner */
- else
- corner = new;
- if (corner == 0) { /* set new x,y and scan start */
- x = c1x;
- y = c1y;
- sc = s1;
- }
- if (corner == 1) {
- x = c2x;
- y = c2y;
- sc = s2;
- }
- if (corner == 2) {
- x = c3x;
- y = c3y;
- sc = s3;
- }
- if (corner == 3) {
- x = c4x;
- y = c4y;
- sc = s4;
- }
-
- /* find the heading we need to get to the desired corner */
- angle = plot_course(x,y);
-
- /* start drive train, full speed */
- drive(angle,100);
-
- /* keep traveling until we are within 100 meters */
- /* speed is checked in case we run into wall, other robot */
- /* not terribly great, since were are doing nothing while moving */
-
- while (distance(loc_x(),loc_y(),x,y) > 100 && speed() > 0)
- ;
-
- /* cut speed, and creep the rest of the way */
-
- drive(angle,20);
- while (distance(loc_x(),loc_y(),x,y) > 10 && speed() > 0)
- ;
-
- /* stop drive, should coast in the rest of the way */
- drive(angle,0);
- } /* end of new_corner */
-
-
-
-
-
-
- Page 18
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- /* classical pythagorean distance formula */
- distance(x1,y1,x2,y2)
- int x1;
- int y1;
- int x2;
- int y2;
- {
- int x, y;
-
- x = x1 - x2;
- y = y1 - y2;
- d = sqrt((x*x) + (y*y));
- return(d);
- }
-
- /* plot course function, return degree heading to */
- /* reach destination x, y; uses atan() trig function */
- plot_course(xx,yy)
- int xx, yy;
- {
- int d;
- int x,y;
- int scale;
- int curx, cury;
-
- scale = 100000; /* scale for trig functions */
- curx = loc_x(); /* get current location */
- cury = loc_y();
- x = curx - xx;
- y = cury - yy;
-
- /* atan only returns -90 to +90, so figure out how to use */
- /* the atan() value */
-
- if (x == 0) { /* x is zero, we either move due north or south */
- if (yy > cury)
- d = 90; /* north */
- else
- d = 270; /* south */
- } else {
- if (yy < cury) {
- if (xx > curx)
- d = 360 + atan((scale * y) / x); /* south-east, quadrant 4 */
- else
- d = 180 + atan((scale * y) / x); /* south-west, quadrant 3 */
- } else {
- if (xx > curx)
- d = atan((scale * y) / x); /* north-east, quadrant 1 */
- else
- d = 180 + atan((scale * y) / x); /* north-west, quadrant 2 */
- }
- }
-
-
- Page 19
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- return (d);
- }
-
-
- Notes: The distance() and plot_course() routines are quite
- handy. Save them for your programs. Also, note that the main scan
- routine will "back up" a few degrees after a target has been found
- and fired upon. This should catch robots trying to flee away from
- the direction you are scanning. If the target moves the other way,
- the normal scan increment will find it.
-
- See the other sample CRobots program files.
-
-
- _1_0_. _C_R_o_b_o_t_s _C_P_U _A_r_c_h_i_t_e_c_t_u_r_e _a_n_d _T_h_e_o_r_y
-
- This information is provided if you need to use the debug
- facility, or are curious about the virtual machine interpreter.
- Don't bother reading this section if you are not so inclined; it is
- not needed for normal play.
-
- _1_0_-_1_. _S_t_a_c_k _u_s_a_g_e_:
-
- The stack is controlled implicitly by several pointers. Stack
- pointers are not accessible through machine instructions. Most
- instructions will either push data onto the stack, or pop data off
- the stack. The stack is used from the bottom up (low memory) for
- data and temporary storage, and is used from the top down (high
- memory) for saving stack pointers and the program counter on
- function call/return.
-
- External (global) variables are allocated at the very bottom of
- the stack, and the local mark pointer for 'main' starts just after
- the externals. External variables are addressed from the beginning
- of the stack, by offset.
-
- When a function is called (including 'main'), the stack pointer
- is marked (local mark) and is increased by the number of local
- variables needed for that function. Local variables are addressed
- relative to the local mark, by offsets. All calculations, function
- calls, and constants are pushed on and popped off the stack as
- needed (temporary mark or top of stack).
-
- A function call also saves its current stack pointers (local
- variable mark and frame mark) and program counter. This return
- information grows from the top down.
-
- Arguments are passed to functions by value. The first argument
- in a function call becomes the first local variable for the called
- function. Consider the following:
-
- main() /* main has three local variables: */
-
-
- Page 20
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- {
- int a, b, c;
- ....;
- sub1 (a,b/2,c+1); /* call sub1, and pass arguments */
- ....;
- }
-
- sub1 (x,y,z) /* sub1 takes three parameters and */
- int x, y, z; /* has one local variable */
- {
- int result;
- result = x + y + z;
- return (result);
- }
-
- The main() function allocates three local variables on the
- stack, sets its local mark at 'a', and sets the temporary stack
- pointer beyond the locals. Just before sub1() is called, the value
- of 'a' is pushed, followed by the result of 'b/2', and 'c+1'. When
- sub1() is called, it sets its local mark where the value of 'a' is,
- so that 'a' is known as 'x' in func1(), likewise 'b/2' is known as
- 'y' and 'c+1' is known as 'z'. Sub1() also allocates one more word
- for 'result', and sets the temporary mark after the storage for
- 'result'.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 21
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- The following diagram illustrates the stack usage:
-
- +------------+ <-- end of stack, high memory
- |main return | <-- return info for main
- +------------+ (frame,ip,local mark)
- |sub1 return | <-- return info for sub1
- +------------+ (etc.)
- | | |
- | v | <-- additional function call return
- | | info grow downwards
- | |
- | |
- | |
- | ^ | <-- additional function calls and
- | | | expressions grow upwards
- |expressions |
- +------------+ <-- temporary mark (top of stack)
- |sub1 locals |
- +------------+ <-- local mark: sub1 function
- |main locals |
- +------------+ <-- local mark: main function
- | |
- | Externals |
- | |
- +------------+ <-- beginning of stack
-
-
- _1_0_-_2_. _L_i_n_k _l_i_s_t
-
- The link list is a list built by the compiler that contains the
- names and link information of the functions within the program. The
- link information contains the starting location of the function
- within the code, the number of parameters, and the number of other
- local variables within the function. The link list cannot be
- accessed by the user program.
-
- _1_0_-_3_. _I_n_s_t_r_u_c_t_i_o_n _s_e_t
-
- The CRobots cpu has 10 instructions. Each instruction occupies
- the same amount of storage, with or without operands.
-
- FETCH offset (external | local) - Fetch will retrieve a word from
- either the external variable pool or the local variable pool
- and push it onto the stack. The offset has its high-bit set
- (or'ed with 0x8000) if it is an external (offset from the
- beginning of the stack), otherwise it is a local (offset from
- the local variable mark). See STORE.
-
- STORE offset (external | local), opcode - Store pops the top two
- items, applies the arithmetic opcode to the two operands,
- pushes the result on the top of the stack and stores it in the
- variable referenced by the offset. Offsets are either external
-
-
- Page 22
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- or local, according to the method described in Fetch. The
- result of the opcode is left on the stack. See FETCH and
- BINOP.
-
- CONST k - Const will push a constant onto the stack.
-
- BINOP opcode - Binop will pop the top two items as top of stack =
- y, next to top of stack as x, apply the arithmetic opcode as
- (x opcode y), and push the result on the stack. Opcodes are
- decimal representations of 'C' operators such as '+', '/',
- '>=', etc. See STORE.
-
- FCALL link-offset - Fcall performs a high level function call
- facility. The link-offset operand specifies an entry in the
- link list table. Fcall pushes its return information: the
- next instruction counter and the current local variable mark.
- A new local variable mark and temporary mark (top of stack
- pointer) is set. The cpu then branches to the first
- instruction of the function. See RETSUB and FRAME.
-
- RETSUB - Retsub returns from a function, leaving the return value
- on the top of the stack. Retsub restores the previous local
- variable pool, the next instruction counter, and re-adjusts
- the stack frame to the point just before the call. The C
- compiler generates code to return a dummy value if the
- function does not explicitly return one. See FCALL and FRAME.
-
- BRANCH instruction - Branch pops the top of the stack and branches
- to the instruction if the value is zero. The next sequential
- instruction is executed if the value is anything other than
- zero.
-
- CHOP - Chop discards the top of the stack by popping it into
- oblivion.
-
- FRAME - Frame facilitates fcall/retsub by saving the current top of
- stack pointer (temporary mark) in anticipation of a fcall
- statement. The top of stack pointer is saved in the
- call/return stack as a frame marker. See FCALL and RETSUB.
-
- NOP - No operation. Is used as a mark indicating the end of code.
-
- _1_0_-_4_. _M_a_c_h_i_n_e _l_e_v_e_l _d_e_b_u_g_g_i_n_g
-
- Debug mode is used to trace by single stepping machine
- instructions. Use this only if you need to see your program
- execute, or are just curious.
-
- First, get a listing on paper of a compile with full information
- by using the 'COMPILE TO' option:
- A>crobots COMPILE TO prt: yourpgm.r
-
-
-
- Page 23
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- Next, start CRobots again with the 'DEBUG' flag:
- A>crobots DEBUG yourpgm.r
-
- Your robot will be placed randomly in the field, and a target
- robot will be placed at the center of the field (x=500,y=500) so
- your robot program can find and shoot at a target.
-
- The virtual machine interpreter will single step through your
- program (machine instructions, that is). At every instruction, a
- machine instruction is disassembled, and the top of stack pointer
- and value are printed. The top of stack and value are after the
- results of the instruction. Other information may also be printed,
- such as function calls searching the link list, etc.
-
- On every step, you are prompted "d,h,q,<cr>:". Entering 'd' will
- dump external and local variable pools, as well as vital
- information of your robot: coordinates, heading, speed, damage,
- etc., and the status of any missiles your robot may have fired.
- Entering 'h' will simulate your robot taking a 10% damage hit, so
- you can check damage detection, etc. Entering 'q' will quit the
- program immediately, and return you to AmigaDOS. A carriage return
- alone will continue the stepping process. All responses ('d','h',
- or 'q') should be in lower case only. You should refer to the
- compile listing for offsets into the external and local variable
- pools, C code, etc.
-
- _1_1_. _I_m_p_l_e_m_e_n_t_a_t_i_o_n _n_o_t_e_s
-
- CRobots is written entirely in 'C'. The compiler section was
- developed with the aid of the Unix* (TM) programs 'yacc' and 'lex'.
- Yacc (yet another compiler-compiler) accepts a 'grammar', which
- describes the CRobots 'C' language. Yacc produces a 'C' function
- known as a parser. The parser is the heart of the compiler,
- recognizing valid 'C' constructs. Lex (lexical analyzer) accepts a
- list of token combinations, and produces a 'C' function to scan the
- compiler input for the tokens. The yacc generated parser,
- yyparse(), repeatedly calls the lex generated analyzer, yylex(), to
- process the source program. The initial screen display routines
- were developed with the 'curses' screen library.
-
- The 'C' source code was then ported to MS-DOS** (TM), and
- recompiled using the Lattice*** (TM) 2.15E compiler, using the
- 'small' memory model. The screen display functions were modified to
- use 'int86()', accessing the rom INT 10H cursor positioning
- functions in the IBM-PC bios.
-
- After it was ported to MS-DOS it was effectively abandoned by
- Tom Poindexter, and at this time all attempts to contact him have
- failed. I (David Wright) got a copy of it which had been ported to
- the Amiga almost 2 years ago, and have been tracking down the
- source code ever since. In September of 1989 I was finally able to
- get the source (for the IBM/Unix version) and re-port it to the
-
-
- Page 24
-
-
- Tom Poindexter '85 David Wright '89-90
-
-
- Amiga. At my first release it was still text based, but supported
- the ARP command line handler, stack handler, and file requesters.
-
- My next release included robots, explosions, and pulses as BOBs,
- and 2 custom graphics screens. I also added the ability to
- pre-compile the robots, so that they may be given out without the
- source code for competition, and so that a win/loss ratio can be
- encoded into the file. I also want to create a standalone robot
- factory and test bench.
-
- Tom was asking for money to get the source code, but I am not
- going to be that strict. If you want the latest version of the
- source, send me a self-addressed, stamped envelope with a single
- floppy also included. I will copy that latest, released, version I
- have onto it, and throw in my latest version of CoreWar to boot.
-
- * Unix is a trademark of Bell Telephone Laboratories.
- ** MS-DOS is a trademark of Microsoft, Inc.
- *** Lattice is a trademark of Lattice, Inc.
- **** IBM is a trademark of International Business Machines, Inc.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 25
-
-
-
-
-
- Table of Contents
-
- 1. Distribution Agreement.................................. 1
- 2. Introduction............................................ 1
- 2-1. Description........................................ 1
- 2-2. Intended Audience.................................. 1
- 2-3. Machine requirements............................... 1
- 2-4. User Interface..................................... 2
- 3. Types of Play........................................... 2
- 4. Running CRobots......................................... 2
- 4-1. Command Line Options............................... 2
- 4-2. Examples........................................... 3
- 4-3. Running CRobots from the WorkBench................. 4
- 4-4. Workbench examples................................. 4
- 5. Game Parameters......................................... 4
- 5-1. Battlefield........................................ 4
- 5-2. Robot Offense...................................... 5
- 5-3. Robot Defense...................................... 5
- 5-4. Disabling Opponents................................ 6
- 5-5. Sample Display..................................... 7
- 5-6. Table of Time Costs................................ 7
- 6. CRobots CPU............................................. 8
- 7. CRobots C Compiler...................................... 8
- 7-1. Description........................................ 8
- 7-2. Features Missing From Standard C................... 9
- 7-3. CRobots Language................................... 9
- 7-4. Compiler Limits.................................... 11
- 7-5. Compiler Error & Warning Messages.................. 11
- 7-6. Compiler Notes:.................................... 12
- 8. CRobots Intrinsic Function Library...................... 13
- 9. CRobots C Program Structure............................. 15
- 9-1. Basic Program Structure............................ 15
- 9-2. "sniper.r"......................................... 15
- 10. CRobots CPU Architecture and Theory.................... 20
- 10-1. Stack usage....................................... 20
- 10-2. Link list......................................... 22
- 10-3. Instruction set................................... 22
- 10-4. Machine level debugging........................... 23
- 11. Implementation notes................................... 24
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - I -
-
-