home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Educational / HodgePodge3 / Source / HodgePodge.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  4.1 KB  |  142 lines

  1. // HodgePodge.m --
  2.  
  3. // PAK 7/31/88 -- coded on Aari ST
  4. // PAK 4/26/92 -- ported to NeXT
  5. // PAK 11/1/92 -- trying 4-bit Color-station format
  6.  
  7. #import "math.h"
  8. #import <appkit/NXBitmapImageRep.h>
  9. #import "HodgePodge.h"
  10.  
  11. @implementation HodgePodge
  12.  
  13. long random();
  14. void wrap_cell_edges();
  15. HodgePodge *Self;
  16.  
  17. - init
  18. {    [super init];
  19.     Cf = &z1;
  20.     Ct = &z2;
  21.     return [self Randomize :nil];
  22. }
  23.  
  24. - Randomize :sender;
  25. {    int i, j;
  26.     for (i=1; i<=c_yh; i++)
  27.         for (j=1; j<=c_xw; j++)
  28.             (*Cf)[i][j] = random() % (n);
  29.     wrap_cell_edges(Cf);
  30.     return self;
  31. }
  32.  
  33. - drawSelf:(const NXRect *)rects :(int)rectCount
  34. {    n                     = rint([NumStates floatValue]);
  35.     force                 = [DrivingForce floatValue]*n;
  36.     Healthy2Sick         = [HealthysAffectOnSick floatValue]*n/8;
  37.     Recover2Sick         = [RecoveringsAffectOnSick floatValue]*n/8;
  38.     cellsHorizontally     = [CellsHorizontally floatValue];
  39.     cellsVertically     = [CellsVertically floatValue];
  40.     intiTimedEntry([MaxFramesPsecond floatValue]);
  41.     initTable([DisplayColorPhase floatValue], [DisplayColorDir floatValue]);
  42.     if (bitmap == 0)
  43.     {    bitmap = [[NXBitmapImageRep alloc]         initData:(unsigned char *)image 
  44.                 pixelsWide :c_xw                pixelsHigh :c_yh
  45.                 bitsPerSample:4                    samplesPerPixel:Ncolors+1
  46.                 hasAlpha:YES                    isPlanar:NO
  47.                 colorSpace:Ncolors>1? NX_RGBColorSpace:NX_OneIsWhiteColorSpace
  48.                 bytesPerRow:0                    bitsPerPixel:0];
  49.         [self setOpaque:YES];
  50.         [self compute];
  51.     }
  52.     [bitmap drawIn :&bounds];
  53.     return self;
  54. }
  55.  
  56. /*
  57.  *    Each cell has a Health h, an integer from 0 to N.
  58.  *    If the cell is recovering (0 < h < N), its new health is the average of
  59.  *        its 8 neighbors plus a Curing Force f, expressed as a fraction of N.
  60.  *    If the cell is sick (h = 0), its new health is A * the number of healthy
  61.  *        neighbors plus B * the number of recovering neighbors.
  62.  *    If the cell is healthy (h = N), it becomes sick (presumably from 
  63.  *        complacency).
  64.  */    
  65. - (void)compute
  66. {    register int j;
  67.     register cell_image *pCf;        // Pointer to Cell_image, From buffer
  68.     register cell_image *pCt, *tmp;    // Pointer to Cell_image, To buffer
  69.     register colorStationPixel *pS;    // Pointer to Screen_image
  70.     register int x, y;
  71.     register int s;
  72.     register int a, b;
  73.     register int sick=0, healthy=n;
  74.  
  75.     Self = self;
  76.     if (Cf == 0)
  77.         [self init];
  78.     for (y=1; y<=c_yh; y++)                    //iterate over Y (except edges)
  79.     {    pCf = (cell_image *)&(*Cf)[y][1];
  80.         pCt = (cell_image *)&(*Ct)[y][1];
  81.         pS = (colorStationPixel *)&image[y-1][0];
  82.         for (x=1; x<=c_xw; x++)                //iterate over X (except edges)
  83.         {    j = (*pCf)[0][0];
  84.             if (j <= sick)            // SICK: look at 8 neighbors
  85.             {    a = 0;                    // count of sick neighbors
  86.                 b = 0;                    // count of recovering neighbors
  87.                 (j=(*pCf)[-1][-1])? (j>=healthy? a++: b++): 0;
  88.                 (j=(*pCf)[-1][ 0])? (j>=healthy? a++: b++): 0;
  89.                 (j=(*pCf)[-1][ 1])? (j>=healthy? a++: b++): 0;
  90.                 (j=(*pCf)[ 0][-1])? (j>=healthy? a++: b++): 0;
  91.                 (j=(*pCf)[ 0][ 1])? (j>=healthy? a++: b++): 0;
  92.                 (j=(*pCf)[ 1][-1])? (j>=healthy? a++: b++): 0;
  93.                 (j=(*pCf)[ 1][ 0])? (j>=healthy? a++: b++): 0;
  94.                 (j=(*pCf)[ 1][ 1])? (j>=healthy? a++: b++): 0;
  95.                 s = a * Healthy2Sick  +  b * Recover2Sick;
  96.             }
  97.             else if (j < healthy)    // RECOVERING: average neighbors, + force
  98.                 s=  ((*pCf)[-1][-1]+(*pCf)[-1][0]+(*pCf)[-1][1]
  99.                     +(*pCf)[0][-1]               +(*pCf)[0][1]
  100.                     +(*pCf)[1][-1] +(*pCf)[1][0] +(*pCf)[1][1])/8.0 + force;
  101.             else                    // HEALTHY: become sick again
  102.                 s = 0;
  103.  
  104.             (*pCt)[0][0] = s = s>n? n: s;
  105.  
  106.             s = s*255/n;
  107.             pS->alpha = -1;
  108.             pS->red   = redTable[s];
  109.             pS->green = greenTable[s];
  110.             pS->blue  = blueTable[s];
  111.             pS++;
  112.  
  113.             pCf = (cell_image *)&(*pCf)[0][1];
  114.             pCt = (cell_image *)&(*pCt)[0][1];
  115.     }    }
  116.  
  117.     tmp = Cf; Cf = Ct; Ct = tmp;
  118.     wrap_cell_edges(Cf);
  119. }
  120.  
  121. // makes the area conform to a torus:
  122. //             row/col 0 and row/col N+1 are replicated    
  123. void wrap_cell_edges(Cf)
  124. register cell_image *Cf;
  125. {    register int x, y;
  126.     int w = Self->c_xw, h = Self->c_yh;
  127.     for (x=1; x<=w; x++)
  128.     {    (*Cf)[h+1][x] = (*Cf)[1][x];
  129.         (*Cf)[0  ][x] = (*Cf)[h][x];
  130.     }
  131.     for (y=1; y<=h; y++)
  132.     {    (*Cf)[y][w+1] = (*Cf)[y][1];
  133.         (*Cf)[y][0  ] = (*Cf)[y][w];
  134.     }
  135.     (*Cf)[0  ][0  ] = (*Cf)[h][w];
  136.     (*Cf)[h+1][w+1] = (*Cf)[1][1];
  137.     (*Cf)[0  ][w+1] = (*Cf)[h][1];
  138.     (*Cf)[h+1][0  ] = (*Cf)[1][w];
  139. }
  140.  
  141. @end
  142.