home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / cellsim / v2_5 / src / cellmoor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-26  |  11.6 KB  |  525 lines

  1. /*****
  2.  *
  3.  * File: cellmoore.c
  4.  *
  5.  * Cellsim, cellular automata simulator
  6.  *
  7.  * Routines specific to Moore nhood
  8.  *
  9.  *****/
  10.  
  11. #include "cellnborhoods.h"
  12.  
  13. /*
  14.  *
  15.  * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
  16.  * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
  17.  *
  18.  * This package may be freely distributed, as long as you don't:
  19.  * - remove this notice
  20.  * - try to make money by doing so
  21.  * - prevent others from copying it freely
  22.  * - distribute modified versions without clearly documenting your changes
  23.  *   and notifying us
  24.  *
  25.  * Please contact either of the authors listed above if you have questions
  26.  * or feel an exception to any of the above restrictions is in order.
  27.  *
  28.  * If you make changes to the code, or have suggestions for changes,
  29.  * let us know!  If we use your suggestion, you will receive full credit
  30.  * of course.
  31.  */
  32.  
  33. /*****
  34.  * Cellsim history:
  35.  *
  36.  * Cellsim was originally written on Apollo workstations by Chris Langton.
  37.  *
  38.  * Sun versions:
  39.  *
  40.  * - version 1.0
  41.  *   by C. Ferenbaugh and C. Langton
  42.  *   released 09/02/88
  43.  *
  44.  * - version 1.5
  45.  *   by Dave Hiebeler and C. Langton  May - June 1989
  46.  *   released 07/03/89
  47.  *
  48.  * - version 2.0
  49.  *   by Dave Hiebeler and C. Langton  July - August 1989
  50.  *   never officially released (unofficially released 09/08/89)
  51.  *
  52.  * - version 2.5
  53.  *   by Dave Hiebeler and C. Langton  September '89 - February 1990
  54.  *   released 02/26/90
  55.  *****/
  56.  
  57.  
  58. /* Local nhood-specific routines */
  59. int 
  60.     get_address_m(), to_nhood_m(), to_index_m(), rotate_m(),
  61.     auto_m(), learn_m();
  62.  
  63.  
  64. set_params_m()
  65. {                    /* set nhood-dependent parameters */
  66.     N = 9;
  67.     TMASK = AMASK | (AMASK << L) | (AMASK << (2 * L));
  68.     TMASK |= (TMASK << (3 * L));
  69.     get_address = get_address_m;
  70.     to_nhood = to_nhood_m;
  71.     to_index = to_index_m;
  72.     rotate = rotate_m;
  73.     auto_screen = auto_step = auto_m;
  74.     learn = learn_m;
  75. }
  76.  
  77.  
  78. auto_m(step)                /* run the automaton <step> steps */
  79.     int     step;
  80.  
  81. {
  82.     /* local variables */
  83.     register unsigned char *cptr, *iptr;/* ptrs to arrays */
  84.     register unsigned char *taa;    /* ptr to t-func array  */
  85.  
  86.  
  87.     register int a;            /* array pointer vars */
  88.     int     i, k;
  89.     register int j;            /* count vars */
  90.     register State value;
  91.     /* register */ int *sc;
  92.     register char l = L;
  93.     register int pb = B, mb = -B;
  94.     register moore_nbors nbors;
  95.     array_info_struct array_info;
  96.  
  97.     /* process the array "step" times */
  98.  
  99.     if (function) {
  100.     nbors.parm1 = (cell_value)parm1;
  101.     nbors.parm2 = (cell_value)parm2;
  102.     nbors.time = (cell_value)stime;
  103.     }
  104.     for (k = 0; k < step; k++) {
  105.  
  106.     if (before_function) {
  107.         array_info.array = ca;
  108.         array_info.time = stime;
  109.         array_info.size = B;
  110.         array_info.parm1 = parm1;
  111.         array_info.parm2 = parm2;
  112.         before_function(&array_info);
  113.     }
  114.     
  115.     cptr = ca;            /* load register copies */
  116.     iptr = ia;
  117.     taa = ta;
  118.     sc = statecount;
  119.  
  120.     for (j = 0; j < S; j++)        /* clear state counts */
  121.         sc[j] = 0;
  122.  
  123.     /* first - initialize top and bottom "wrap" buffers */
  124.  
  125.     for (i = 0; i < B; i++) {
  126.         cptr[i] = cptr[BSQR + i];
  127.         cptr[BBUF + i] = cptr[ABASE + i];
  128.     }
  129.  
  130.     /* now - traverse the array row by row */
  131.  
  132.     cptr = &ca[BM1];        /* preset cell pointer */
  133.     iptr = &ia[BM1];
  134.  
  135.     for (i = 0; i < RCOUNT; i++) {
  136.  
  137.         /* initialize neighbor pointers */
  138.  
  139.         cptr++;
  140.         iptr++;
  141.         a = 0;
  142.  
  143.         /* now - do the left edge cell load */
  144.  
  145.         if (function) {
  146.         nbors.tl = (cell_value)cptr[-1];
  147.         nbors.l = (cell_value)cptr[pb - 1];
  148.         nbors.bl = (cell_value)cptr[TBM1];
  149.         nbors.t = (cell_value)cptr[mb];
  150.         nbors.c = (cell_value)cptr[0];
  151.         nbors.b = (cell_value)cptr[pb];
  152.         nbors.tr = (cell_value)cptr[mb + 1];
  153.         nbors.r = (cell_value)cptr[1];
  154.         nbors.br = (cell_value)cptr[pb + 1];
  155.         nbors.x = (cell_value)0;
  156.         nbors.y = (cell_value)i;
  157.         *iptr = value = (unsigned char)update_function(&nbors);
  158.         }
  159.         else {
  160.         a |= cptr[-1];        /* tl wrap */
  161.         a <<= l;
  162.         a |= cptr[pb - 1];        /* l  wrap */
  163.         a <<= l;
  164.         a |= cptr[TBM1];        /* bl wrap */
  165.         a <<= l;
  166.         a |= cptr[mb];        /* t     */
  167.         a <<= l;
  168.         a |= cptr[0];        /* c     */
  169.         a <<= l;
  170.         a |= cptr[pb];        /* b     */
  171.         a <<= l;
  172.         a |= cptr[mb + 1];        /* tr     */
  173.         a <<= l;
  174.         a |= cptr[1];        /* r     */
  175.         a <<= l;
  176.         a |= cptr[pb + 1];        /* br     */
  177.  
  178.         /* now get image */
  179.         if ((*iptr = value = taa[a]) == UNDEF)
  180.         return (cptr - ca);
  181.         }
  182.         sc[value]++;
  183.  
  184.         /* now do the central cells of this row */
  185.  
  186.         for (j = 2; j < pb; j++) {
  187.  
  188.         cptr++;
  189.         iptr++;
  190.  
  191.         if (function) {
  192.             nbors.tl = (cell_value)cptr[mb - 1];
  193.             nbors.l = (cell_value)cptr[-1];
  194.             nbors.bl = (cell_value)cptr[pb - 1];
  195.             nbors.t = (cell_value)cptr[mb];
  196.             nbors.c = (cell_value)cptr[0];
  197.             nbors.b = (cell_value)cptr[pb];
  198.             nbors.tr = (cell_value)cptr[mb + 1];
  199.             nbors.r = (cell_value)cptr[1];
  200.             nbors.br = (cell_value)cptr[pb + 1];
  201.             nbors.x = (cell_value)j-1;
  202.             /* nbors.y doesn't need to be changed */
  203.             *iptr = value = (unsigned char)update_function(&nbors);
  204.         }
  205.         else {
  206.         a &= TMASK;
  207.         a <<= l;
  208.         a |= cptr[mb + 1];
  209.         a <<= l;
  210.         a |= cptr[1];
  211.         a <<= l;
  212.         a |= cptr[pb + 1];
  213.  
  214.         if ((*iptr = value = taa[a]) == UNDEF)
  215.             return (cptr - ca);
  216.         }
  217.         sc[value]++;
  218.  
  219.         } /* central cell for loop */
  220.  
  221.         /* and now do the right edge cell */
  222.  
  223.         cptr++;
  224.         iptr++;
  225.  
  226.         if (function) {
  227.         nbors.tl = (cell_value)cptr[mb - 1];
  228.         nbors.l = (cell_value)cptr[-1];
  229.         nbors.bl = (cell_value)cptr[pb - 1];
  230.         nbors.t = (cell_value)cptr[mb];
  231.         nbors.c = (cell_value)cptr[0];
  232.         nbors.b = (cell_value)cptr[pb];
  233.         nbors.tr = (cell_value)cptr[-TBM1];
  234.         nbors.r = (cell_value)cptr[mb + 1];
  235.         nbors.br = (cell_value)cptr[1];
  236.         nbors.x = (cell_value)pb - 1;
  237.         /* nbors.y still doesn't need to be changed */
  238.         *iptr = value = (unsigned char)update_function(&nbors);
  239.         }
  240.         else {
  241.         a &= TMASK;
  242.         a <<= l;
  243.         a |= cptr[-TBM1];        /* wrap tr */
  244.         a <<= l;
  245.         a |= cptr[mb + 1];        /* wrap r  */
  246.         a <<= l;
  247.         a |= cptr[1];        /* wrap br */
  248.  
  249.         if ((*iptr = value = taa[a]) == UNDEF)
  250.             return (cptr - ca);
  251.         }
  252.         sc[value]++;
  253.  
  254.         /* that's all for this row */
  255.  
  256.     } /* row for loop */
  257.  
  258.     /* that's all for the array */
  259.     /* now increment time and swap current and image arrays */
  260.  
  261.     if (after_function) {
  262.         array_info.array = ia;
  263.         array_info.time = stime;
  264.         array_info.size = B;
  265.         array_info.parm1 = parm1;
  266.         array_info.parm2 = parm2;
  267.         after_function(&array_info);
  268.     }
  269.     
  270.     swap_data();            /* image array is now current */
  271.  
  272.     show_time(++stime);        /* advance time */
  273.  
  274.     if (SOCKET_INUSE)
  275.         send_sock();
  276.  
  277.     
  278.     } /* step for loop */
  279.  
  280.  
  281.     return (0);
  282.  
  283. } /* auto_m */
  284.  
  285.  
  286.  
  287. int 
  288. to_index_m(nhood)            /* encode t-table index of ascii nhood */
  289.     char    nhood[];
  290.  
  291. {
  292.     int     i;
  293.  
  294.     for (i = 0; i < N; i++)        /* check for input errors */
  295.     if (!is_state(nhood[i]))
  296.         return (TABLE_ERR);
  297.  
  298.     /* encoding for Moore neighborhood */
  299.  
  300.     string[0] = nhood[1];        /* tl     */
  301.     string[1] = nhood[8];        /* l     */
  302.     string[2] = nhood[7];        /* bl     */
  303.     string[3] = nhood[2];        /* t     */
  304.     string[4] = nhood[0];        /* c   */
  305.     string[5] = nhood[6];        /* b     */
  306.     string[6] = nhood[3];        /* tr     */
  307.     string[7] = nhood[4];        /* r     */
  308.     string[8] = nhood[5];        /* br  */
  309.  
  310.     return (cnvrt(string));        /* convert index string to int */
  311.  
  312. } /* to_index_m */
  313.  
  314.  
  315.  
  316. rotate_m(nhood)                /* rotate ascii nhood 90 degrees */
  317.     char    nhood[];
  318. {
  319.     char    temp;
  320.     temp = nhood[8];
  321.     nhood[8] = nhood[6];        /* b -> l */
  322.     nhood[6] = nhood[4];        /* r -> b */
  323.     nhood[4] = nhood[2];        /* t -> r */
  324.     nhood[2] = temp;            /* l -> t */
  325.     temp = nhood[7];
  326.     nhood[7] = nhood[5];        /* br -> bl */
  327.     nhood[5] = nhood[3];        /* tr -> br */
  328.     nhood[3] = nhood[1];        /* tl -> tr */
  329.     nhood[1] = temp;            /* bl -> tl */
  330. } /* rotate_m */
  331.  
  332.  
  333. to_nhood_m(a, buf)            /* Moore t-table index to ascii c-clock
  334.                      * string */
  335.     int     a;
  336.     char    buf[];
  337.  
  338. {
  339.     uncnvrt(a, string);            /* index string from t-table index */
  340.  
  341.     buf[0] = string[4];            /* c     */
  342.     buf[1] = string[0];            /* tl     */
  343.     buf[2] = string[3];            /* t      */
  344.     buf[3] = string[6];            /* tr     */
  345.     buf[4] = string[7];            /* r     */
  346.     buf[5] = string[8];            /* br     */
  347.     buf[6] = string[5];            /* b     */
  348.     buf[7] = string[2];            /* bl     */
  349.     buf[8] = string[1];            /* l     */
  350.     buf[9] = NULL;            /* '\0' end of string */
  351.  
  352. } /* to_nhood_m */
  353.  
  354.  
  355.  
  356.  
  357. get_address_m(x, y)            /* get index at given ca location */
  358.     unsigned short x, y;
  359. {
  360.     int     a, cp, lwrap = (x == 0 ? B : 0), rwrap = (x == BM1 ? -B : 0);
  361.  
  362.     a = 0;
  363.     cp = y * B + x + ABASE;
  364.  
  365.     a += ca[cp + lwrap - BPL1];        /* tl (wraparound if needed) */
  366.     a <<= L;
  367.     a += ca[cp + lwrap - 1];        /* l  (wraparound if needed) */
  368.     a <<= L;
  369.     a += ca[cp + lwrap + BM1];        /* bl (wraparound if needed) */
  370.     a <<= L;
  371.     a += ca[cp - B];            /* t     */
  372.     a <<= L;
  373.     a += ca[cp];            /* c     */
  374.     a <<= L;
  375.     a += ca[cp + B];            /* b     */
  376.     a <<= L;
  377.     a += ca[cp + rwrap - BM1];        /* tr (wraparound if needed) */
  378.     a <<= L;
  379.     a += ca[cp + rwrap + 1];        /* r  (wraparound if needed) */
  380.     a <<= L;
  381.     a += ca[cp + rwrap + BPL1];        /* br (wraparound if needed) */
  382.  
  383.     return (a);
  384.  
  385. } /* get_address_m */
  386.  
  387.  
  388.  
  389. get_nbors_m(nb,x, y)            /* get nbors at given ca location */
  390. moore_nbors *nb;
  391. unsigned short x, y;
  392. {
  393.     int     cp, lwrap = (x == 0 ? B : 0), rwrap = (x == BM1 ? -B : 0);
  394.  
  395.     cp = y * B + x + ABASE;
  396.  
  397.     nb->tl = ca[cp + lwrap - BPL1];        /* tl (wraparound if needed) */
  398.     nb->l = ca[cp + lwrap - 1];        /* l  (wraparound if needed) */
  399.     nb->bl = ca[cp + lwrap + BM1];        /* bl (wraparound if needed) */
  400.     nb->t = ca[cp - B];            /* t     */
  401.     nb->c = ca[cp];            /* c     */
  402.     nb->b = ca[cp + B];            /* b     */
  403.     nb->tr = ca[cp + rwrap - BM1];        /* tr (wraparound if needed) */
  404.     nb->r = ca[cp + rwrap + 1];        /* r  (wraparound if needed) */
  405.     nb->br = ca[cp + rwrap + BPL1];        /* br (wraparound if needed) */
  406.     nb->x = x;
  407.     nb->y = y;
  408.     nb->time = stime;
  409.     nb->parm1 = parm1;
  410.     nb->parm2 = parm2;
  411.  
  412.     return;
  413.  
  414. } /* get_nbors_m */
  415.  
  416.  
  417. learn_m()
  418. {                    /* learn trans rule for Moore nhood */
  419.     int     a, cp;            /* array pointer vars   */
  420.     int     tr, br, r;            /* new neighbor offsets */
  421.     int     i, x, y;            /* count variables      */
  422.  
  423.  
  424.     /* swap current and image arrays */
  425.  
  426.     swap_data();
  427.  
  428.     /* initialize top and bottom buffers */
  429.  
  430.     for (i = 0; i < B; i++) {
  431.     ca[i] = ca[BSQR + i];
  432.     ca[BBUF + i] = ca[ABASE + i];
  433.     }
  434.  
  435.  
  436.     /* now traverse the array */
  437.  
  438.     cp = BM1;                /* preset cell ptr */
  439.  
  440.     for (y = 0; y < RCOUNT; y++) {
  441.  
  442.     cp++;
  443.  
  444.     tr = cp - BM1;            /* initialize tr offset */
  445.     r = cp + 1;            /* initialize tr offset */
  446.     br = cp + BPL1;            /* initialize tr offset */
  447.  
  448.     a = 0;
  449.     x = 0;
  450.  
  451.     /* initial left edge cell load */
  452.  
  453.     a += ca[cp - 1];        /* tl wrap */
  454.     a <<= L;
  455.     a += ca[cp + BM1];        /* l  wrap */
  456.     a <<= L;
  457.     a += ca[cp + TBM1];        /* bl wrap */
  458.     a <<= L;
  459.     a += ca[cp - B];        /* t     */
  460.     a <<= L;
  461.     a += ca[cp];            /* c     */
  462.     a <<= L;
  463.     a += ca[cp + B];        /* b     */
  464.     a <<= L;
  465.     a += ca[tr];            /* tr     */
  466.     a <<= L;
  467.     a += ca[r];            /* r     */
  468.     a <<= L;
  469.     a += ca[br];            /* br     */
  470.  
  471.     /* now process cell */
  472.  
  473.     if (!(derive(x, y, a, &ia[cp]))) {
  474.         swap_data();
  475.         return;
  476.     }
  477.     /* now do central cells of this row */
  478.  
  479.     for (x = 1; x < BM1; x++) {
  480.  
  481.         cp++;
  482.         tr++;
  483.         r++;
  484.         br++;
  485.  
  486.         a &= TMASK;
  487.         a <<= L;
  488.         a += ca[tr];
  489.         a <<= L;
  490.         a += ca[r];
  491.         a <<= L;
  492.         a += ca[br];
  493.  
  494.         if (!(derive(x, y, a, &ia[cp]))) {
  495.         swap_data();
  496.         return;
  497.         }
  498.     } /* central cell for loop */
  499.  
  500.  
  501.     /* now do the right edge cell */
  502.  
  503.     x = BM1;
  504.  
  505.     cp++;
  506.  
  507.     a &= TMASK;
  508.     a <<= L;
  509.     a += ca[cp - TBM1];        /* wrap tr */
  510.     a <<= L;
  511.     a += ca[cp - BM1];        /* wrap r  */
  512.     a <<= L;
  513.     a += ca[cp + 1];        /* wrap br */
  514.  
  515.     if (!(derive(x, y, a, &ia[cp]))) {
  516.         swap_data();
  517.         return;
  518.     }
  519.     } /* row for loop */
  520.  
  521.     swap_data();            /* switch arrays back */
  522.     copy_data();            /* copy image to backup */
  523.  
  524. } /* learn_m */
  525.