Metropoli BBS
VIEWER: lifeca.c MODE: TEXT (CP437)
/*
  ╔════════════════════════════════════════════════════════════════════════╗
  ║                                                                        ║
  ║      2 State Finite Closed 2-Dimensional Life Cellular Automation      ║
  ║                                                                        ║
  ║                   (c) 1991 Christopher D. Watkins                      ║
  ║                                                                        ║
  ╚════════════════════════════════════════════════════════════════════════╝
*/

#include "stdio.h"
#include "dos.h"
#include "string.h"
#include "defs.h"
#include "globals.h"
#include "mathb.h"
#include "graphb.h"

#define MaxColumn 100
#define MaxRow 100
#define States 2
#define MaxState (States-1)
#define Born 1
#define Dead 0
#define WorldTop (MaxColumn-1)
#define WorldSide (MaxRow-1)

typedef Byte State[2];
typedef Byte WorldArray[WorldTop+1][WorldSide+1];
typedef Byte Rule[2][2][2][2][2][2][2][2][2];

WorldArray NewWorld;
WorldArray OldWorld;
WorldArray TempWorld;
Rule Rules;

void DoWorld()
{
  Word i, j;
  Byte col;
  Boolean LowI, HighI;
  Boolean LowJ, HighJ;

  for(i=0; i<=WorldTop; i++)
  {
    LowI=(i==0);
    HighI=(i==WorldTop);
    for(j=0; j<=WorldSide; j++)
    {
      LowJ=(j==0);
      HighJ=(j==WorldSide);
				/*  Mod operations can be used here -  */
				/*  but the logical testing is faster  */
      if(!(LowI||HighI||LowJ||HighJ))
	NewWorld[i][j]=Rules[OldWorld[i-1][j-1]]
			    [OldWorld[i][j-1]]
			    [OldWorld[i+1][j-1]]
			    [OldWorld[i-1][j]]
			    [OldWorld[i][j]]
			    [OldWorld[i+1][j]]
			    [OldWorld[i-1][j+1]]
			    [OldWorld[i][j+1]]
			    [OldWorld[i+1][j+1]];
      else
      {
	if((LowI||HighI)&& !(LowJ||HighJ))
	{
	  if(LowI)
	    NewWorld[i][j]=Rules[OldWorld[WorldTop][j-1]]
				[OldWorld[i][j-1]]
				[OldWorld[i+1][j-1]]
				[OldWorld[WorldTop][j]]
				[OldWorld[i][j]]
				[OldWorld[i+1][j]]
				[OldWorld[WorldTop][j+1]]
				[OldWorld[i][j+1]]
				[OldWorld[i+1][j+1]];
	  else
	    NewWorld[i][j]=Rules[OldWorld[i-1][j-1]]
				[OldWorld[i][j-1]]
				[OldWorld[0][j-1]]
				[OldWorld[i-1][j]]
				[OldWorld[i][j]]
				[OldWorld[0][j]]
				[OldWorld[i-1][j+1]]
				[OldWorld[i][j+1]]
				[OldWorld[0][j+1]];
	}
	else
	{
	  if((LowJ||HighJ)&& !(LowI||HighI))
	  {
	    if(LowJ)
	      NewWorld[i][j]=Rules[OldWorld[i-1][WorldSide]]
				  [OldWorld[i][WorldSide]]
				  [OldWorld[i+1][WorldSide]]
				  [OldWorld[i-1][j]]
				  [OldWorld[i][j]]
				  [OldWorld[i+1][j]]
				  [OldWorld[i-1][j+1]]
				  [OldWorld[i][j+1]]
				  [OldWorld[i+1][j+1]];
	    else
	      NewWorld[i][j]=Rules[OldWorld[i-1][j-1]]
				  [OldWorld[i][j-1]]
				  [OldWorld[i+1][j-1]]
				  [OldWorld[i-1][j]]
				  [OldWorld[i][j]]
				  [OldWorld[i+1][j]]
				  [OldWorld[i-1][0]]
				  [OldWorld[i][0]]
				  [OldWorld[i+1][0]];
	  }
	  else
	  {
	    if(LowI&&LowJ)
	      NewWorld[i][j]=Rules[OldWorld[WorldTop][WorldSide]]
				  [OldWorld[i][WorldSide]]
				  [OldWorld[i+1][WorldSide]]
				  [OldWorld[WorldTop][j]]
				  [OldWorld[i][j]]
				  [OldWorld[i+1][j]]
				  [OldWorld[WorldTop][j+1]]
				  [OldWorld[i][j+1]]
				  [OldWorld[i+1][j+1]];
	    else
	    {
	      if(LowI&&HighJ)
		NewWorld[i][j]=Rules[OldWorld[WorldTop][j-1]]
				    [OldWorld[i][j-1]]
				    [OldWorld[i+1][j-1]]
				    [OldWorld[WorldTop][j]]
				    [OldWorld[i][j]]
				    [OldWorld[i+1][j]]
				    [OldWorld[WorldTop][0]]
				    [OldWorld[i][0]]
				    [OldWorld[i+1][0]];
	      else
	      {
		if(HighI&&LowJ)
		  NewWorld[i][j]=Rules[OldWorld[i-1][WorldSide]]
				      [OldWorld[i][WorldSide]]
				      [OldWorld[0][WorldSide]]
				      [OldWorld[i-1][j]]
				      [OldWorld[i][j]]
				      [OldWorld[0][j]]
				      [OldWorld[i-1][j+1]]
				      [OldWorld[i][j+1]]
				      [OldWorld[0][j+1]];
		else
		  NewWorld[i][j]=Rules[OldWorld[i-1][j-1]]
				      [OldWorld[i][j-1]]
				      [OldWorld[0][j-1]]
				      [OldWorld[i-1][j]]
				      [OldWorld[i][j]]
				      [OldWorld[0][j]]
				      [OldWorld[i-1][0]]
				      [OldWorld[i][0]]
				      [OldWorld[0][0]];
	      }
	    }
	  }
	}
      }
      if(NewWorld[i][j]==0)
	Plot(i, j, 0);
      else
	Plot(i, j, 127);
    }
  }
  memcpy(TempWorld, NewWorld, sizeof(NewWorld));
  memcpy(NewWorld, OldWorld, sizeof(OldWorld));
  memcpy(OldWorld, TempWorld, sizeof(TempWorld));
}

typedef char Name[33];

Name WorldFileName;
FILE *WorldFile;

void LoadWorld()
{
  Word i, j;

  /*  Read World From File  */

  fread(OldWorld, sizeof(OldWorld), 1, WorldFile);
  fclose(WorldFile);
}

Name RuleFileName;
FILE *RuleFile;

void LoadRules()
{
  fread(Rules, sizeof(Rules), 1, RuleFile);
  fclose(RuleFile);
}

void ClearMemory()
{
  Word i, j, k, l, m, n, p, q, r;

  for(i=0; i<=WorldTop; i++)
  {
    for(j=0; j<=WorldSide; j++)
    {
      NewWorld[i][j]=Dead;
      OldWorld[i][j]=Dead;
      TempWorld[i][j]=Dead;
    }
  }
  for(i=0; i<=MaxState; i++)
  {
    for(j=0; j<=MaxState; j++)
    {
      for(k=0; k<=MaxState; k++)
      {
	for(l=0; l<=MaxState; l++)
	{
	  for(m=0; m<=MaxState; m++)
	  {
	    for(n=0; n<=MaxState; n++)
	    {
	      for(p=0; p<=MaxState; p++)
	      {
		for(q=0; q<=MaxState; q++)
		{
		  for(r=0; r<=MaxState; r++)
		      Rules[i][j][k][l][m][n][p][q][r]=Dead;
		}
	      }
	    }
	  }
	}
      }
    }
  }
}

Palette_Register PalArray;

void main()
{
  ClearMemory();
  strcpy(WorldFileName,"LWORLD.CA");
  strcpy(RuleFileName,"LRULE.CA");
  WorldFile=fopen(WorldFileName, "rb");
  RuleFile=fopen(RuleFileName, "rb");
  LoadRules();
  LoadWorld();
  Init_Graphics(19);
  Init_Palette(PalArray);
  Set_Palette(PalArray);
  do
  {
    DoWorld();
  }
  while(!kbhit());
  Exit_Graphics();
}
[ RETURN TO DIRECTORY ]