home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * File: celllin.c
- *
- * Cellsim, cellular automata simulator
- *
- * Routines specific to linear nhoods
- *
- *****/
-
- #include "cellnborhoods.h"
-
- /*
- *
- * Cellsim copyright 1989, 1990 by Chris Langton and Dave Hiebeler
- * (cgl@lanl.gov, hiebeler@heretic.lanl.gov)
- *
- * This package may be freely distributed, as long as you don't:
- * - remove this notice
- * - try to make money by doing so
- * - prevent others from copying it freely
- * - distribute modified versions without clearly documenting your changes
- * and notifying us
- *
- * Please contact either of the authors listed above if you have questions
- * or feel an exception to any of the above restrictions is in order.
- *
- * If you make changes to the code, or have suggestions for changes,
- * let us know! If we use your suggestion, you will receive full credit
- * of course.
- */
-
- /*****
- * Cellsim history:
- *
- * Cellsim was originally written on Apollo workstations by Chris Langton.
- *
- * Sun versions:
- *
- * - version 1.0
- * by C. Ferenbaugh and C. Langton
- * released 09/02/88
- *
- * - version 1.5
- * by Dave Hiebeler and C. Langton May - June 1989
- * released 07/03/89
- *
- * - version 2.0
- * by Dave Hiebeler and C. Langton July - August 1989
- * never officially released (unofficially released 09/08/89)
- *
- * - version 2.5
- * by Dave Hiebeler and C. Langton September '89 - February 1990
- * released 02/26/90
- *****/
-
-
- static State *cl, *il; /* local single line arrays */
-
- /* Local nhood-specific routines */
- int
- get_address_l(), to_nhood_l(), to_index_l(), rotate_l(),
- auto_l(), auto_screen_l(), learn_l();
-
-
- set_params_l()
- { /* set nhood-dependent parameters */
- int i;
- N = 2 * R + 1;
- TMASK = AMASK;
- for (i = 1; i < N - 1; i++) {
- TMASK <<= L;
- TMASK |= AMASK;
- }
- get_address = get_address_l;
- to_nhood = to_nhood_l;
- to_index = to_index_l;
- rotate = rotate_l;
- auto_step = auto_l;
- auto_screen = auto_screen_l;
- learn = learn_l;
-
- cl = (State *) malloc(B); /* initialize line arrays */
- il = (State *) malloc(B);
- }
-
-
- change_image_size_l() {
- if (cl) free(cl);
- if (il) free(il);
- cl = (State *) malloc(B);
- il = (State *) malloc(B);
- }
-
-
- onestep_l()
- {
- register int a; /* array pointer vars */
- register int r; /* new neighbor offset */
- register int i, j; /* count variables */
- State *temp; /* used for swapping */
- register State value;
- register lr1_nbors nbors1;
- register lr2_nbors nbors2;
- register lr3_nbors nbors3;
- array_info_struct array_info;
-
- for (j = 0; j < S; j++) /* clear state counts */
- statecount[j] = 0;
-
- r = R; /* initialize r offset */
- a = 0;
-
- if (before_function) {
- array_info.array = cl;
- array_info.time = stime;
- array_info.size = B;
- array_info.parm1 = parm1;
- array_info.parm2 = parm2;
- before_function(&array_info);
- }
-
- if (function) {
- switch (R) {
- case 1:
- nbors1.parm1 = parm1;
- nbors1.parm2 = parm2;
- break;
- case 2:
- nbors2.parm1 = parm1;
- nbors2.parm2 = parm2;
- break;
- case 3:
- nbors3.parm1 = parm1;
- nbors3.parm2 = parm2;
- break;
- }
- }
- /* initial left edge cell load */
-
- if (function) {
- r = B - R;
- for (i=0; i < R; i++) {
- switch (R) {
- case 1:
- nbors1.l = cl[r];
- nbors1.c = cl[(r+1)%B];
- nbors1.r = cl[(r+2)%B];
- nbors1.x = i;
- il[i] = (unsigned char)update_function(&nbors1);
- break;
- case 2:
- nbors2.ll = cl[r];
- nbors2.l = cl[(r+1)%B];
- nbors2.c = cl[(r+2)%B];
- nbors2.r = cl[(r+3)%B];
- nbors2.rr = cl[(r+4)%B];
- nbors2.x = i;
- il[i] = (unsigned char)update_function(&nbors2);
- break;
- case 3:
- nbors3.lll = cl[r];
- nbors3.ll = cl[(r+1)%B];
- nbors3.l = cl[(r+2)%B];
- nbors3.c = cl[(r+3)%B];
- nbors3.r = cl[(r+4)%B];
- nbors3.rr = cl[(r+5)%B];
- nbors3.rrr = cl[(r+6)%B];
- nbors3.x = i;
- il[i] = (unsigned char)update_function(&nbors3);
- break;
- }
- statecount[il[i]]++;
- r = (r+1)%B;
- }
- for (i=R; i < B-R; i++) {
- switch (R) {
- case 1:
- nbors1.l = cl[r];
- nbors1.c = cl[r+1];
- nbors1.r = cl[r+2];
- nbors1.x = i;
- il[i] = (unsigned char)update_function(&nbors1);
- break;
- case 2:
- nbors2.ll = cl[r];
- nbors2.l = cl[r+1];
- nbors2.c = cl[r+2];
- nbors2.r = cl[r+3];
- nbors2.rr = cl[r+4];
- nbors2.x = i;
- il[i] = (unsigned char)update_function(&nbors2);
- break;
- case 3:
- nbors3.lll = cl[r];
- nbors3.ll = cl[r+1];
- nbors3.l = cl[r+2];
- nbors3.c = cl[r+3];
- nbors3.r = cl[r+4];
- nbors3.rr = cl[r+5];
- nbors3.rrr = cl[r+6];
- nbors3.x = i;
- il[i] = (unsigned char)update_function(&nbors3);
- break;
- }
- statecount[il[i]]++;
- r++;
- }
- for (i = B-R; i < B; i++) {
- switch (R) {
- case 1:
- nbors1.l = cl[r];
- nbors1.c = cl[(r+1)%B];
- nbors1.r = cl[(r+2)%B];
- nbors1.x = i;
- il[i] = (unsigned char)update_function(&nbors1);
- break;
- case 2:
- nbors2.ll = cl[r];
- nbors2.l = cl[(r+1)%B];
- nbors2.c = cl[(r+2)%B];
- nbors2.r = cl[(r+3)%B];
- nbors2.rr = cl[(r+4)%B];
- nbors2.x = i;
- il[i] = (unsigned char)update_function(&nbors2);
- break;
- case 3:
- nbors3.lll = cl[r];
- nbors3.ll = cl[(r+1)%B];
- nbors3.l = cl[(r+2)%B];
- nbors3.c = cl[(r+3)%B];
- nbors3.r = cl[(r+4)%B];
- nbors3.rr = cl[(r+5)%B];
- nbors3.rrr = cl[(r+6)%B];
- nbors3.x = i;
- il[i] = (unsigned char)update_function(&nbors3);
- break;
- }
- statecount[il[i]]++;
- r++;
- }
- }
- else {
- for (i = -R; i < 0; i++) {
- a |= cl[B + i];
- a <<= L;
- }
- a |= cl[0]; /* c */
- for (i = 1; i <= R; i++) {
- a <<= L;
- a |= cl[i]; /* r */
- }
-
- /* now process cell */
-
- if ((il[0] = value = ta[a]) == UNDEF)
- return (0);
- statecount[value]++;
-
-
- /* now do remaining cells of this row */
-
- for (j = 1; j < B; j++) {
- if (++r == B) /* increment r, wrap if needed */
- r = 0;
-
- a &= TMASK;
- a <<= L; /* shift left */
- a |= cl[r];
-
- if ((il[j] = value = ta[a]) == UNDEF)
- return (j);
- statecount[value]++;
-
-
- } /* central cell for loop */
- }
-
- temp = cl; /* swap current and image lines */
- cl = il;
- il = temp;
-
- if (after_function) {
- array_info.array = cl;
- array_info.time = stime;
- array_info.size = B;
- array_info.parm1 = parm1;
- array_info.parm2 = parm2;
- after_function(&array_info);
- }
-
- if (SOCKET_INUSE)
- send_sock();
-
- return (-1); /* success return value */
-
- } /* onestep_l */
-
-
- auto_l(step)
- int step; /* cycle counter */
-
- {
- int j, k; /* count variables */
- int ret;
-
- /* initialize top line, current line from bottom line */
-
- for (k = 1; k <= step; k++) {
- for (j = 0; j < B; j++) {
- ia[ABASE + j] = ca[ABASE + j]; /* copy to backup array */
- cl[j] = ca[BSQR + j];
- }
-
- ret = onestep_l();
- if (ret != -1)
- return (BSQR + ret);
-
- /* now go back and copy into current array */
-
- for (j = 0; j < B; j++) {
- ca[ABASE + j] = cl[j];
- }
- vshift_data(-1); /* shift current and image arrays */
- swap_data();
- vshift_data(-1);
- swap_data();
- } /* for k */
- show_time(stime += step); /* now inc time */
-
-
- /* that's it for this time through the array */
-
- return (0);
-
- } /* auto_l */
-
-
-
- auto_screen_l(step)
- int step; /* cycle counter */
-
- {
- register int a, cp, ip; /* array pointer vars */
- register int r; /* new neighbor offset */
- int i, j, k; /* count variables */
- int ret;
-
- /* initialize top line, current line from bottom line */
- for (k = 1; k <= step; k++) {
-
- for (i = 0; i < B; i++) {
- ia[ABASE + i] = ca[ABASE + i]; /* copy to backup array */
- cl[i] = ca[ABASE + i] = ca[BSQR + i];
- }
-
- /* now traverse the array */
-
- cp = 0; /* preset cell ptrs */
- ip = cp + B;
-
- for (i = 1; i < RCOUNT; i++) {
-
- cp += B;
- ip += B;
-
-
- ret = onestep_l();
- if (ret != -1)
- return (cp + ret);
-
-
- /* now go back and copy into current array */
-
- for (j = 0; j < B; j++) {
- ia[ip + j] = ca[ip + j]; /* store backup */
- ca[ip + j] = cl[j];
- }
-
- } /* row for loop */
-
- /* now inc time */
-
- } /* for k */
- stime += BM1 * step;
- show_time(stime);
-
- /* that's it for this time through the array */
-
- return (0);
-
- } /* auto_screen_l */
-
-
-
- learn_l()
- {
- int a, cp, ip; /* array pointer vars */
- int r; /* new neighbor offset */
- int i, x, y; /* count variables */
-
-
- /* now traverse the array */
-
- ip = BSQR; /* preset cell ptrs */
- cp = ip - B;
-
- r = cp + R; /* initialize r offset */
-
- a = 0;
- x = 0;
- y = BM1;
-
- /* initial left edge cell load */
-
- for (i = -R; i < 0; i++) {
- a += ca[cp + B + i];
- a <<= L;
- }
- a += ca[cp]; /* c */
- for (i = 1; i <= R; i++) {
- a <<= L;
- a += ca[cp + i]; /* r */
- }
-
- /* now process cell */
-
- if (!(derive(x, y, a, &ca[ip])))
- return;
-
-
- /* now do remaining cells of this row */
-
- for (x = 1; x < B; x++) {
-
- cp++;
- ip++;
- if (++r == B) /* increment r, wrap if needed */
- r = 0;
-
- a &= TMASK;
- a <<= L;
- a += ca[r];
-
- if (!(derive(x, y, a, &ca[ip])))
- return;
-
- } /* central cell for loop */
-
-
- for (x = 0; x < B; x++)
- ca[ABASE + x] = ca[BSQR + x];
- vshift_data(-1);
- display_image();
-
- } /* learn_l() */
-
-
- to_nhood_l(a, buf) /* linear t-table index to ascii string */
- int a;
- char buf[];
- {
- uncnvrt(a, buf); /* integer to string */
-
- /* that's all, no further conversion needed */
- } /* to_nhood_l */
-
-
- int
- to_index_l(nhood) /* encode t-table index of ascii nhood */
- char nhood[];
- {
- int k;
- for (k = 0; k < N; k++) /* check for input errors */
- if (!is_state(nhood[k]))
- return (TABLE_ERR);
-
- return (cnvrt(nhood)); /* no other conversion needed */
- } /* to_index_l */
-
-
- rotate_l(nhood) /* rotate ascii nhood 180 degrees */
- char nhood[];
- {
- char temp;
- int i;
- for (i = 0; i < R; i++) {
- temp = nhood[i];
- nhood[i] = nhood[N - 1 - i]; /* l <- r */
- nhood[N - 1 - i] = temp; /* r <- l */
- }
- } /* rotate_l */
-
-
- get_address_l(x, y) /* get index at given ca location */
- short x, y;
- {
- int a, cp, i;
-
- a = 0;
- cp = y * B + x + ABASE;
-
- for (i = -R; i < 0; i++) {
- a += ca[x + i < 0 ? cp + B + i : cp + i];
- a <<= L;
- }
- a += ca[cp]; /* c */
- for (i = 1; i <= R; i++) {
- a <<= L;
- a += ca[x + i > BM1 ? cp - B + i : cp + i]; /* r */
- }
-
- return (a);
-
- } /* get_address_l */
-
-
-
- get_nbors_l(nb, x, y) /* get nbors at given ca location */
- unsigned char *nb;
- short x, y;
- {
- int cp, i;
- lr1_nbors *nb1;
- lr2_nbors *nb2;
- lr3_nbors *nb3;
-
- cp = y * B + x + ABASE;
-
- switch (R) {
- case 1:
- nb1 = (lr1_nbors *) nb;
- nb1->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1]; /* l */
- nb1->c = ca[cp]; /* c */
- nb1->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1]; /* r */
- nb1->time = stime;
- nb1->x = x;
- nb1->parm1 = parm1;
- nb1->parm2 = parm2;
- break;
- case 2:
- nb2 = (lr2_nbors *) nb;
- nb2->ll = ca[x-2 < 0 ? cp + B - 2 : cp - 2]; /* ll */
- nb2->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1]; /* l */
- nb2->c = ca[cp]; /* c */
- nb2->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1]; /* r */
- nb2->rr = ca[x+2 > BM1 ? cp - B + 2 : cp + 2]; /* rr */
- nb2->time = stime;
- nb2->x = x;
- nb2->parm1 = parm1;
- nb2->parm2 = parm2;
- break;
- case 3:
- nb3 = (lr3_nbors *)nb;
- nb3->lll = ca[x-3 < 0 ? cp + B - 3 : cp - 3]; /* lll */
- nb3->ll = ca[x-2 < 0 ? cp + B - 2 : cp - 2]; /* ll */
- nb3->l = ca[x-1 < 0 ? cp + B - 1 : cp - 1]; /* l */
- nb3->c = ca[cp]; /* c */
- nb3->r = ca[x+1 > BM1 ? cp - B + 1 : cp + 1]; /* r */
- nb3->rr = ca[x+2 > BM1 ? cp - B + 2 : cp + 2]; /* rr */
- nb3->rrr = ca[x+3 > BM1 ? cp - B + 3 : cp + 3]; /* rrr */
- nb3->time = stime;
- nb3->x = x;
- nb3->parm1 = parm1;
- nb3->parm2 = parm2;
- break;
- }
- return;
-
- } /* get_nbors_l */
-