[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::amiga_v1

Title:AMIGA NOTES
Notice:Join us in the *NEW* conference - HYDRA::AMIGA_V2
Moderator:HYDRA::MOORE
Created:Sat Apr 26 1986
Last Modified:Wed Feb 05 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:5378
Total number of notes:38326

2804.0. "Cellular Automata" by WJG::GUINEAU (Only obvious to the casual observer) Mon Aug 07 1989 11:52

Here's a little something hacked together last night (after spending all day
recovering from a &^%# CBM picked Rodime JUNK disk crash! Anyone know
CBM's customer support number?).

It's from the August 1989 issue of Scientific American's Computer Recreations
column. 

		WJG::AMIGA:CELLAUTO.ZOO

Here's the docs:


This is a Cellular Automata program using an algorithm taken 
from the Computer Recreations column of the August 1989 issue of 
Scientific American.

Public Domain, Have Fun! 

So what does it do?  It simulates cyclic space. Basically, you have 
a bunch of cells (pixels) and a defined set of states (colors). Each cell
starts out in a random state. Successive generations are calculated
according to a simple rule: If any neighbor of a cell is in state n-1,
where n is the state of the cell in question, then that neighbor
becomes the same state as the cell. In other words, cells of state n eat
neighboring cells of state n-1, making them state n (just like we
convert suitable food into us). The result is quite amazing - 
Run it and see!

Be patient. Amy's quick (esp an A2500!), but there's a lot to
do to get to the end. The window starts out as colored confetti.
Eventually blotches appear, they grow and shrink, and then...

Read the article and the source for more info :-) The interesting thing
is that the ending result is always the same!

The program will use either a 320x200 or a 640x200 screen, 16 colors
and a window of your specified size and max colors.

Usage:

	CA width height #colors resolution(L or H)

defaults are 320x200 (low res) 12 colors with a 100x100 window.

If you have an 020 or lots of time, try something like:

	CA 250 100 16 H

This will make a 640x200 (hires) screen 16 colors with a 250x100 window.

At the bottom of the screen is a second window which simply displays
the color corresponding to each state for reference (actually for
debugging!).



The program is written using old[] and new[] state arrays as the author
of the article suggests. I believe it would be *much* faster to use a
double buffered display - each bitmap being an array - and calculate
one while the other is being displayed. the majority of time taken
by this program is in the writing of the pixels. Directly changing
alternate bitmaps during calculations and then swapping the active bitmap
would be a great improvement. Anyone interested in doing this?!?


Compiled with Lattice C 5.02

This zoo contains:

	ca.doc		this file
	ca.c		source
	ca.h		   code
	ca		executable (lc -L -O ca)
	ca020		68020 only (lc -L -m2 -O ca)



If you'ld like, send me mail about bugs or whatever at:


	John Guineau
	3 Royal Crest Dr. #9
	Marlboro, Ma. 01752
	(508) 485-6233 (after 8:00 PM EST)



T.RTitleUserPersonal
Name
DateLines
2804.1free help for what it's worthMANTIS::LONGMon Aug 07 1989 18:2870
John,
	You should find this a lot faster, there was a bit too much happening
within the loop ( the extra assignments and recalculation of constants always
get me too ).  Amazing how I can never find this kind of thing in my own code!

	Dick

void InitArrays()
  {
    int i,
        j = maxx+maxy;
        k = MaxStates+1;

    srand( time( 0 ));
    for ( i = 0, i < j, i++ )
      {
       new[i] = (UBYTE)((rand() >> new[i-1]) % k );    
       old[i] = new[i];
      }
  }

Just out of interest, how does Lattice C do an operation like
	old = new = operation; ?

   1. new = operation;
      old = operation;
    
or 2. new = operation;
      old = new;

I don't have Lattice C but I did find the following double buffered display 
code fragment a few weeks ago that may be of help.

	InitBitMap (&bm1, deep, wide, high);
	InitBitMap (&bm2, deep, wide, high);
	InitVPort (&vp1);
	InitVPort (&vp2);
	InitView (&v1);
	InitView (&v2);
 
	v1.ViewPort = &vp1;
	v2.ViewPort = &vp2;
 
	rasinfo1.BitMap = &bm1;
	rasinfo2.BitMap = &bm2;
	rasinfo1.Next = rasinfo2.Next = NULL;
 
	vp1.RasInfo = &rasinfo1;
	vp2.RasInfo = &rasinfo2;
 
	MakeVPort (&v1, &vp1);
	MakeVPort (&v2, &vp2);
	MrgCop (&v1);
	MrgCop (&v2);
--------
 
	At this point (.), you can LoadView() either v1 or v2, and it'll pop
onto your screen at the next VBLANK.  Much less pain and misery all around.


Also, one little macro for you from a lazy typist ;^}

#define CLEAN_EXIT(string,exit_value) /
      { /
        printf( string ); /
        CleanUp(); /
        exit( exit_value ); /
      }

      CLEAN_EXIT("no graphics library!!!\n",13)
2804.2What a C compiler would doTLE::RMEYERSRandy MeyersMon Aug 07 1989 21:1522
Re: .1

>Just out of interest, how does Lattice C do an operation like
>	old = new = operation; ?
>
>   1. new = operation;
>      old = operation;
>    
>or 2. new = operation;
>      old = new;

Since I am not in the business of testing Lattice C for bugs, I can't
promise what Lattice C for the above case.

However, I am in the business of saying what is C and what isn't.  A
C compiler must evaluate old = new = operation as 

	2. new = operation
	   old = new

or act as if it had (what I mean by that is very complex).  Assume
that the compiler acts the way that I described.
2804.33x for "free"WJG::GUINEAUOnly obvious to the casual observerTue Aug 08 1989 01:1150
Re .1:

I like the optimization you did on InitArrays()! I'll have to remember it
for later code. For now, InitArrays only gets called once at the start of the
program so a small hit there isn't so bad.

There is another version of CellAuto.zoo on WJG::

Following is the readme that tells the story...


7/7/89


Well, there I was; explaining to my roomate some grand plans for speeding
up this program: "I'm not going to use a double buffered display as I
originally thought.", I began, " Instead I will simply create a second
BitMap to swap with the original in the windows RastPort. I'll use each
bitmap as an array thereby eliminating the old[] and new[] arrays and do
calculations directly on the bitmaps. Then I'll WritePixel..", 
He interrupted, not quite grasping what I was rattling on about: 

"And only write the ones that changed?", he asked... 

Of course!, I thought. All the time was obviously being wasted in the
WritePixel() routine (shuffling through those PLANEPTR's
is hazardous to Amys CPU health!). If I skipped WritePixel() for
the cases where old[i] == new[i], things should improve...

So here it is. Ignore what I say in the docs about a double buffered
display ;-) I just added the line:

		if(old[i] != new[i]) {
                

                };

around the SetAPEN(), WritePixel() in DrawCells() and voila! 
 a 3x increase in speed! 

[ Thats 300% Jeff, hope your next raise is so good :-) ]

See for yourself! The zoo now has the old program as oldca and oldca020.
The source is updated and ca, ca020 are the new faster versions.




John
2804.4WOW!SPIDER::LONGTue Aug 08 1989 01:469
Just got a chance to run the slow version and was quite surprised ( especially
after having looked over the code).  Guess I'll have to port it to MANX and
play some more with it.

BTW: at the end of the include file there is a reference to "powerwindows"???
Do you have some tool to generate the window structures for you?


	Dick
2804.5Power Windows 2.5WJG::GUINEAUOnly obvious to the casual observerTue Aug 08 1989 11:4130
Yes, PowerWindows is invaluable for creating intuition based user interfaces.

It allows you to play around with all the standard stuff (screens,windows,
gadgets etc) on screen, with the mouse and edit their characteristics,
sizes positions. It even allows loading brush images and hand tailoring borders.

It will then generate source code in several languages (Lattice C, Manx C,
Assembly, Modula II, BASIC etc.!).  You can save the interface in thier
own format for later editing. 

It even allows you to grab another window or screen running on the system
with all it's gadgets. You can then examine/edit/generate_source for that
(those) windows!

When used in conjunction with InovaTools, you get a file requestor and "Knob"
gadgets (look like a round volume control on a stereo).

Did I forget anything?

Moe tossed it in when I bought my A2500 from him. See, he's not such a bad guy!
(Don't tell him I told you!)

I used it to generate the screen and windows for CellAuto. I did need to later
edit ca.h and add all those Image structures so the STATES window would display
each color gadget as a solid color (After John Osborn told me how way back
on CM!).  Other than that, PowerWindows is pretty complete.


John
2804.6Oh,WJG::GUINEAUOnly obvious to the casual observerTue Aug 08 1989 11:4720
I guess going the pseudo double buffered (just swapping the Window's RastPort's 
BitMap) would probably not speed things up much. In fact, it might even
slow things down!

The problem is in the way BitMaps, or more specifically Planes, are stored.
In the BitMap structure (which hangs off the RastPort of the Window) is an
array of pointers. Each pointer points to one plane. So to get/set the value
of a pixel, you need to get a bit from each plane then contruct a color value
(UWORD) from them. I assume this is what ReadPixel() and WritePixel() do and
they are probably optimised as best as they could be (I aim to look in the RKM
source listings to see how CBM did it).

So doing double-bitmap stuff on the window, while a neat trick, would
require getting and setting the pixel values from the bitmap, probably
using ReadPixel() and WritePixel() which are already  Slooooow.

Amiga Experts, Am I missing something here?


John
2804.7Protection time...FROCKY::BALZERChristian Balzer DTN:785-1029Tue Aug 08 1989 13:216
    Uh, John, 
    how about setting the protection of cellauto.zoo in a way us lower
    lifeforms can access it? :-)
    
    Thanks,
    <CB>
2804.8Sorry!WJG::GUINEAUOnly obvious to the casual observerTue Aug 08 1989 14:400