/*
╔════════════════════════════════════════════════════════════════════════╗
║ ║
║ 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();
}