home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / cellsim / v2_5 / src / celllin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-31  |  11.5 KB  |  571 lines

  1. /*****
  2.  *
  3.  * File: celllin.c
  4.  *
  5.  * Cellsim, cellular automata simulator
  6.  *
  7.  * Routines specific to linear nhoods
  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. static State  *cl, *il;            /* local single line arrays */
  59.  
  60. /* Local nhood-specific routines */
  61. int
  62.     get_address_l(), to_nhood_l(), to_index_l(), rotate_l(),
  63.     auto_l(), auto_screen_l(), learn_l();
  64.  
  65.  
  66. set_params_l()
  67. {                    /* set nhood-dependent parameters */
  68.     int     i;
  69.     N = 2 * R + 1;
  70.     TMASK = AMASK;
  71.     for (i = 1; i < N - 1; i++) {
  72.     TMASK <<= L;
  73.     TMASK |= AMASK;
  74.     }
  75.     get_address = get_address_l;
  76.     to_nhood = to_nhood_l;
  77.     to_index = to_index_l;
  78.     rotate = rotate_l;
  79.     auto_step = auto_l;
  80.     auto_screen = auto_screen_l;
  81.     learn = learn_l;
  82.  
  83.     cl = (State *) malloc(B);        /* initialize line arrays */
  84.     il = (State *) malloc(B);
  85. }
  86.  
  87.  
  88. change_image_size_l() {
  89.     if (cl) free(cl);
  90.     if (il) free(il);
  91.     cl = (State *) malloc(B);
  92.     il = (State *) malloc(B);
  93. }
  94.  
  95.  
  96. onestep_l()
  97. {
  98.     register int a;            /* array pointer vars */
  99.     register int r;            /* new neighbor offset */
  100.     register int i, j;            /* count variables */
  101.     State  *temp;            /* used for swapping */
  102.     register State value;
  103.     register lr1_nbors nbors1;
  104.     register lr2_nbors nbors2;
  105.     register lr3_nbors nbors3;
  106.     array_info_struct array_info;
  107.  
  108.     for (j = 0; j < S; j++)        /* clear state counts */
  109.     statecount[j] = 0;
  110.  
  111.     r = R;                /* initialize r offset */
  112.     a = 0;
  113.  
  114.     if (before_function) {
  115.     array_info.array = cl;
  116.     array_info.time = stime;
  117.     array_info.size = B;
  118.     array_info.parm1 = parm1;
  119.     array_info.parm2 = parm2;
  120.     before_function(&array_info);
  121.     }
  122.     
  123.     if (function) {
  124.     switch (R) {
  125.       case 1:
  126.         nbors1.parm1 = parm1;
  127.         nbors1.parm2 = parm2;
  128.         break;
  129.       case 2:
  130.         nbors2.parm1 = parm1;
  131.         nbors2.parm2 = parm2;
  132.         break;
  133.       case 3:
  134.         nbors3.parm1 = parm1;
  135.         nbors3.parm2 = parm2;
  136.         break;
  137.     }
  138.     }
  139.     /* initial left edge cell load */
  140.  
  141.     if (function) {
  142.     r = B - R;
  143.     for (i=0; i < R; i++) {
  144.         switch (R) {
  145.           case 1:
  146.         nbors1.l = cl[r];
  147.         nbors1.c = cl[(r+1)%B];
  148.         nbors1.r = cl[(r+2)%B];
  149.         nbors1.x = i;
  150.         il[i] = (unsigned char)update_function(&nbors1);
  151.         break;
  152.           case 2:
  153.         nbors2.ll = cl[r];
  154.         nbors2.l = cl[(r+1)%B];
  155.         nbors2.c = cl[(r+2)%B];
  156.         nbors2.r = cl[(r+3)%B];
  157.         nbors2.rr = cl[(r+4)%B];
  158.         nbors2.x = i;
  159.         il[i] = (unsigned char)update_function(&nbors2);
  160.         break;
  161.           case 3:
  162.         nbors3.lll = cl[r];
  163.         nbors3.ll = cl[(r+1)%B];
  164.         nbors3.l = cl[(r+2)%B];
  165.         nbors3.c = cl[(r+3)%B];
  166.         nbors3.r = cl[(r+4)%B];
  167.         nbors3.rr = cl[(r+5)%B];
  168.         nbors3.rrr = cl[(r+6)%B];
  169.         nbors3.x = i;
  170.         il[i] = (unsigned char)update_function(&nbors3);
  171.         break;
  172.         }
  173.         statecount[il[i]]++;
  174.         r = (r+1)%B;
  175.     }
  176.     for (i=R; i < B-R; i++) {
  177.         switch (R) {
  178.           case 1:
  179.         nbors1.l = cl[r];
  180.         nbors1.c = cl[r+1];
  181.         nbors1.r = cl[r+2];
  182.         nbors1.x = i;
  183.         il[i] = (unsigned char)update_function(&nbors1);
  184.         break;
  185.           case 2:
  186.         nbors2.ll = cl[r];
  187.         nbors2.l = cl[r+1];
  188.         nbors2.c = cl[r+2];
  189.         nbors2.r = cl[r+3];
  190.         nbors2.rr = cl[r+4];
  191.         nbors2.x = i;
  192.         il[i] = (unsigned char)update_function(&nbors2);
  193.         break;
  194.           case 3:
  195.         nbors3.lll = cl[r];
  196.         nbors3.ll = cl[r+1];
  197.         nbors3.l = cl[r+2];
  198.         nbors3.c = cl[r+3];
  199.         nbors3.r = cl[r+4];
  200.         nbors3.rr = cl[r+5];
  201.         nbors3.rrr = cl[r+6];
  202.         nbors3.x = i;
  203.         il[i] = (unsigned char)update_function(&nbors3);
  204.         break;
  205.         }
  206.         statecount[il[i]]++;
  207.         r++;
  208.     }
  209.     for (i = B-R; i < B; i++) {
  210.         switch (R) {
  211.           case 1:
  212.         nbors1.l = cl[r];
  213.         nbors1.c = cl[(r+1)%B];
  214.         nbors1.r = cl[(r+2)%B];
  215.         nbors1.x = i;
  216.         il[i] = (unsigned char)update_function(&nbors1);
  217.         break;
  218.           case 2:
  219.         nbors2.ll = cl[r];
  220.         nbors2.l = cl[(r+1)%B];
  221.         nbors2.c = cl[(r+2)%B];
  222.         nbors2.r = cl[(r+3)%B];
  223.         nbors2.rr = cl[(r+4)%B];
  224.         nbors2.x = i;
  225.         il[i] = (unsigned char)update_function(&nbors2);
  226.         break;
  227.           case 3:
  228.         nbors3.lll = cl[r];
  229.         nbors3.ll = cl[(r+1)%B];
  230.         nbors3.l = cl[(r+2)%B];
  231.         nbors3.c = cl[(r+3)%B];
  232.         nbors3.r = cl[(r+4)%B];
  233.         nbors3.rr = cl[(r+5)%B];
  234.         nbors3.rrr = cl[(r+6)%B];
  235.         nbors3.x = i;
  236.         il[i] = (unsigned char)update_function(&nbors3);
  237.         break;
  238.         }
  239.         statecount[il[i]]++;
  240.         r++;
  241.     }
  242.     }
  243.     else {
  244.     for (i = -R; i < 0; i++) {
  245.         a |= cl[B + i];
  246.         a <<= L;
  247.     }
  248.     a |= cl[0];                /* c */
  249.     for (i = 1; i <= R; i++) {
  250.         a <<= L;
  251.         a |= cl[i];            /* r */
  252.     }
  253.  
  254.     /* now process cell */
  255.  
  256.     if ((il[0] = value = ta[a]) == UNDEF)
  257.         return (0);
  258.     statecount[value]++;
  259.  
  260.  
  261.     /* now do remaining cells of this row */
  262.  
  263.     for (j = 1; j < B; j++) {
  264.         if (++r == B)        /* increment r, wrap if needed */
  265.         r = 0;
  266.  
  267.         a &= TMASK;
  268.         a <<= L;            /* shift left */
  269.         a |= cl[r];
  270.  
  271.         if ((il[j] = value = ta[a]) == UNDEF)
  272.         return (j);
  273.         statecount[value]++;
  274.  
  275.  
  276.     } /* central cell for loop */
  277.     }
  278.  
  279.     temp = cl;                /* swap current and image lines */
  280.     cl = il;
  281.     il = temp;
  282.  
  283.     if (after_function) {
  284.     array_info.array = cl;
  285.     array_info.time = stime;
  286.     array_info.size = B;
  287.     array_info.parm1 = parm1;
  288.     array_info.parm2 = parm2;
  289.     after_function(&array_info);
  290.     }
  291.     
  292.     if (SOCKET_INUSE)
  293.     send_sock();
  294.  
  295.     return (-1);            /* success return value */
  296.  
  297. } /* onestep_l */
  298.  
  299.  
  300. auto_l(step)
  301.     int     step;            /* cycle counter */
  302.  
  303. {
  304.     int     j, k;            /* count variables */
  305.     int     ret;
  306.  
  307.     /* initialize top line, current line from bottom line */
  308.  
  309.     for (k = 1; k <= step; k++) {
  310.     for (j = 0; j < B; j++) {
  311.         ia[ABASE + j] = ca[ABASE + j];    /* copy to backup array */
  312.         cl[j] = ca[BSQR + j];
  313.     }
  314.  
  315.     ret = onestep_l();
  316.     if (ret != -1)
  317.         return (BSQR + ret);
  318.  
  319.     /* now go back and copy into current array */
  320.  
  321.     for (j = 0; j < B; j++) {
  322.         ca[ABASE + j] = cl[j];
  323.     }
  324.     vshift_data(-1);        /* shift current and image arrays */
  325.     swap_data();
  326.     vshift_data(-1);
  327.     swap_data();
  328.     } /* for k */
  329.     show_time(stime += step);        /* now inc time */
  330.  
  331.  
  332.     /* that's it for this time through the array */
  333.  
  334.     return (0);
  335.  
  336. } /* auto_l */
  337.  
  338.  
  339.  
  340. auto_screen_l(step)
  341.     int     step;            /* cycle counter */
  342.  
  343. {
  344.     register int a, cp, ip;        /* array pointer vars */
  345.     register int r;            /* new neighbor offset */
  346.     int     i, j, k;            /* count variables */
  347.     int     ret;
  348.  
  349.     /* initialize top line, current line from bottom line */
  350.     for (k = 1; k <= step; k++) {
  351.  
  352.     for (i = 0; i < B; i++) {
  353.         ia[ABASE + i] = ca[ABASE + i];    /* copy to backup array */
  354.         cl[i] = ca[ABASE + i] = ca[BSQR + i];
  355.     }
  356.  
  357.     /* now traverse the array */
  358.  
  359.     cp = 0;                /* preset cell ptrs */
  360.     ip = cp + B;
  361.  
  362.     for (i = 1; i < RCOUNT; i++) {
  363.  
  364.         cp += B;
  365.         ip += B;
  366.  
  367.  
  368.         ret = onestep_l();
  369.         if (ret != -1)
  370.         return (cp + ret);
  371.  
  372.  
  373.         /* now go back and copy into current array */
  374.  
  375.         for (j = 0; j < B; j++) {
  376.         ia[ip + j] = ca[ip + j];    /* store backup */
  377.         ca[ip + j] = cl[j];
  378.         }
  379.  
  380.     } /* row for loop */
  381.  
  382.     /* now inc time */
  383.  
  384.     } /* for k */
  385.     stime += BM1 * step;
  386.     show_time(stime);
  387.  
  388.     /* that's it for this time through the array */
  389.  
  390.     return (0);
  391.  
  392. } /* auto_screen_l */
  393.  
  394.  
  395.  
  396. learn_l()
  397. {
  398.     int     a, cp, ip;            /* array pointer vars   */
  399.     int     r;                /* new neighbor offset */
  400.     int     i, x, y;            /* count variables      */
  401.  
  402.  
  403.     /* now traverse the array */
  404.  
  405.     ip = BSQR;                /* preset cell ptrs */
  406.     cp = ip - B;
  407.  
  408.     r = cp + R;                /* initialize r offset */
  409.  
  410.     a = 0;
  411.     x = 0;
  412.     y = BM1;
  413.  
  414.     /* initial left edge cell load */
  415.  
  416.     for (i = -R; i < 0; i++) {
  417.     a += ca[cp + B + i];
  418.     a <<= L;
  419.     }
  420.     a += ca[cp];            /* c */
  421.     for (i = 1; i <= R; i++) {
  422.     a <<= L;
  423.     a += ca[cp + i];        /* r */
  424.     }
  425.  
  426.     /* now process cell */
  427.  
  428.     if (!(derive(x, y, a, &ca[ip])))
  429.     return;
  430.  
  431.  
  432.     /* now do remaining cells of this row */
  433.  
  434.     for (x = 1; x < B; x++) {
  435.  
  436.     cp++;
  437.     ip++;
  438.     if (++r == B)            /* increment r, wrap if needed */
  439.         r = 0;
  440.  
  441.     a &= TMASK;
  442.     a <<= L;
  443.     a += ca[r];
  444.  
  445.     if (!(derive(x, y, a, &ca[ip])))
  446.         return;
  447.  
  448.     } /* central cell for loop */
  449.  
  450.  
  451.     for (x = 0; x < B; x++)
  452.     ca[ABASE + x] = ca[BSQR + x];
  453.     vshift_data(-1);
  454.     display_image();
  455.  
  456. } /* learn_l() */
  457.  
  458.  
  459. to_nhood_l(a, buf)        /* linear t-table index to ascii string */
  460.     int     a;
  461.     char    buf[];
  462. {
  463.     uncnvrt(a, buf);            /* integer to string */
  464.  
  465.     /* that's all, no further conversion needed */
  466. } /* to_nhood_l */
  467.  
  468.  
  469. int
  470. to_index_l(nhood)            /* encode t-table index of ascii nhood */
  471.     char    nhood[];
  472. {
  473.     int     k;
  474.     for (k = 0; k < N; k++)        /* check for input errors */
  475.     if (!is_state(nhood[k]))
  476.         return (TABLE_ERR);
  477.  
  478.     return (cnvrt(nhood));        /* no other conversion needed */
  479. } /* to_index_l */
  480.  
  481.  
  482. rotate_l(nhood)                /* rotate ascii nhood 180 degrees */
  483.     char    nhood[];
  484. {
  485.     char    temp;
  486.     int     i;
  487.     for (i = 0; i < R; i++) {
  488.     temp = nhood[i];
  489.     nhood[i] = nhood[N - 1 - i];    /* l <- r */
  490.     nhood[N - 1 - i] = temp;    /* r <- l */
  491.     }
  492. } /* rotate_l */
  493.  
  494.  
  495. get_address_l(x, y)            /* get index at given ca location */
  496.     short   x, y;
  497. {
  498.     int     a, cp, i;
  499.  
  500.     a = 0;
  501.     cp = y * B + x + ABASE;
  502.  
  503.     for (i = -R; i < 0; i++) {
  504.     a += ca[x + i < 0 ? cp + B + i : cp + i];
  505.     a <<= L;
  506.     }
  507.     a += ca[cp];            /* c */
  508.     for (i = 1; i <= R; i++) {
  509.     a <<= L;
  510.     a += ca[x + i > BM1 ? cp - B + i : cp + i];    /* r */
  511.     }
  512.  
  513.     return (a);
  514.  
  515. } /* get_address_l */
  516.  
  517.  
  518.  
  519. get_nbors_l(nb, x, y)            /* get nbors at given ca location */
  520. unsigned char *nb;
  521. short   x, y;
  522. {
  523.     int     cp, i;
  524.     lr1_nbors *nb1;
  525.     lr2_nbors *nb2;
  526.     lr3_nbors *nb3;
  527.  
  528.     cp = y * B + x + ABASE;
  529.  
  530.     switch (R) {
  531.       case 1:
  532.     nb1 = (lr1_nbors *) nb;
  533.     nb1->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1];    /* l */
  534.     nb1->c = ca[cp];                    /* c */
  535.     nb1->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1];    /* r */
  536.     nb1->time = stime;
  537.     nb1->x = x;
  538.     nb1->parm1 = parm1;
  539.     nb1->parm2 = parm2;
  540.     break;
  541.       case 2:
  542.     nb2 = (lr2_nbors *) nb;
  543.     nb2->ll = ca[x-2 < 0 ? cp + B - 2 : cp - 2];    /* ll */
  544.     nb2->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1];    /* l */
  545.     nb2->c = ca[cp];                    /* c */
  546.     nb2->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1];    /* r */
  547.     nb2->rr = ca[x+2 > BM1 ? cp - B + 2 : cp + 2];    /* rr */
  548.     nb2->time = stime;
  549.     nb2->x = x;
  550.     nb2->parm1 = parm1;
  551.     nb2->parm2 = parm2;
  552.     break;
  553.       case 3:
  554.     nb3 = (lr3_nbors *)nb;
  555.     nb3->lll = ca[x-3 < 0 ? cp + B - 3 : cp - 3];    /* lll */
  556.     nb3->ll = ca[x-2 < 0 ? cp + B - 2 : cp - 2];    /* ll */
  557.     nb3->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1];    /* l */
  558.     nb3->c = ca[cp];                    /* c */
  559.     nb3->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1];    /* r */
  560.     nb3->rr = ca[x+2 > BM1 ? cp - B + 2 : cp + 2];    /* rr */
  561.     nb3->rrr = ca[x+3 > BM1 ? cp - B + 3 : cp + 3];    /* rrr */
  562.     nb3->time = stime;
  563.     nb3->x = x;
  564.     nb3->parm1 = parm1;
  565.     nb3->parm2 = parm2;
  566.     break;
  567.     }
  568.     return;
  569.  
  570. } /* get_nbors_l */
  571.