// life2.c
// Transcribe BASIC LIFE.bas to C, pointer version
// by Andre Adrian, DL1ADR, 2026-05-05

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define XSZ 50  // grid size rows
#define YSZ 70  // grid size columns
#define DD 0    // is death, becomes death
#define LL 1    // is live, becomes live
#define DL 2    // is death, becomes live
#define LD 3    // is live, becomes death

void TAB(int x) {
    while(--x) {
        printf(" ");
    }
}

int main() {
    char A[XSZ+1][YSZ+1], B[XSZ+1][40];
    memset(A, 0, sizeof(A));
    int C=0, G=0, P=0, E=0;
    TAB(34); printf("LIFE\n");
    TAB(15); printf("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"
                    "\n\n"
                    "ENTER YOUR PATTERN:\n");
    for (;;) {
        fgets(B[C], sizeof(B[0]), stdin);
        *strchr(B[C], '\n')='\0';
        if (strstr(B[C], "DONE")) {
            break;
        }
        ++C;
    }
    --C; unsigned L=0;
    for(int X=0; X<=C-1; ++X) {
        if (strlen(B[X])>L)
            L=strlen(B[X]);
    }
    int X1=XSZ/2-C/2, X2=X1+C;
    int Y1=YSZ/2-L/2, Y2=Y1+L;
    for (int X=0; X<=C; ++X) {
        for (unsigned Y=0; Y<strlen(B[X]); ++Y) {
            if (B[X][Y]=='*') {
                A[X1+X][Y1+Y]=1; ++P;
            }
        }
    }
    printf("\n\n");
    for(;;) {
        int X4=2, X3=XSZ-2, Y4=2, Y3=YSZ-2;
        for (int X=1; X<=X1-1; ++X) printf("\n");
        printf("\n");
        char* pX=&A[X1][0];
        for (int X=X1; X<=X2; ++X, pX+=(YSZ+1)) {
            TAB(Y1);
            char* pY=pX+Y1;
            for (int Y=Y1; Y<=Y2; ++Y, ++pY) {
                if (*pY==DD || *pY==LD) {
                    *pY=DD; printf(" "); continue;
                }
                *pY=LL; printf("*");
                if (X<X3) X3=X;
                if (X>X4) X4=X;
                if (Y<Y3) Y3=Y;
                if (Y>Y4) Y4=Y;
            }
            printf("\n");
        }
        for (int X=X2+1; X<=XSZ-1; ++X) printf("\n");
        printf("GENERATION: %d\t\tPOPULATION: %d ", G, P);
        if (E) printf("INVALID %d", E);
        if (P==0) break;
        sleep(1);
        X1=X3; X2=X4; Y1=Y3; Y2=Y4; ++G; P=0; E=0;
        if (X1<2) { X1=2; E=1; }
        if (X2>XSZ-2) { X2=XSZ-2; E+=2; }
        if (Y1<2) { Y1=2; E+=4; }
        if (Y2>YSZ-2) { Y2=YSZ-2; E+=8; }
        pX=&A[X1-1][0];
        for (int X=X1-1; X<=X2+1; ++X, pX+=(YSZ+1)) {
            char* pY=pX+Y1-1;
            for (int Y=Y1-1; Y<=Y2+1; ++Y, ++pY) {
                C=0;
                char* pI=pY-(YSZ+1);
                for (int I=X-1; I<=X+1; ++I, pI+=(YSZ+1)) {
                    char* pJ=pI-1;
                    for (int J=Y-1; J<=Y+1; ++J, ++pJ) {
                        if (*pJ&1)
                            ++C;
                    }
                }
                if (*pY==DD) goto L570;
                if (C<3 || C>4) {
                    *pY=LD; continue;
                }
                ++P; continue;
L570:
                if(C==3) {
                    *pY=DL; ++P;
                }
            }
        }
        --X1; --Y1; ++X2; ++Y2;
    }
}
