home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 275_01 / lcau22.c < prev    next >
Encoding:
C/C++ Source or Header  |  1980-01-01  |  19.6 KB  |  675 lines

  1.  
  2. /* lcau22.c                */
  3. /* (2,2) Linear Cellular Automaton    */
  4.  
  5. /* Reference:                */
  6. /*                    */
  7. /*    Kenneth E. Perry            */
  8. /*    Abstract Mathematical Art        */
  9. /*    BYTE                */
  10. /*    December, 1986            */
  11. /*    pages 181-192            */
  12.  
  13. /*    Copyright (C) 1987        */
  14. /*    Copyright (C) 1988        */
  15. /*    Harold V. McIntosh        */
  16. /*    Gerardo Cisneros S.        */
  17.  
  18. /* G. Cisneros, 4.3.87                        */
  19. /* 10 April 1987 - modified for (4,2) [HVM]            */
  20. /* 26 April 1987 - Multiple menus [HVM]                */
  21. /* 28 April 1987 - back modified to (4,1) [HVM]            */
  22. /* 28 April 1987 - version for XVI Feria de Puebla [HVM]    */
  23. /* 14 May 1987 - modified for (3,1) and general rule [HVM]    */
  24. /* 19 May 1987 - modified for (2,2) [HVM]            */
  25. /* 20 May 1987 - modified for (2,3) [HVM]            */
  26. /* 21 May 1987 - Wolfram rule number [HVM]            */
  27. /* 8 June 1987 - general rule for (4,1) [HVM]             */
  28. /* 12 June 1987 - cartesian product of (2,1) rules [HVM]    */
  29. /* 12 June 1987 - (2,1) rule with memory  [HVM]            */
  30. /* 14 June 1987 - individual cycles of evolution [HVM]        */
  31. /* 17 June 1987 - p-adic representation in plane [HVM]        */
  32. /* 22 June 1987 - 2 speed gliders via 16 transitions [HVM]    */
  33. /* 26 June 1987 - push, pop the rule [HVM]            */
  34. /* 26 June 1987 - conserve position of rule cursor [HVM]    */
  35. /* 27 June 1987 - incremental rule construction [HVM]        */
  36. /* 29 June 1987 - conserve position of cell pointer [HVM]    */
  37. /* 30 June 1987 - mark & unmark transitions, xchg x&X [HVM]    */
  38. /* 25 July 1987 - display and edit de Bruijn diagrams [HVM]    */
  39. /* 27 July 1987 - graph of transition probabilities [HVM]    */
  40. /* 4 September 1987 - PROB21.C for option 't' [HVM]        */
  41. /* 21 October 1987 - program disks disappeared            */
  42. /* 20 December 1987 - program reconstructed from listings    */
  43. /* 20 February 1988 - RIJN21.C for option 'd' [HVM]        */
  44.  
  45. # include <bdos.h>
  46.  
  47. # define COLGRAF        4  /* graph resolution            */
  48. # define T80X25            3  /* text resolution            */
  49. # define WHCYMAG        1  /* color quad for normal screen    */
  50. # define YELREGR        2  /* alternative color palette     */
  51. # define CR                5  /* cursor reference - row editor    */
  52. # define CM                7  /* cursor reference - main menu    */
  53. # define CL               11  /* cursor reference - line editor    */
  54. # define AL                320  /* array length (screen width)    */
  55. # define SL               40  /* short array length        */
  56. # define KK                 2  /* number of states per cell        */
  57. # define DS        KK*KK*KK*KK*KK  /* number of distinct neighborhoods    */
  58. # define TS           5*(KK-1)+1  /* distinct sums w/totalistic rule    */
  59. # define BD               25  /* max number Bernstein coeffs    */ 
  60. # define NX                  7  /* number of sample rules        */
  61.  
  62. char xrule[NX][KK][KK][KK][KK][KK];
  63.  
  64. char ixrule[NX][DS]=
  65.  
  66.     "00010110011010010110100110010111",    /* totalistic rule #52    */
  67.     "00010110011010010110100110010110",    /* totalistic rule #20    */
  68.     "00010011101010011100110001100011",    /* mottled                 */
  69.     "00101110000110101011001111000100",    /*                      */
  70.     "01101000001100110011001100110011",    /*                */
  71.     "10010000101100110000000101111100",    /*                 */
  72.     "11111101001100110011001100110011"    /*                         */
  73.  
  74.     ;
  75.  
  76. char   ascrule[KK][KK][KK][KK][KK];
  77. char   trule[TS]="000000";
  78. int    binrule[KK][KK][KK][KK][KK];
  79. int    arr1[AL], arr2[AL];
  80. int    ix0, iy0;                    /* origin for pen moves */
  81. double bp[BD];
  82.  
  83. main()
  84. {
  85. int  i, j, i0, i1, i2, i3, i4;
  86. int  more = 'r';
  87. char a, b, c;
  88.  
  89. for (i=0; i<NX; i++) {                    /* copy to 3-index array */
  90. i0=0; i1=0; i2=0; i3=0; i4=0;
  91. for (j=0; j<DS; j++) {
  92.   xrule[i][i0][i1][i2][i3][i4]=ixrule[i][j];
  93.   i4++;
  94.   if (i4>KK-1) {i4=0; i3++;};
  95.   if (i3>KK-1) {i3=0; i2++;};
  96.   if (i2>KK-1) {i2=0; i1++;};
  97.   if (i1>KK-1) {i1=0; i0++;};
  98.   if (i0>KK-1) {i0=0; };
  99. };};
  100.  
  101.  
  102.     videopalette(WHCYMAG);                /* white/cyan/magenta */
  103.  
  104.     tuto();
  105.     while (!kbdst()) rand();                /* wait for keypress */
  106.     kbdin();                        /* ignore it */
  107.     videomode(T80X25);
  108.     videoscroll(0,0,CR,71,0,3);                /* menu on blue background */
  109.     videoscroll(CL+8,0,24,71,0,3);
  110.     xtoasc(rand()%NX);
  111.     ranlin();                        /* random initial array */
  112.  
  113.     while (more!='n') {                    /* execute multiple runs */
  114.     rmenu();
  115.     lmenu();
  116.     while (0<1) {                    /* set up one run */
  117.     c=kbdin();
  118.     if (c=='g') break;                    /* go draw graph */
  119.     if (c=='q') more='n';                /* quit for good */
  120.     if (more=='n') break;
  121.     switch (c) {
  122.     case '@':                    /* numbered tot rule */
  123.         nutoto(numin(0));
  124.         totoasc();
  125.         rmenu();
  126.         videocursor(0,CM,0);
  127.         break;
  128.     case '$':                    /* dozen totalistics */
  129.         j=numin(0);
  130.         for (i=0; i<12; i++) {
  131.           nutoto(j+i);
  132.           totoasc();
  133.           ranlin();
  134.           evolve();
  135.           };
  136.             videomode(T80X25);
  137.         rmenu();
  138.         lmenu();
  139.         break;
  140.     case 'T':                    /* totalistic rule */
  141.         xblnk();
  142.         tmenu();
  143.         edtrule();
  144.         totoasc();
  145.         for (i0=0; i0<KK; i0++) {
  146.         for (i1=0; i1<KK; i1++) {
  147.         for (i2=0; i2<KK; i2++) {
  148.         for (i3=0; i3<KK; i3++) {
  149.         for (i4=0; i4<KK; i4++) {
  150.         ascrule[i0][i1][i2][i3][i4]=trule[i0+i1+i2+i3+i4];
  151.         };};};};};
  152.         videocursor(0,CM,0);
  153.         rmenu();
  154.         break;
  155.     case 't':                    /* probability calculation */
  156.         edtri();
  157.         rmenu();
  158.         lmenu();
  159.         break;
  160.         case 'r':                    /* edit rule */    
  161.         xblnk();
  162.         edrule();
  163.         videocursor(0,CM,0);
  164.         rmenu();
  165.         break;
  166.         case 'l':                    /* edit cell string */
  167.         xblnk();
  168.         edline();
  169.         videocursor(0,CM,0);
  170.         lmenu();
  171.         break;
  172.         case '#':                    /* read stored rule */
  173.         xmenu(NX);
  174.         xtoasc(lim(1,numin(0),NX)-1);
  175.         rmenu();
  176.             break;
  177.     case 'D':                    /* run through samples */
  178.         for (i=0; i<NX; i++) {
  179.           xmenu(i);
  180.           xtoasc(i);
  181.           ranlin();
  182.           evolve();
  183.           };
  184.         videomode(T80X25);
  185.         rmenu();
  186.         break;
  187.     case 'd':                    /* de Bruijn diagram */
  188.         edijn();
  189.         rmenu();
  190.         lmenu();
  191.         break;
  192.         case 'u':                    /* sparse init arry */
  193.         xblnk();
  194.         for (i=0; i<AL; i++) arr1[i]=0;
  195.         arr1[AL/4]=1;
  196.             arr1[AL/2]=1;
  197.             arr1[(3*AL)/4]=1;
  198.             arr1[(3*AL)/4+2]=1;
  199.         lmenu();
  200.             break;
  201.     case 'w':                    /* Wolfram rulw # */
  202.         i=numin(0);
  203.         wmenu(i);
  204.         for (i0=0; i0<KK; i0++) {
  205.         for (i1=0; i1<KK; i1++) {
  206.         for (i2=0; i2<KK; i2++) {
  207.         for (i3=0; i3<KK; i3++) {
  208.         for (i4=0; i4<KK; i4++) {
  209.           ascrule[i0][i1][i2][i3][i4]='0'+i%KK;
  210.           i/=KK;
  211.         };};};};};
  212.         rmenu();
  213.         break;
  214.     case 'x':                    /* random rule */
  215.         xblnk();
  216.         for (i0=0; i0<KK; i0++) {
  217.         for (i1=0; i1<KK; i1++) {
  218.         for (i2=0; i2<KK; i2++) {
  219.         for (i3=0; i3<KK; i3++) {
  220.         for (i4=0; i4<KK; i4++) {
  221.           if ((KK*(KK*i0+i1)+i2)%4 == 0) i=rand();
  222.           ascrule[i0][i1][i2][i3][i4]='0'+i%KK;
  223.           i/=KK;
  224.         };};};};};
  225.         rmenu();
  226.         break;
  227.     case 'y':                    /* random line */
  228.         xblnk();
  229.         ranlin();
  230.             lmenu();
  231.         break;
  232.     case 'Y':                    /* symmetrize rule */
  233.         for (i0=0; i0<KK; i0++) {
  234.         for (i1=0; i1<KK; i1++) {
  235.         for (i2=0; i2<KK; i2++) {
  236.         for (i3=0; i3<KK; i3++) {
  237.         for (i4=0; i4<KK; i4++) {
  238.         ascrule[i4][i3][i2][i1][i0]=ascrule[i0][i1][i2][i3][i4];      
  239.         };};};};};
  240.         break;
  241.     case 'B':                    /* begin barrier */
  242.         a=kbdin();
  243.         b=kbdin();
  244.         ascrule[0][a-'0'][b-'0'][a-'0'][a-'0']=a;
  245.         ascrule[1][a-'0'][b-'0'][a-'0'][a-'0']=a;
  246.         ascrule[2][a-'0'][b-'0'][a-'0'][a-'0']=a;
  247.         rmenu();
  248.         break;
  249.     case 'E':                    /* end barrier */
  250.         a=kbdin();
  251.         b=kbdin();
  252.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][0]=b;
  253.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][1]=b;
  254.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][2]=b;
  255.         rmenu();
  256.         break;
  257.     case 'L':                    /* left glider link */
  258.         a=kbdin();
  259.         b=kbdin();
  260.         c=kbdin();
  261.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][c-'0']=c;
  262.         rmenu();
  263.         break;
  264.     case 'R':                    /* left glider link */
  265.         a=kbdin();
  266.         b=kbdin();
  267.         c=kbdin();
  268.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][c-'0']=a;
  269.         rmenu();
  270.         break;
  271.     case 'S':                    /* still life link */
  272.         a=kbdin();
  273.         b=kbdin();
  274.         c=kbdin();
  275.         ascrule[a-'0'][a-'0'][a-'0'][b-'0'][c-'0']=b;
  276.         rmenu();
  277.         break;
  278.     case '.':                    /* one cycle of evolution */
  279.         asctobin();
  280.         onegen(AL);
  281.         lmenu();
  282.         break;
  283.     case '=':
  284.         for (i=1; i<8;  i++) {
  285.         for (j=0; j<40; j++) arr1[40*i+j]=arr1[j];};
  286.         lmenu();
  287.         break;
  288.     case '~':
  289.         for (i=1; i<16;  i++) {
  290.         for (j=0; j<20; j++) arr1[20*i+j]=arr1[j];};
  291.         lmenu();
  292.         break;
  293.         default: break;
  294.         };
  295.     };
  296.     if (more=='n') break;
  297.     do {
  298.     evolve();
  299.     videocursor(0,0,0);
  300.     scrstr("?");
  301.     videocursor(0,0,34);
  302.     scrstr("y/n/cr");
  303.     more=kbdin();
  304.     } while (more=='\015');
  305.     videomode(T80X25);                    /* reset the screen */
  306.     if (more=='n') break;
  307.     };
  308.   videomode(T80X25);}    
  309.  
  310. /* edit the rule */
  311. edrule() {
  312. char c;
  313. int  i, i0, i1, i2, i3, i4;
  314.  
  315. i=6; i0=0; i1=0, i2=0; i3=0; i4=0;
  316.     while (0<1) {
  317.         videocursor(0,CR,i);
  318.         c=kbdin();
  319.         if (c == '\015') break;                /* carriage return exits */
  320.         switch (c) {
  321.         case '0':  case '1':                /* state */
  322.         ascrule[i0][i1][i2][i3][i4] = c;
  323.             i4++;
  324.         if (i4>KK-1) {i4=0; i3++;};
  325.         if (i3>KK-1) {i3=0; i2++;};
  326.         if (i2>KK-1) {i2=0; i1++;};
  327.         if (i1>KK-1) {i1=0; i0++;};
  328.         if (i0>KK-1) {i2=0; };
  329.             videocattr(0,c,3,1);
  330.             if (i<6+DS) i++;
  331.             break;
  332.         case ' ': case '\315':                /* space = advance */
  333.             i4++;
  334.         if (i4>KK-1) {i4=0; i3++;};
  335.         if (i3>KK-1) {i3=0; i2++;};
  336.         if (i2>KK-1) {i2=0; i1++;};
  337.         if (i1>KK-1) {i1=0; i0++;};
  338.         if (i0>KK-1) {i2=0; };
  339.             if (i<6+DS) i++;
  340.             break;
  341.         case '\010': case '\313':            /* backspace */
  342.         if (i4!=0) i4--; else {i4=KK-1;
  343.         if (i3!=0) i3--; else {i3=KK-1;
  344.         if (i2!=0) i2--; else {i2=KK-1;
  345.         if (i1!=0) i1--; else {i1=KK-1;
  346.         if (i0!=0) i0--; else {i0=KK-1;
  347.         };};};};};
  348.             if (i>6) i--;
  349.             break;
  350.     default: break;
  351.         };
  352.     };
  353. }
  354.  
  355. /* edit totalistic rule */
  356. edtrule() {char c; int  i;
  357.   i=0;
  358.   while (i<TS) {
  359.     c=trule[i];
  360.     videocursor(0,3,56+i);
  361.     videocattr(0,c,3,1);
  362.     c=kbdin();
  363.     if (c=='\015') break;
  364.     switch (c) {
  365.       case '0': case '1':                /* state */
  366.         trule[i]=c;
  367.         videocattr(0,c,CR,1);
  368.         i++;
  369.         break;
  370.       case ' ': case '\315':            /* space = advance */
  371.         i++;
  372.         break;
  373.       case '\010': case '\313':            /* backspace */
  374.         if (i!=0) i--;
  375.     break;
  376.       default: break;
  377.       };
  378.   };
  379. }
  380.  
  381. /* edit the line */
  382. edline() {
  383. char c;
  384. int  i, j, k, ii, jj;
  385.  
  386.     videocursor(0,19,0);
  387.     scrstr("insert states using 0, 1,");
  388.     videocursor(0,20,0);
  389.     scrstr("move cursor with n(north), s(south), e(east), w(west), or");
  390.     videocursor(0,21,0);
  391.     scrstr("with keyboard arrows. Space, backspace move right and left.");
  392.     videocursor(0,22,0);
  393.     scrstr("( seeks left margin, < absolutely, { up one line, [ down one line");
  394.     videocursor(0,23,0);
  395.     scrstr(") seeks right margin, > absolutely, } up one line, ] down one line");
  396.     videocursor(0,24,0);
  397.     scrstr("carriage return exits");
  398.     jj=4;
  399.     ii=1;
  400.     while (0<1) {
  401.     ii=lim(1,ii,40);
  402.     jj=lim(1,jj,8);
  403.     j=jj-1;
  404.     i=ii-1;
  405.     videocursor(0,j+CL,i);
  406.     c=kbdin();
  407.     if (c == '\015') {videoscroll(19,0,24,70,0,3); break;};
  408.     switch (c) {
  409.     case '0':  case '1':        /* enter  state */
  410.        arr1[40*j+i]=c-'0'; ii++; break;
  411.     case 's': case '\012': case '\320':          jj++; break;    /* down - next line */
  412.     case 'n': case '\013': case '\310':          jj--; break;    /* up   - last line */
  413.     case 'e': case '\014': case '\315': case ' ': ii++; break;    /* space = advance  */
  414.     case 'w': case '\010': case '\313':          ii--; break;    /* backspace */
  415.     case '<': ii=1;  jj=1;  break;  /* absolute left */
  416.     case '{': ii=1;  jj--;  break;  /* left one row up */
  417.     case '(': ii=1;         break;  /* left this row */
  418.     case '[': ii=1;  jj++;  break;  /* left next row */
  419.     case '>': ii=40; jj=40; break;  /* absolute right */
  420.     case '}': ii=40; jj--;  break;  /* right one row up */
  421.     case ')': ii=40;        break;  /* right this row */
  422.     case ']': ii=40; jj++;  break;  /* right next row */
  423.     default: break;
  424.         };
  425.     videocursor(0,j+CL,0);
  426.     for (k=0; k<40; k++) videoputc('0'+arr1[40*j+k],1);
  427.     };
  428. }
  429.  
  430. /* display a screen of evolution */
  431. evolve() {
  432. int i, j;
  433.   videomode(COLGRAF);                    /* erase the screen */
  434.   videocursor(0,0,0);                    /* top text line */
  435.   scrstr(":");
  436.   scrrul(); 
  437.   asctobin();
  438.   for (j=8; j<200; j++) videodot(j,AL-1,2);
  439.   for (j=8; j<200; j++) {                /* evolve for 192 generations */
  440.     for (i=0; i<AL; i++) videodot(j,i,arr1[i]);
  441.     onegen(AL);
  442.     if (kbdst()) {kbdin(); break;};
  443.     };
  444. }
  445.  
  446. /* copy ascrule over to binrul */
  447. asctobin() {int i0, i1, i2, i3, i4;
  448.     for (i0=0; i0<KK; i0++) {
  449.     for (i1=0; i1<KK; i1++) {
  450.     for (i2=0; i2<KK; i2++) {
  451.     for (i3=0; i3<KK; i3++) {
  452.     for (i4=0; i4<KK; i4++) {
  453.       binrule[i0][i1][i2][i3][i4]=ascrule[i0][i1][i2][i3][i4]-'0';
  454.       };};};};};
  455. }
  456.  
  457. /* evolution for one generation */
  458. onegen(j) int j; {int i;
  459.   if (j<4) return;
  460.   arr2[0]=binrule[arr1[j-2]][arr1[j-1]][arr1[0]][arr1[1]][arr1[2]];
  461.   arr2[1]=binrule[arr1[j-1]][arr1[0]][arr1[1]][arr1[2]][arr1[3]];
  462.   for (i=2; i<j-2; i++) arr2[i]=binrule[arr1[i-2]][arr1[i-1]][arr1[i]][arr1[i+1]][arr1[i+2]];
  463.   arr2[j-2]=binrule[arr1[j-4]][arr1[j-3]][arr1[j-2]][arr1[j-1]][arr1[0]];
  464.   arr2[j-1]=binrule[arr1[j-3]][arr1[j-2]][arr1[j-1]][arr1[0]][arr1[1]];
  465.   for (i=0;  i<j; i++) arr1[i]=arr2[i];
  466. }
  467.  
  468. /* generate a random line of cells in arr1 */
  469. ranlin() {int i, c;
  470. for (i=0; i<AL; i++) {
  471.   if (i%8 == 0) c=rand();
  472.   arr1[i]=c%KK; c/=KK;};
  473. }
  474.  
  475. /* tutorial and Help screen */
  476. tuto() {
  477.     videomode(T80X25);
  478.     videocursor(0,2,0);
  479.     scrstr("<Copyright (C) 1987, 1988 - H.V. McIntosh, G. Cisneros S.>");
  480.     videocursor(0,4,0);
  481.     scrstr("           ***** LIFE in One Dimension *****");
  482.     videocursor(0,6,0);
  483.     scrstr("Two States - Black(0), Cyan(1).");
  484.     videocursor(0,8,0);
  485.     scrstr("Second neighbors - two on each side, five altogether.");
  486.     videocursor(0,10,0);
  487.     scrstr("Complete transition rule - random, edited, or stored.");
  488.     videocursor(0,12,0);
  489.     scrstr("Initial Cellular Array - random, edited, or patterned.");
  490.     videocursor(0,14,0);
  491.     scrstr("Submenus in options t(probabilities) and d(de Bruijn)");
  492.     videocursor(0,15,0);
  493.     scrstr("will be displayed in response to typing ?");
  494.     videocursor(0,17,0);
  495.     scrstr("Use any key to terminate a display in progress.");
  496.     videocursor(0,21,0);
  497.     scrstr("Now, ... press any key to continue.");
  498. }
  499.  
  500. /* rule menu */
  501. rmenu() {
  502.     videocursor(0,CR-5,0);
  503.     scrstr("      00000000000000001111111111111111");
  504.     videocursor(0,CR-4,0);
  505.     scrstr("      00000000111111110000000011111111");
  506.     videocursor(0,CR-3,0);
  507.     scrstr("      00001111000011110000111100001111");
  508.     videocursor(0,CR-2,0);
  509.     scrstr("      00110011001100110011001100110011");
  510.     videocursor(0,CR-1,0);
  511.     scrstr("      01010101010101010101010101010101");
  512.     videocursor(0,CR,0);
  513.     scrstr("Rule: ");
  514.     scrrul();
  515.     videocursor(0,CR,42);
  516.     printf("      ");
  517.     videocursor(0,CR,42);
  518.     if (istot()==1) printf("(T-%2d)",totonu(0));
  519.     videocursor(0,CM,0);
  520.     scrstr("    r(rule), l(line), #nn(stored), g(graph), q(quit), t(prob),");
  521.     videocursor(0,CM+1,0);
  522.     scrstr("         x(rand rule), y(rand line), u(unit line), d(deBruijn)");
  523.     videocursor(0,CM+2,0);
  524.     scrstr("         @nn(tot/rule), $nn(12 tot/rules), T(ed tot/rule).");
  525.     videocursor(0,CM,0);
  526.     }
  527.  
  528. /* totalistic rule menu*/
  529. tmenu() {
  530.     videocursor(0,CR-3,50);
  531.     scrstr("      0....1");
  532.     videocursor(0,CR-2,50);
  533.     scrstr("rule: ");
  534.     tscrrul();
  535.     videocursor(0,CR-2,56);
  536.     }
  537.  
  538. /* line menu */
  539. lmenu() {int i, j;
  540.   for (j=0; 40*j<AL; j++) {
  541.     videocursor(0,CL+j,0);
  542.     for (i=0; i<40; i++) videoputc('0'+arr1[40*j+i],1);
  543.     }
  544.   videocursor(0,CM,0);
  545.   }
  546.  
  547. /* display Wolfram rule number */
  548. wmenu(n) int n;
  549. {char xx[4]; int i, nn;  
  550.     nn=sprintf(xx,"%3d",n);
  551.     videocursor(0,2,40);
  552.     for (i=0; i<nn; i++) videoputc(xx[i],1);
  553.     videocursor(0,2,40); }
  554.  
  555. /* display rule number */
  556. xmenu(n) int n;
  557. {char xx[4]; int i, nn;  
  558.     nn=sprintf(xx,"%3d",n);
  559.     videocursor(0,1,40);
  560.     for (i=0; i<nn; i++) videoputc(xx[i],1);
  561.     videocursor(0,1,40); }
  562.  
  563. /* clear screen space for rule numbers */
  564. xblnk() {
  565.     videocursor(0,CR-4,40);
  566.     scrstr("     ");
  567.     videocursor(0,CR-3,40);
  568.     scrstr("     ");
  569.     videocursor(0,CR,0); }
  570.  
  571. /* copy saved rule #n into active rule */
  572. xtoasc(n) int n; { int i0, i1, i2, i3, i4;
  573.     xmenu(n+1);
  574.     for (i0=0; i0<KK; i0++) {
  575.     for (i1=0; i1<KK; i1++) {
  576.     for (i2=0; i2<KK; i2++) {
  577.     for (i3=0; i3<KK; i3++) {
  578.     for (i4=0; i4<KK; i4++) {
  579.     ascrule[i0][i1][i2][i3][i4]=xrule[n][i0][i1][i2][i3][i4];        /* random sample rule */
  580.     };};};};}; }
  581.  
  582. /* change totalistic rule to general rule */
  583. totoasc() {int i0, i1, i2, i3, i4;
  584. for (i0=0; i0<KK; i0++) {
  585. for (i1=0; i1<KK; i1++) {
  586. for (i2=0; i2<KK; i2++) {
  587. for (i3=0; i3<KK; i3++) {
  588. for (i4=0; i4<KK; i4++) {
  589. ascrule[i0][i1][i2][i3][i4]=trule[i0+i1+i2+i3+i4];
  590. };};};};};
  591. }
  592.  
  593. /* change decimal totalistic rule to sum values */
  594. nutoto(x) int x; {int i; for (i=0; i<TS; i++) {trule[i]=x%KK+'0'; x/=KK;};}
  595.  
  596. /* change sum values to decimal totalistic rule */
  597. int totonu(i) int i; {int r;
  598.  r=0; if (i<TS) r=(trule[i]-'0')+KK*totonu(i+1);
  599.   return r; }
  600.  
  601. /* test whether a rule is totalistic */
  602. int istot() {int i0, i1, i2, i3, i4, l;
  603.     l=1;
  604.     trule[0]=ascrule[0][0][0][0][0];
  605.     trule[1]=ascrule[1][0][0][0][0];
  606.     trule[2]=ascrule[1][1][0][0][0];
  607.     trule[3]=ascrule[1][1][1][0][0];
  608.     trule[4]=ascrule[1][1][1][1][0];
  609.     trule[5]=ascrule[1][1][1][1][1];
  610.     for (i0=0; i0<KK; i0++) {
  611.     for (i1=0; i1<KK; i1++) {
  612.     for (i2=0; i2<KK; i2++) {
  613.     for (i3=0; i3<KK; i3+#) {
  614.     for (i4=0; i4<KK; i4++) {
  615.     if (ascarr1[j-3]][arr1[j-2]][arr1[j-1]][arr1[0]][arr1[1]];
  616.   for (i=0;  i<j; i++) arr1[i]=arr2[i];
  617. }
  618.  
  619. /* generate a random line of cells in arr1 */
  620. ranlin() {int i, c;
  621. for (i=0; i<AL; i++) {
  622.   if (i%8 == 0) c=rand();
  623.   arr1[i]=c%KK; c/=KK;};
  624. }
  625.  
  626. /* tutorial and Help screen */
  627. tuto() {
  628.     videomode(T80X25);
  629.     videocursor(0,2,0);
  630.     scrstr("<Copyright (C) 1987, 1988 - H.V. McIntosh, G. Cisneros S.>");
  631.     videocursor(0,4,0);
  632.     scrstr("           ***** LIFE in One Dimension *****");
  633.     videocu* turn ascrule into its Wolfram number and place on screen at (i,j) */
  634. woruno(i,j) int i, j; {
  635. char xx[12];
  636. int  k, l, i0, i1, i2, i3, i4;
  637.   k=0;
  638.   for (i0=KK-1; i0>=0; i0--) {
  639.   for (i1=KK-1; i1>=0; i1--) {
  640.   for (i2=KK-1; i2>=0; i2--) {
  641.   for (i3=KK-1; i3>=0; i3--) {
  642.   for (i4=KK-1; i4>=0; i4--) {
  643.     k=KK*k+(ascrule[i0][i1][i2][i3][i4]-'0');
  644.     };};};};};
  645.   k=sprintf(xx,"%10d",k);
  646.   videocursor(0,i,j);
  647.   for (l=0; l<k; l++) videoputc(xx[l],1);
  648. }
  649.  
  650. /* display totalistic rule number by sum */
  651. tscrrul() {int i; for (i=0; i<TS; i++) {videoputc(trule[i]); }; }
  652.  
  653. /* write a string in graphics mode */
  654. scrstr(s) char *s; {for (; *s != '\0'; s++) videoputc(*s,1); }
  655.  
  656. /* keyboard status */
  657. int kbdst() {return(bdos(11) & 0xFF);}
  658.  
  659. /* direct keyboard input, no echo */
  660. kbdin() {int c;
  661.   if ((c = bdos(7) & 0xFF) == '\0') c = (bdos(7) & 0xFF) | 0x80;
  662.   return(c);
  663. }
  664.  
  665. /* read number from keyboard */
  666. int numin(n) int n; {char c;
  667.   c=kbdin();
  668.   if (c>='0'&&c<='9') return(numin(10*n+(c-'0'))); else return(n);
  669. }
  670.  
  671. # include "prob22.c"
  672. # include "rijn22.c"
  673.  
  674. /* end */
  675.