home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.theory.cell-automata
- Path: sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!concert!gatech!news.ans.net!cmcl2!panix!james
- From: james@panix.com (James Britt)
- Subject: Wolfram CA C source code
- Message-ID: <1992Nov17.061208.16131@panix.com>
- Date: Tue, 17 Nov 1992 06:12:08 GMT
- Organization: PANIX Public Access Unix & Internet, NYC
- Lines: 550
-
- /************************************************************************
- November 1992
-
- This is a cellular automata that implements a line automata
- described in Stephan Wolfram's book, Theory and Aplications of
- Cellular Automata. In this model, any cell in the array may have
- one of two states, 1 or 0. The next state is determined by taking
- each cell, along with its immediate neighbors, and using the three
- bits to create a binary number:
-
- i.e., |0|1|1| -> 3
- |1|1|0| -> 6
-
- So, unlike many automatas, the order of the bits matters.
-
- This number is used to index the state transition rule table. Three
- bits can create a number from 0 to 7, so each rule will be a string
- of 8 bits. Thus, you can have 256 different rules.
-
- This program gives you three options:
-
- You can run the automata in "standard" mode, and see the results
- of any given rule table. Or, you can "mesh" two almost-alike
- automata, and see how a small difference in the initial array
- propagates differences as time goes by. This is something
- Wolfram does in his book. He ran two automatas, each with the
- same rule, and same starting conditions, except that in the second
- one, he flipped a middle bit in the starting array. Then, for
- each generation, he would compare the two arrays, and only display
- those cells where the two differed. Aside from producing some
- interesting pictures, this allows you to see how the individual
- cells are dependant on each other for information propagation.
- This property is interesting to observe, and you may want to think
- about what it tells us about a given rule.
-
- The third option is to display the standard CA with the
- difference pattern overlayed.
-
- The code is written in Turbo C++, 3.0. I've put the graphic routines
- in functions to make it easier to convert to whatever C you might
- have. There a few features I would like to add at some point, such
- as saving a screen to a GIF file, and automatically executing each rule
- from 0 to 127, saving the results.
-
- What I would really like to see is a project similar to Fractint, the
- large, public domain fractal program. Fractint consists of a wide range
- of fractal routines, contributed by a numerous people. The code and
- executable are re-distributed regularly as the program is updated.
-
- Why not have a large, multi-function cellular automata program? One
- that could produce Life; hodge-podge; multi-state line automata; "rug"
- generators, etc...
-
- Anyway, here it is.
-
-
-
- James Britt
- james@panix.com
- (Compu$erve 73417,2776)
-
-
- ***********************************************************************/
-
-
- #include <dos.h>
- #include <math.h>
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <graphics.h>
-
- #define ARRAYSIZE 640
-
- typedef struct
- {
- int rulenumber;
- int choice;
- } menu_struct;
-
-
- void Menu( menu_struct *);
- void GraphicsOn();
- void GraphicsOff();
- void InitStart();
- void Update();
- void Generate();
- void Display( int *, int, int * );
- void OverDisplay( int *, int, int * );
- void ShowRule( int );
- void SaveRule( int);
- void ReadRule(int );
- void MakeTable( int, int * );
- void ClearScreen();
- void Mesh( int *, int *, int * );
-
- main(void)
- {
- menu_struct menuchoice;
- int YSIZE = 480;
- int x, y, z;
- char c, mesh, overlay;
- int array1[ARRAYSIZE], array2[ARRAYSIZE];
- int duplicate1[ARRAYSIZE], duplicate2[ARRAYSIZE], dub[ARRAYSIZE];
- int ruletable[8], colors[2], colors2[2];
-
-
-
- clrscr();
- y = 0;
- colors[0] = WHITE;
- colors[1] = CYAN;
- colors2[0] = CYAN;
- colors2[1] = RED;
-
- Menu( &menuchoice );
-
- MakeTable( menuchoice.rulenumber, ruletable );
- InitStart( array1, duplicate1 );
- GraphicsOn();
- while( 1 )
- {
- Generate( array1, array2, ruletable );
-
-
- if( menuchoice.choice < 2 )
- Display( array1, y, colors );
-
- if( menuchoice.choice == 2 )
- {
- Generate( duplicate1, duplicate2, ruletable );
- Mesh( array1, duplicate1, dub );
- Display( dub, y, colors2 );
- }
-
- if( menuchoice.choice > 2 )
- {
- Generate( duplicate1, duplicate2, ruletable );
- Mesh( array1, duplicate1, dub );
- Display( array1, y, colors );
- OverDisplay( dub, y, colors2 );
- }
-
-
- y++;
-
- y%=YSIZE;
-
- if( y == 0 )
- ClearScreen();
-
- Update( array1, array2 );
- Update( duplicate1, duplicate2 );
- if( kbhit() )
- {
- c = getch();
- if( c == 'x')
- {
- GraphicsOff();
- return;
- }
- if( c == 's')
- ShowRule( menuchoice.rulenumber );
- if( c == 'n')
- {
- GraphicsOff();
- Menu( &menuchoice );
- MakeTable( menuchoice.rulenumber, ruletable );
- InitStart( array1, duplicate1 );
- GraphicsOn();
- cleardevice();
- y = 1;
- }
-
- }
-
-
-
- }
- // GraphicsOff();
-
- // return;
-
- } /* end main() */
-
- /**************************************************************************
- *
- * void Menu( menu_struct *menuchoice )
- *
- * Displays the options for this automata, returning the user's choice.
- *
- ****************************************************************************/
-
-
- void Menu( menu_struct *menuchoice )
- {
-
- clrscr();
- printf("\n The Wolfram CA Program\n");
- printf("\n Please send comments to james@panix.com");
- printf("\n\n\n\n");
- printf("This automata has only two states: on and off.\n");
- printf("Each cell has only two neighbors, left and right.\n");
- printf("However, order matters. |1|0|0| is different than |0|0|1|.\n");
- printf("This allows 2^3 different states, 0 to 7 as writen in binary.\n");
- printf("So, for each possible state, you must decide what the next \n");
- printf("state will be. 2^8 different state tables, 0 to 255 as writen in binary.\n");
- printf("\n\n\n");
- printf("Please enter a number from 0 to 255 for the state table:");
- scanf("%d", &menuchoice->rulenumber );
- printf("\nPlease select a display choice:\n\n");
- printf("1: Show just the automata.\n");
- printf("2: Show just the difference pattern.\n");
- printf("3: Show the difference pattern overlayed on the automata.\n");
- printf("\n? ");
- scanf( "%d", &menuchoice->choice );
- return;
- }
-
- /**************************************************************************
- *
- * void GraphicsOn()
- *
- * Initializes the graphics, TC++ style.
- *
- ****************************************************************************/
-
- void GraphicsOn()
- {
-
- int ErrorCode; /* Reports any graphics errors */
- int GraphDriver; /* The Graphics device driver */
- int GraphMode; /* The Graphics mode value */
-
- GraphDriver = DETECT; /* Request auto-detection */
- initgraph( &GraphDriver, &GraphMode, "" );
- ErrorCode = graphresult(); /* Read result of initialization*/
- if( ErrorCode != grOk ){ /* Error occured during init */
- printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
- exit( 1 );
- }
-
- return;
- }
- /**************************************************************************
- *
- * void GraphicsOff()
- *
- * Turns off the graphics.
- *
- ****************************************************************************/
-
- void GraphicsOff()
- {
- closegraph();
- return;
- }
- /**************************************************************************
- *
- * void InitStart( int array1[ARRAYSIZE], int duplicate1[ARRAYSIZE] )
- *
- * Creates identical random starting arrays for the automatas, then
- * flips the middle bit in the duplicate array.
- *
- ****************************************************************************/
-
- void InitStart( int array1[ARRAYSIZE], int duplicate1[ARRAYSIZE] )
- {
- int x, y, z;
- for( x = 0; x < ARRAYSIZE; x++ )
- {
- array1[x] = rand()%2;
- duplicate1[x] = array1[x];
- }
-
- if(duplicate1[(int)ARRAYSIZE/2] == 1)
- duplicate1[(int)ARRAYSIZE/2] = 0;
- else
- duplicate1[(int)ARRAYSIZE/2] = 1;
- /* flip middle bit */
-
- return;
- }
-
- /**************************************************************************
- *
- * void ShowRule( int rulenumber )
- *
- * Displays the current rule, and allows you to save the rule, plus a
- * brief description, to a file, by calling SaveRule().
- *
- ****************************************************************************/
-
- void ShowRule( int rulenumber )
- {
- char c;
-
- GraphicsOff();
- clrscr();
- printf("\n\n\n\n");
- printf("\The rule is %d", rulenumber );
- printf("\nEnter 's' to save the rule. Press any other key to continue.");
- flushall();
- c = getch();
- if( c == 's')
- SaveRule(rulenumber);
-
- GraphicsOn();
-
- return;
- }
- /**************************************************************************
- *
- * void MakeTable( int rulenumber, int ruletable[8] )
- *
- * Creates the state transistion rule table from the rule number given
- * by the user.
- *
- ****************************************************************************/
-
- void MakeTable( int rulenumber, int ruletable[8] )
- {
- int x, MASK = 01;
-
- printf("%d looks like this: ", rulenumber);
-
- for( x = 0; x < 8; x++)
- {
- ruletable[x] = rulenumber&MASK;
- rulenumber = rulenumber>>1;
- printf("%d ", ruletable[x]);
-
- }
- printf("\n");
- delay(1000);
- return;
- }
- /**************************************************************************
- *
- * void Update(int array1[], int array2[] )
- *
- * Copies one array to another.
- *
- ****************************************************************************/
-
- void Update(int array1[], int array2[] )
- {
- int x;
- for( x = 0; x < ARRAYSIZE; x++ )
- array1[x] = array2[x];
-
- return;
- }
-
- /**************************************************************************
- *
- * void Generate(int array1[ARRAYSIZE], int array2[ARRAYSIZE], int ruletable[8] )
- *
- * Creates the next line in the automata.
- *
- ****************************************************************************/
-
- void Generate(int array1[ARRAYSIZE], int array2[ARRAYSIZE], int ruletable[8] )
- {
- int x, number;
- for( x = 1; x < ARRAYSIZE-1; x++ )
- {
- number = array1[x-1]*4 + array1[x]*2 + array1[x+1];
- array2[x] = ruletable[number];
- }
- // number = array1[ARRAYSIZE-1]*4 + array1[0]*2 + array1[1]; screen wrap
- number = array1[0]*2 + array1[1];
- array2[0] = ruletable[number];
-
- // number = array1[ARRAYSIZE-2]*4 + array1[ARRAYSIZE-1]*2 + array1[0]; screen wrap
- number = array1[ARRAYSIZE-2]*4 + array1[ARRAYSIZE-1]*2;
- array2[ARRAYSIZE-1] = ruletable[number];
-
- return;
- }
- /**************************************************************************
- *
- * void SaveRule( int rulenumber )
- *
- * Saves the rule ( by appending) to a file called "wolfca.dat"
- *
- * (There should be a GetRule(), but...)
- ****************************************************************************/
-
-
- void SaveRule( int rulenumber )
- {
- char description[40];
- FILE *fp;
-
- printf("\nPlease enter a short description of the rule:");
- gets( description );
-
- fp = fopen("wolfca.dat", "a" );
- fprintf (fp,"%d %s\n", rulenumber, description );
- fclose(fp);
-
- return;
- }
- /**************************************************************************
- *
- * void Display( int array1[ARRAYSIZE], int y, int colors[2] )
- *
- * Diplays the contents of the array to the screen.
- *
- ****************************************************************************/
-
- void Display( int array1[ARRAYSIZE], int y, int colors[2] )
- {
- int x;
-
- for( x = 0; x < ARRAYSIZE; x++ )
- putpixel( x, y, colors[ array1[x] ] );
-
-
- return;
-
- }
-
- /**************************************************************************
- *
- * void OverDisplay( int array1[ARRAYSIZE], int y, int colors[2] )
- *
- * Diplays the contents of the mesh array to the screen, only plotting 1's.
- *
- ****************************************************************************/
-
- void OverDisplay( int array1[ARRAYSIZE], int y, int colors[2] )
- {
- int x;
-
- for( x = 0; x < ARRAYSIZE; x++ )
- if( array1[x] == 1 )
- putpixel( x, y, colors[ array1[x] ] );
-
-
- return;
-
- }
-
- /**************************************************************************
- *
- * void ClearScreen()
- *
- * Makes a beep sound, then waits for a keypress, then clears the
- * graphics didplay.
- *
- ****************************************************************************/
-
- void ClearScreen()
- {
- int x;
-
- for( x = 0; x < 20000; x++ )
- {
- sound(2100);
- sound(900);
- }
-
- nosound();
- getch();
-
- cleardevice();
-
- return;
-
- }
-
- /**************************************************************************
- *
- * void SaveScreen()
- *
- * Saves the contents of the screen to a file.
- * Not fully implemented yet. Play with it!
- *
- ****************************************************************************/
-
-
-
-
- void SaveScreen()
- {
- #define XSIZE 640/8
- #define YSIZE 480
-
- FILE *fd;
- int x, y, z;
- unsigned char screen[XSIZE][YSIZE], bit;
-
-
- for( y = 0; y < 480; y++ )
- for( x = 0; x < 640; x+=8 )
- {
- for( z = 7; z > -1; z-- )
- {
- bit = getpixel(x+z, y);
- bit = bit<<z;
- screen[x][y] = screen[x][y] | bit;
- }
-
- }
-
- fd = fopen( "screen.dat", "wt" );
-
- for( y = 0; y < YSIZE; y++ )
- {
- for( x = 0; x < XSIZE; x++ )
- fprintf( fd, "%c", screen[x][y] );
-
- fprintf( fd, "\n" );
- }
-
- return;
- } /* end SaveScreen() */
-
- /**************************************************************************
- *
- * void Mesh( int array1[ARRAYSIZE], int duplicate1[ARRAYSIZE],
- * int dub[ARRAYSIZE] )
- *
- * Compares the results of two arrays and puts the result in a third array.
- *
- ****************************************************************************/
-
- void Mesh(int array1[ARRAYSIZE],int duplicate1[ARRAYSIZE],int dub[ARRAYSIZE] )
- {
- int x;
- FILE *fd;
-
- for( x = 0; x < ARRAYSIZE; x++)
- {
- if( array1[x] == duplicate1[x])
- dub[x] = 0;
- else
- dub[x] = 1;
- }
-
- return;
- }
-
- --
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Just another speed-metal vegetarian anarchist cyberhippie Zen Socratic...
- Diblo Rules! Hack The Wetware!
- james@panix.com .............................................................
-