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

  1. /*****
  2.  *
  3.  * File: cellvonn.c
  4.  *
  5.  * Cellsim, cellular automata simulator
  6.  *
  7.  * Routines specific to vonNeumann 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_v(), to_nhood_v(), to_index_v(), rotate_v(),
  61.     auto_v(), learn_v();
  62.  
  63.  
  64. /*
  65.  * Set basic nhood-specific vars and function-pointers
  66.  */
  67. set_params_v()
  68. {
  69.     N = 5;
  70.     TMASK = (AMASK << (3 * L)) | (AMASK << (2 * L));
  71.     get_address = get_address_v;
  72.     to_nhood = to_nhood_v;
  73.     to_index = to_index_v;
  74.     rotate = rotate_v;
  75.     auto_screen = auto_step = auto_v;
  76.     learn = learn_v;
  77. }
  78.  
  79.  
  80. /* transition function table access routines */
  81. /* Note:  cnvrt and uncnvrt are also called by the other neighborhood routines */
  82.  
  83. cnvrt(str)            /* convert t-table index string to int */
  84.     char    str[];        /* ptr to index string */
  85.  
  86. {
  87.     int     a, i;
  88.  
  89.     a = 0;
  90.  
  91.     for (i = 0; i < N; i++) {
  92.     a <<= L;
  93.     a += to_state(str[i]);
  94.     }
  95.  
  96.     return (a);
  97.  
  98. } /* cnvrt */
  99.  
  100.  
  101. uncnvrt(a, str)                /* index string from t-table index */
  102.     int     a;
  103.     char    str[];
  104. {
  105.     int     i;
  106.     for (i = N - 1; i >= 0; i--) {
  107.     str[i] = to_char(a & AMASK);
  108.     a >>= L;
  109.     }
  110.     str[N] = NULL;
  111. } /* uncnvrt */
  112.  
  113.  
  114. to_nhood_v(a, buf)            /* von-N t-table index to ascii c-clock
  115.                      * string */
  116.     int     a;
  117.     char    buf[];
  118.  
  119. {
  120.     uncnvrt(a, string);            /* integer to ascii */
  121.  
  122.     buf[0] = string[1];            /* c */
  123.     buf[1] = string[3];            /* t */
  124.     buf[2] = string[2];            /* r */
  125.     buf[3] = string[4];            /* b */
  126.     buf[4] = string[0];            /* l */
  127.     buf[5] = NULL;            /* '\0' end of string */
  128.  
  129. } /* to_nhood_v */
  130.  
  131.  
  132.  
  133. int 
  134. to_index_v(nhood)        /* encode t-table index of ascii nhood */
  135.     char    nhood[];
  136.  
  137. {
  138.     int     k;
  139.  
  140.     for (k = 0; k < N; k++)        /* check for input errors */
  141.     if (!is_state(nhood[k]))
  142.         return (TABLE_ERR);
  143.  
  144.     /* encoding for von-N neighborhood */
  145.  
  146.     string[0] = nhood[4];        /* l */
  147.     string[1] = nhood[0];        /* c */
  148.     string[2] = nhood[2];        /* r */
  149.     string[3] = nhood[1];        /* t */
  150.     string[4] = nhood[3];        /* b */
  151.     string[5] = NULL;
  152.  
  153.     return (cnvrt(string));
  154.  
  155. } /* to_index_v */
  156.  
  157.  
  158. rotate_v(nhood)                /* rotate ascii nhood 90 degrees */
  159.     char    nhood[];
  160. {
  161.     char    temp;
  162.     temp = nhood[4];
  163.     nhood[4] = nhood[3];        /* b -> l */
  164.     nhood[3] = nhood[2];        /* r -> b */
  165.     nhood[2] = nhood[1];        /* t -> r */
  166.     nhood[1] = temp;            /* l -> t */
  167. } /* rotate_v */
  168.  
  169.  
  170. auto_v(steps)                /* run the automaton for <steps> time steps */
  171.     int     steps;            /* cycle counter */
  172.  
  173. {
  174.     register unsigned char *cptr, *iptr;/* ptrs to arrays */
  175.  
  176.     register unsigned char *taa;    /* ptr to t-func array  */
  177.     register int a;            /* array pointer vars   */
  178.     register char l = L;        /* count variables      */
  179.     int     tmask = TMASK;
  180.     register short mb = -B, pb = B;
  181.     register short j;
  182.     register State value;
  183.     /* register */ int *sc;
  184.     register vonn_nbors nbors;
  185.     array_info_struct array_info;
  186.  
  187.     int     i, k;
  188.  
  189.     /* cycle through the array "steps" times */
  190.  
  191.     if (function) {
  192.     nbors.parm1 = parm1;
  193.     nbors.parm2 = parm2;
  194.     nbors.time = stime;
  195.     }
  196.  
  197.     for (k = 0; k < steps; k++) {
  198.  
  199.     if (before_function) {
  200.         array_info.array = ca;
  201.         array_info.time = stime;
  202.         array_info.parm1 = parm1;
  203.         array_info.parm2 = parm2;
  204.         before_function(&array_info);
  205.     }
  206.         
  207.     cptr = ca;            /* load register copies */
  208.     taa = ta;
  209.     sc = statecount;
  210.  
  211.     for (j = 0; j < S; j++)        /* clear state counts */
  212.         sc[j] = 0;
  213.  
  214.     /* initialize top and bottom buffers */
  215.  
  216.     for (i = 0; i < B; i++) {
  217.         cptr[i] = cptr[BSQR + i];
  218.         cptr[BBUF + i] = cptr[ABASE + i];
  219.     }
  220.  
  221.     /* now traverse the array */
  222.  
  223.     cptr = &ca[BM1];
  224.     iptr = &ia[BM1];
  225.  
  226.     for (i = 0; i < RCOUNT; i++) {
  227.         cptr++;
  228.         iptr++;
  229.  
  230.         a = 0;
  231.  
  232.         /* initial left edge cell load */
  233.  
  234.         if (function) {
  235.         nbors.l = cptr[pb - 1];
  236.         nbors.c = cptr[0];
  237.         nbors.r = cptr[1];
  238.         nbors.t = cptr[mb];
  239.         nbors.b = cptr[pb];
  240.         nbors.x = 0;
  241.         nbors.y = i;
  242.         *iptr = value = (unsigned char)update_function(&nbors);
  243.         }
  244.         else {
  245.  
  246.         a |= cptr[pb - 1];        /* wrap l */
  247.         a <<= l;
  248.         a |= cptr[0];        /* c  */
  249.         a <<= l;
  250.         a |= cptr[1];        /* r  */
  251.         a <<= l;
  252.         a |= cptr[mb];        /* t  */
  253.         a <<= l;
  254.         a |= cptr[pb];        /* b  */
  255.  
  256.         /* now process cell */
  257.  
  258.         if ((*iptr = value = taa[a]) == UNDEF)
  259.             return (cptr - ca);
  260.         }
  261.         sc[value]++;
  262.  
  263.  
  264.         cptr++;
  265.         iptr++;            /* now do one normal cell */
  266.  
  267.         if (function) {
  268.         nbors.l = cptr[-1];
  269.         nbors.c = cptr[0];
  270.         nbors.r = cptr[1];
  271.         nbors.t = cptr[mb];
  272.         nbors.b = cptr[pb];
  273.         nbors.x = 1;
  274.         /* nbors.y doesn't need to be changed */
  275.         *iptr = value = (unsigned char)update_function(&nbors);
  276.         }
  277.         else {
  278.         a &= tmask;
  279.         a |= (cptr[1] << l);    /* r */
  280.         a |= cptr[mb];        /* t */
  281.         a <<= l;
  282.         a |= cptr[pb];        /* b */
  283.  
  284.         if ((*iptr = value = taa[a]) == UNDEF)
  285.             return (cptr - ca);
  286.         }
  287.         sc[value]++;
  288.  
  289.  
  290.         /* now do central cells of this row, four at a time */
  291.  
  292.         for (j = 4; j < pb; j += 4) {
  293.         cptr++;
  294.         iptr++;            /***** ONE *****/
  295.  
  296.         if (function) {
  297.             nbors.l = cptr[-1];
  298.             nbors.c = cptr[0];
  299.             nbors.r = cptr[1];
  300.             nbors.t = cptr[mb];
  301.             nbors.b = cptr[pb];
  302.             nbors.x = j-2;
  303.             /* nbors.y doesn't need to be changed */
  304.             *iptr = value = (unsigned char)update_function(&nbors);
  305.         }
  306.         else {    
  307.             a &= tmask;
  308.             a |= (cptr[1] << l);    /* r */
  309.             a |= cptr[mb];        /* t */
  310.             a <<= l;
  311.             a |= cptr[pb];        /* b */
  312.             if ((*iptr = value = taa[a]) == UNDEF)
  313.             return (cptr - ca);
  314.         }
  315.         sc[value]++;
  316.  
  317.         cptr++;
  318.         iptr++;            /***** TWO *****/
  319.  
  320.         if (function) {
  321.             nbors.l = cptr[-1];
  322.             nbors.c = cptr[0];
  323.             nbors.r = cptr[1];
  324.             nbors.t = cptr[mb];
  325.             nbors.b = cptr[pb];
  326.             nbors.x = j-1;
  327.             /* nbors.y doesn't need to be changed */
  328.             *iptr = value = (unsigned char)update_function(&nbors);
  329.         }
  330.         else {
  331.             a &= tmask;
  332.             a |= (cptr[1] << l);    /* r */
  333.             a |= cptr[mb];        /* t */
  334.             a <<= l;
  335.             a |= cptr[pb];        /* b */
  336.             if ((*iptr = value = taa[a]) == UNDEF)
  337.             return (cptr - ca);
  338.         }
  339.         sc[value]++;
  340.  
  341.         cptr++;
  342.         iptr++;            /***** THREE *****/
  343.  
  344.         if (function) {
  345.             nbors.l = cptr[-1];
  346.             nbors.c = cptr[0];
  347.             nbors.r = cptr[1];
  348.             nbors.t = cptr[mb];
  349.             nbors.b = cptr[pb];
  350.             nbors.x = j;
  351.             /* nbors.y doesn't need to be changed */
  352.             *iptr = value = (unsigned char)update_function(&nbors);
  353.         }
  354.         else {
  355.             a &= tmask;
  356.             a |= (cptr[1] << l);    /* r */
  357.             a |= cptr[mb];        /* t */
  358.             a <<= l;
  359.             a |= cptr[pb];        /* b */
  360.             if ((*iptr = value = taa[a]) == UNDEF)
  361.             return (cptr - ca);
  362.         }
  363.         sc[value]++;
  364.  
  365.         cptr++;
  366.         iptr++;            /***** FOUR *****/
  367.  
  368.         if (function) {
  369.             nbors.l = cptr[-1];
  370.             nbors.c = cptr[0];
  371.             nbors.r = cptr[1];
  372.             nbors.t = cptr[mb];
  373.             nbors.b = cptr[pb];
  374.             nbors.x = j+1;
  375.             /* nbors.y doesn't need to be changed */
  376.             *iptr = value = (unsigned char)update_function(&nbors);
  377.         }
  378.         else {
  379.             a &= tmask;
  380.             a |= (cptr[1] << l);    /* r */
  381.             a |= cptr[mb];        /* t */
  382.             a <<= l;
  383.             a |= cptr[pb];        /* b */
  384.             if ((*iptr = value = taa[a]) == UNDEF)
  385.             return (cptr - ca);
  386.         }    
  387.         sc[value]++;
  388.         } /* column for loop */
  389.  
  390.         cptr++;
  391.         iptr++;            /* now do one more normal cell */
  392.         if (function) {
  393.         nbors.l = cptr[-1];
  394.         nbors.c = cptr[0];
  395.         nbors.r = cptr[1];
  396.         nbors.t = cptr[mb];
  397.         nbors.b = cptr[pb];
  398.         nbors.x = pb - 2;
  399.         /* nbors.y doesn't need to be changed */
  400.         *iptr = value = (unsigned char)update_function(&nbors);
  401.         }
  402.         else {
  403.         a &= tmask;
  404.         a |= (cptr[1] << l);    /* r */
  405.         a |= cptr[mb];        /* t */
  406.         a <<= l;
  407.         a |= cptr[pb];        /* b */
  408.         
  409.         if ((*iptr = value = taa[a]) == UNDEF)
  410.             return (cptr - ca);
  411.         }
  412.         sc[value]++;
  413.  
  414.  
  415.         cptr++;
  416.         iptr++;            /* now do the right edge cell */
  417.  
  418.         if (function) {
  419.         nbors.l = cptr[-1];
  420.         nbors.c = cptr[0];
  421.         nbors.r = cptr[mb + 1];
  422.         nbors.t = cptr[mb];
  423.         nbors.b = cptr[pb];
  424.         nbors.x = pb - 1;
  425.         /* nbors.y doesn't need to be changed */
  426.         *iptr = value = (unsigned char)update_function(&nbors);
  427.         }
  428.         else {
  429.         a &= tmask;
  430.         a |= (cptr[mb + 1] << l);    /* wrap r neighbor */
  431.         a |= cptr[mb];        /* t */
  432.         a <<= l;
  433.         a |= cptr[pb];        /* b */
  434.         
  435.         if ((*iptr = value = taa[a]) == UNDEF)
  436.             return (cptr - ca);
  437.         }
  438.         sc[value]++;
  439.  
  440.         /* that's all for this row */
  441.  
  442.     } /* row for(...) loop */
  443.     if (after_function) {
  444.         array_info.array = ia;
  445.         array_info.time = stime;
  446.         array_info.parm1 = parm1;
  447.         array_info.parm2 = parm2;
  448.         after_function(&array_info);
  449.     }
  450.  
  451.     swap_data();            /* image array is now current */
  452.  
  453.     show_time(++stime);        /* advance time */
  454.  
  455.     if (SOCKET_INUSE)
  456.         send_sock();
  457.  
  458.     }    /* steps for loop */
  459.     return 0;
  460. } /* auto_v */
  461.  
  462.  
  463. get_address_v(x, y)            /* get index at given ca location */
  464.     unsigned short x, y;
  465. {
  466.     int     a, cp;
  467.  
  468.     a = 0;
  469.     cp = y * B + x + B;
  470.  
  471.     a += ca[x == 0 ? cp + BM1 : cp - 1];/* l (wraparound if needed) */
  472.     a <<= L;
  473.     a += ca[cp];            /* c */
  474.     a <<= L;
  475.     a += ca[x == BM1 ? cp - BM1 : cp + 1];    /* r (wraparound if needed) */
  476.     a <<= L;
  477.     a += ca[cp - B];            /* t */
  478.     a <<= L;
  479.     a += ca[cp + B];            /* b */
  480.  
  481.     return (a);
  482.  
  483. } /* get_address_v */
  484.  
  485.  
  486.  
  487. get_nbors_v(nb, x, y)            /* get nbors at given ca location */
  488. vonn_nbors *nb;
  489. unsigned short x, y;
  490. {
  491.     int     cp;
  492.  
  493.     cp = y * B + x + B;
  494.  
  495.     nb->l = ca[x == 0 ? cp + BM1 : cp - 1];/* l (wraparound if needed) */
  496.     nb->c = ca[cp];            /* c */
  497.     nb->r = ca[x == BM1 ? cp - BM1 : cp + 1];    /* r (wraparound if needed) */
  498.     nb->t = ca[cp - B];            /* t */
  499.     nb->b = ca[cp + B];            /* b */
  500.     nb->x = x;
  501.     nb->y = y;
  502.     nb->parm1 = parm1;
  503.     nb->parm2 = parm2;
  504.     nb->time = stime;
  505.  
  506.     return;
  507.  
  508. } /* get_nbors_v */
  509.  
  510.  
  511. learn_v()
  512. {                    /* learn trans rule for VonNeumann
  513.                      * nhood */
  514.     int     a, cp;            /* array pointer vars   */
  515.     int     r, t, b;            /* new neighbor offsets */
  516.     int     i, x, y;            /* count variables      */
  517.  
  518.  
  519.     /* swap current and image arrays */
  520.  
  521.     swap_data();
  522.  
  523.     /* initialize top and bottom buffers */
  524.  
  525.     for (i = 0; i < B; i++) {
  526.     ca[i] = ca[BSQR + i];
  527.     ca[BBUF + i] = ca[ABASE + i];
  528.     }
  529.  
  530.  
  531.     /* now traverse the array */
  532.  
  533.     cp = BM1;                /* preset cell ptr */
  534.  
  535.     for (y = 0; y < RCOUNT; y++) {
  536.  
  537.     cp++;
  538.     r = cp + 1;            /* initialize r offset */
  539.     t = cp - B;            /* initialize t offset */
  540.     b = cp + B;            /* initialize b offset */
  541.  
  542.     a = 0;
  543.     x = 0;
  544.  
  545.     /* initial left edge cell load */
  546.  
  547.     a += ca[cp + BM1];        /* wrap l */
  548.     a <<= L;
  549.     a += ca[cp];            /* c */
  550.     a <<= L;
  551.     a += ca[r];            /* r */
  552.     a <<= L;
  553.     a += ca[t];            /* t */
  554.     a <<= L;
  555.     a += ca[b];            /* b */
  556.  
  557.     /* now process cell */
  558.  
  559.     if (!(derive(x, y, a, &ia[cp]))) {
  560.         swap_data();
  561.         return;
  562.     }
  563.     /* now do central cells of this row */
  564.  
  565.     for (x = 1; x < BM1; x++) {
  566.  
  567.         cp++;
  568.         r++;
  569.         t++;
  570.         b++;
  571.  
  572.         a &= TMASK;
  573.         a += (ca[r] << L);
  574.         a += ca[t];
  575.         a <<= L;
  576.         a += ca[b];
  577.  
  578.         if (!(derive(x, y, a, &ia[cp]))) {
  579.         swap_data();
  580.         return;
  581.         }
  582.     } /* central cell for loop */
  583.  
  584.  
  585.     /* now do the right edge cell */
  586.  
  587.     x = BM1;
  588.  
  589.     cp++;
  590.     t++;
  591.     b++;
  592.  
  593.     a &= TMASK;
  594.     a += (ca[cp - BM1] << L);    /* wrap r neighbor */
  595.     a += ca[t];
  596.     a <<= L;
  597.     a += ca[b];
  598.  
  599.     if (!(derive(x, y, a, &ia[cp]))) {
  600.         swap_data();
  601.         return;
  602.     }
  603.     } /* row for loop */
  604.  
  605.     swap_data();            /* switch arrays back */
  606.     copy_data();            /* copy image to backup */
  607.  
  608. } /* learn_v */
  609.