home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / cellsim / v2_5 / doc / rule_rdm < prev    next >
Encoding:
Text File  |  1990-02-26  |  11.5 KB  |  285 lines

  1.  
  2.       Documentation for writing C code to generate Cellsim rules
  3.                  Cellsim V2.5
  4.  
  5.  
  6.            ****************************************
  7.               YOU MUST HAVE THE MAKEFILE
  8.              ("Use the Makefile, Luke!")
  9.  
  10.   To use the new method of writing your own rules, you must have a copy
  11. of the file "Makefile" (which is in the directory "Rule_src" under the
  12. "V2.5" directory of this distribution of Cellsim); you should have a copy
  13. of the "Makefile" in the same directory as your C files for the rules.
  14.  
  15.   Note also that the second line of the Makefile, the definition of MDIR,
  16. should point to the full pathname of the "Rule_mdir" directory under the
  17. Cellsim V2.5 directory.  This is necessary, so that the C compiler will
  18. know where to find the necessary include file, and the other C files it
  19. needs to generate your rules.
  20.  
  21.  
  22.            ****************************************
  23.               WRITING AN UPDATE FUNCTION
  24.  
  25.   Update functions must be written in C.
  26.  
  27.   During the following documentation, you are advised to consult the files
  28. "heat2.m256.c" and "life.m2" in the "Rule_src" directory, as examples of how
  29. to write an update-function file for both 256-state computed-function rules,
  30. and lookup-table rules.  Writing rules is really much simpler than this
  31. documentation makes it sound; looking at the examples after you've read this
  32. will clarify any confusion about the process, I hope.
  33.  
  34.   The first thing in your rule file (besides any comments) should be the line:
  35.  
  36. #include "nborhood.h"
  37.  
  38.   This will include definitions of the neighborhood structures and
  39. variables, plus a few macros to extract the neighbors from the structures
  40. for you.
  41.  
  42.   Next, you should declare all of the functions in your file.  You -must-
  43. declare your update function here.  If you are using 256 states and will
  44. be using "before" and "after" functions, you must declare them too.
  45. An example of doing this is:
  46.  
  47. byte my_update_func();
  48.  
  49.   Your update function should return a "byte", which has been typedef'ed
  50. to be an unsigned char.
  51.  
  52.   Next, if you are using 256 states, you should declare any static variables,
  53. if you want any.  For example, the heat2.m256.c rule defines:
  54.  
  55. static int hsum=0;
  56.  
  57. as a private integer it will use.
  58.  
  59.   Note that the following variable names are reserved (they are defined in
  60. the "nborhood.h" file):
  61.      tl, l, bl, t, c, b, tr, r, br, ll, rr, lll, rrr, cw, ccw, opp, phase,
  62.      x,y,time, parm1, parm2, center, north, south, east, west, northeast,
  63.      southeast, northwest, southwest, clockwise, counterclockwise, and
  64.      opposite.
  65.  
  66. So be sure you don't define your own variables that would conflict with
  67. these.
  68.  
  69.  
  70.   The first actual routine in your file must be an initialization routine,
  71. which will be called once when the rule-file is first used.  This function
  72. -must- have the name "init_function"! In this function, there is one thing
  73. you are required to do: set the value of "update_function".  When using 256
  74. states, this is necessary so that Cellsim will know what to call to update a
  75. cell's value; when using fewer states, it is necessary so that the library
  76. routines will know what function to call to generate the lookup table.
  77.   For example, an initialization function could be:
  78.  
  79. void
  80. init_function()
  81. {
  82.     update_function = my_update_func;
  83. }
  84.  
  85.   Note that there are *not* parenthesis after "my_update_func".  This is
  86. because we aren't calling my_update_func, we are using its name (actually
  87. its address) in the assignment statement.  If you accidentally say something
  88. like:  update_function = my_update_func();   then things will probably
  89. crash when you try to run.
  90.  
  91.   Note that the following names are reserved; that is, you cannot use them
  92. as the names of your own functions:
  93.  
  94.      initialization_function, update_function, before_function, after_function
  95.  
  96. Cellsim uses these names as pointers to your routines.
  97.  
  98. Note that if you are using 256 states, you can also set either or both of
  99. the global parameters in your initialization function, by simply assigning
  100. values to the variables "parm1" and "parm2".  If you are going to be doing
  101. analysis or modifications on the image array before or after each time-step,
  102. you can also set the values of the function-pointers "before_function" and
  103. "after_function", just as you did for "update_function".  See heat2.m256.c
  104. for a demonstration of this.
  105. When using lookup-table rules, setting parm1 and/or parm2 will have no effect,
  106. and trying to set either "before_function" or "after_function" will cause
  107. an error when trying to compile your routine.
  108.  
  109.  
  110.            ****************************************
  111.              THE UPDATE FUNCTION
  112.  
  113.   When using 256 states, your update function will be called for every cell
  114. in the array, every time step.  Therefore, if you run on a 64x64 array for
  115. a couple hundred time steps, your update function will be called a million
  116. times!  Because of this, you don't want to make your update function
  117. unnecessarily complicated.  When using less than 256 states, your update
  118. function will be called once for every possible neighborhood configuration,
  119. to generate the lookup table (e.g. 512 times for the "m2" neighborhood).
  120. Therefore, it's OK if your function is a little slow, since once the table
  121. has been generated, your function won't be used again.
  122.  
  123.   Your update function will receive only one parameter; it will be a
  124. pointer to a structure which contains all of the neighbors of the current
  125. cell.  If you are using 256 states, the structure will also contain the
  126. current values of parm1 and parm2, the current "time" (what time-step you
  127. are currently on, as displayed in the Cellsim control panel), and x and y
  128. coordinates of the current cell (only x coordinate, for linear neighborhoods).
  129. You must declare that parameter as the appropriate type; the possible
  130. neighborhood structures are:
  131.      moore_nbors, vonn_nbors, margolus_nbors, lr1_nbors, lr2_nbors, lr3_nbors
  132. Remember that the parameter is a pointer to a structure, so you would
  133. declare the parameter for example as:
  134.   moore_nbors *nbors;
  135. where "nbors" is the parameter to your update-funtion.
  136.  
  137.   There are macros defined to extract these neighbors from their structure
  138. and store them into local variables.  The name of the macro depends on the
  139. neighborhood.  They are:
  140.      Get_moore_nbors, Get_vonn_nbors, Get_margolus_nbors,
  141.      Get_lr1_nbors, Get_lr2_nbors, Get_lr3_nbors
  142.  
  143. You call them by treating them as a simple statement, i.e. you simply say:
  144.  
  145. Get_moore_nbors;
  146.  
  147.   That will set the Moore-neighborhood variables:
  148.  
  149. tl, l, bl, t, c, b, tr, r, br
  150.  
  151. and   parm1, parm2, x, y, time   as well, if you are using 256 states
  152.  
  153.   which your function can then use.  Note that all of these variables are
  154. integers, although they will only have 1-byte values in them.  They are
  155. integers to prevent overflow problems that arise when you do arithmetic
  156. with 1-byte (unsigned char) variables.  However, your function should
  157. still return a 1-byte value.
  158.  
  159.   The rest of your function, after you've called the appropriate macro to
  160. set the neighborhood variables, should be the actual code to compute the
  161. new value of this cell.  A simple example of computating the new value of a
  162. cell would be to add the values of the neighbors, and return the sum mod 4,
  163. assuming you are using a neighborhood with at least 4 states/cell.
  164. You wouldn't even need a local variable in your function to do this,
  165. your whole update function could look like this:
  166.  
  167. byte
  168. my_update_func(nbors)
  169. moore_nbors *nbors;
  170. {
  171.     return (tl + l + bl + t + c + b + tr + r + br) % 4;
  172. }
  173.  
  174.  
  175.   That's all there is to it.
  176.  
  177.  
  178.            ****************************************
  179.             THE BEFORE AND AFTER FUNCTIONS
  180.  
  181.   If you are using 256 states, then in addition to the update function, you
  182. can also write an analysis function to be called before the array is updated,
  183. and another one to be called after the array is updated, if you like.  These
  184. functions can be set in the initialization routine, as described above.
  185.   This feature is not available for lookup-table rules, so that they can
  186. run as fast as possible.  If you need this feature for a 4-state rule, for
  187. example "myrule.v4.c", then rename your file to "myrule.v256.c" so that it
  188. will be used as a computed-function rule rather than a lookup-table rule.
  189. This will let you use the before and after functions; your update function 
  190. will have to make sure it only returns values between 0 and 3, however, if
  191. that is what you want.
  192.   The before and after functions each receive one argument, which is a
  193. pointer to a structure containing: a pointer to the current array, the
  194. current time, the size of the array, and the two global parameters parm1
  195. and parm2.  The precise definition of this
  196. structure is:
  197.  
  198. typedef struct {
  199.     unsigned char *array;
  200.     int time;
  201.     int size;
  202.     int parm1, parm2;
  203. } array_info_struct;
  204.  
  205. The array is stored as a linear array of bytes; the first byte is the
  206. upper-left cell, the second byte is the second cell on the first row, and
  207. so on.  You can modify the contents of the array if you wish, or simply
  208. perform some data analysis and perhaps print out some numbers or store
  209. them in a file.  (You can open a file from your initialization function).
  210.  
  211.  
  212.            ****************************************
  213.            COMPILING YOUR UPDATE FUNCTIONS
  214.  
  215.   If your rule is a 256-state rule, you can simply compile your update
  216. function by saying, for example:
  217.     cc -c myrule.m256.c
  218. which will generate a file "myrule.m256.o" which you can then
  219. load into Cellsim.
  220.   However, since you already had to copy the Makefile from the "Rule_src"
  221. directory into the current directory, you can just use the "make" utility
  222. to compile your rule.  To do so, you would type:
  223.   make myrule.m256
  224. and it would generate a file "myrule.m256.sun3.o" (or sun4, if that is what
  225. you are running on).
  226.  
  227.   The Makefile will also work for non-computed-function (lookup-table) rules;
  228. for example if you had a file "myrule.v8.c", you could simply say:
  229.   make myrule.v8
  230. and it would compile your C file, along with another C file supplied as
  231. part of Cellsim, which contains the main() which loops through all possible
  232. neighborhoods.  It would then generate a temporary executable file to call
  233. your routines, generate the lookup table, and write the table out to the
  234. file "myrule.v8".  So after you've typed "make myrule.v8" there would be a
  235. file called "myrule.v8" in the current directory, which is the lookup-table
  236. file.
  237.  
  238.   You can also edit the Makefile to tell it where to deposit the lookup-tables
  239. and/or ".o" files once they have been generated.
  240.  
  241.  
  242. /*
  243.  *
  244.  * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
  245.  * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
  246.  *
  247.  * This package may be freely distributed, as long as you don't:
  248.  * - remove this notice
  249.  * - try to make money by doing so
  250.  * - prevent others from copying it freely
  251.  * - distribute modified versions without clearly documenting your changes
  252.  *   and notifying us
  253.  *
  254.  * Please contact either of the authors listed above if you have questions
  255.  * or feel an exception to any of the above restrictions is in order.
  256.  *
  257.  * If you make changes to the code, or have suggestions for changes,
  258.  * let us know!  If we use your suggestion, you will receive full credit
  259.  * of course.
  260.  */
  261.  
  262. /*****
  263.  * Cellsim history:
  264.  *
  265.  * Cellsim was originally written on Apollo workstations by Chris Langton.
  266.  *
  267.  * Sun versions:
  268.  *
  269.  * - version 1.0
  270.  *   by C. Ferenbaugh and C. Langton
  271.  *   released 09/02/88
  272.  *
  273.  * - version 1.5
  274.  *   by Dave Hiebeler and C. Langton  May - June 1989
  275.  *   released 07/03/89
  276.  *
  277.  * - version 2.0
  278.  *   by Dave Hiebeler and C. Langton  July - August 1989
  279.  *   never officially released (unofficially released 09/08/89)
  280.  *
  281.  * - version 2.5
  282.  *   by Dave Hiebeler and C. Langton  September '89 - February 1990
  283.  *   released 02/26/90
  284.  *****/
  285.