home *** CD-ROM | disk | FTP | other *** search
- /*
-
- life.cwx
-
- An implementation of Conway's Game of Life using object graphics.
-
- Copyright 1997 by TrueSpectra Inc.
-
- This code is provided purely for demonstration purposes and is not
- supported or under warranty. Feel free to modify and examine this
- example script for your own purposes.
-
- */
-
-
- initial_cells = 30; /* number of cells to create at start */
- max_generation = 200; /* number of generations */
- output_count = 10; /* number of cells to fit in the output area */
-
- /*************************************************************************/
- call CwNewProject;
-
- /* scale the object appropriately so that output_count objects fit in the
- * output area. Objects may, of course, be created outseide of the output
- * area as generations go by */
- scale = 0;
-
- outp = CwGetAppHandle( "output settings" );
- width = CwGetProperty( outp, "output size:width" );
- height = CwGetProperty( outp, "output size:height" );
-
- /* make sure the scales are such that the cells are square by scaling to
- * the limiting value */
- if width < height then;
- scale = width / output_count;
- else;
- scale = height / output_count;
-
- /* zoom to something reasonable */
- call CwSetViewZoom width/2, height/2, width*2, height*2;
-
- /*************************************************************************/
- /* Create the initial generation randomly. We could also create a way to
- * read data from a file and generate from that. */
-
- gen = 0; /* handle of current generation */
- do c = 1 to initial_cells;
- x = TRUNC( rand( 1, output_count ) );
- y = TRUNC( rand( 1, output_count ) );
-
- /* we're doing this randomly, so we don't want to stack multiple cells
- * in one place. It won't cause any serious problems, but more cells
- * do drop performance. */
- if \find_cell( x, y, gen ) then do;
- cell = create_cell( x, y );
- gen = CwAddObjectToGroup( cell, gen );
- end;
- end;
-
- call CwWaitOnRender CwGetCurrentView();
-
- /*************************************************************************/
- p1 = 0;
- p2 = 0;
- p3 = 0;
- do generation = 1 to max_generation;
- p3 = p2;
- p2 = p1;
- p1 = gen;
- gen = create_generation( p1 );
- /* could be that everything died */
- if \CwIsHandleValid( gen ) then;
- exit;
-
- call age_generation( p1 );
- call age_generation( p2 );
- call age_generation( p3 );
-
- call CwWaitOnRender CwGetCurrentView();
- end;
- exit;
-
- /*************************************************************************/
- rand:procedure
- arg from,to
- r = random(0,999)/1000;
- return (to - from) * r + from;
-
- /*************************************************************************/
- /* This can do all kinds of cool things. For example, we could stick a
- * blur on top of the entire group to fade out a generation, or we can just
- * delete it. Some interesting effects are possible... */
- age_generation:procedure
- arg parent
- if \CwIsHandleValid( parent ) then
- return;
-
- call CwDeleteObject parent;
- return;
-
- /*************************************************************************/
- create_cell:procedure expose scale
- arg x, y
- call CwSetSelectionRectangle (x*scale), (y*scale), scale, scale;
- cell = CwCreateEffect( "ellipse", "solid color" );
- tool = CwGetTool( cell );
- call CwSetProperty tool, "color", "#b00000";
- name = 'X:'||x||' Y:'||y;
- call CwSetName cell, name;
-
- return cell;
-
- /*************************************************************************/
- find_cell:procedure
- arg x, y, parent;
- if \CwIsHandleValid( parent ) then;
- return 0;
-
- name = 'X:'||x||' Y:'||y;
- n = CwGetHandleFromObjectName( parent, name );
- if CwIsHandleValid( n ) then do;
- return 1;
- end;
- return 0;
-
- /*************************************************************************/
- evolve_cell:procedure expose scale;
- arg x, y, old_parent;
- old = find_cell( x, y, old_parent );
- neighbours = 0;
-
- neighbours = neighbours + find_cell( x-1, y-1, old_parent );
- neighbours = neighbours + find_cell( x-1, y, old_parent );
- neighbours = neighbours + find_cell( x-1, y+1, old_parent );
- neighbours = neighbours + find_cell( x, y-1, old_parent );
- neighbours = neighbours + find_cell( x, y+1, old_parent );
- neighbours = neighbours + find_cell( x+1, y-1, old_parent );
- neighbours = neighbours + find_cell( x+1, y, old_parent );
- neighbours = neighbours + find_cell( x+1, y+1, old_parent );
-
- if old & (neighbours = 2 | neighbours = 3) then;
- cell = create_cell( x, y );
- else if \old & neighbours = 3 then;
- cell = create_cell( x, y );
- return cell;
-
- /*************************************************************************/
- create_generation:procedure expose scale
- arg old_parent;
-
- /* first, figure out the area of the generation to create. It will be
- * just slightly (one cell) larger than the area covered by the last
- * generation. We also put in a generous safety margin. */
- call CwGetPosition old_parent, pos;
- left = TRUNC((pos.x - (pos.width/2))/scale) - 3;
- right = TRUNC((pos.x + (pos.width/2))/scale) + 3;
- top = TRUNC((pos.y + (pos.height/2))/scale) + 3;
- bottom = TRUNC((pos.y - (pos.height/2))/scale) - 3;
-
- parent = 0; /* the new generation has a new group */
-
- do x = left to right;
- do y = bottom to top;
- cell = evolve_cell( x, y, old_parent );
- if CwIsHandleValid( cell ) then do;
- parent = CwAddObjectToGroup( cell, parent );
- end;
- end;
- end;
-
- return parent;
-
- /*************************************************************************/
-