' Conway's Game of Life — 2D cellular automaton on flattened 1D grid
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL grid(6000) AS LONG
    LOCAL nextGrid(6000) AS LONG
    LOCAL width AS LONG
    LOCAL height AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL gen AS LONG
    LOCAL maxGen AS LONG
    LOCAL neighbors AS LONG
    LOCAL x AS LONG
    LOCAL y AS LONG
    LOCAL nx AS LONG
    LOCAL ny AS LONG
    LOCAL idx AS LONG
    LOCAL idxN AS LONG
    LOCAL lineStr AS STRING
    LOCAL aliveCount AS LONG
    width = 50
    height = 20
    maxGen = 30
    PRINT "============================================"
    PRINT "       CONWAY'S GAME OF LIFE"
    PRINT "============================================"
    PRINT ""
    PRINT "Glider pattern:"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    idx = 5 * width + 5
    grid(idx) = 1
    grid(idx + 1) = 1
    grid(idx + 2) = 1
    grid(idx + width) = 1
    grid(idx + 2 * width + 1) = 1
    FOR gen = 0 TO maxGen
        lineStr = ""
        aliveCount = 0
        FOR y = 0 TO height - 1
            lineStr = ""
            FOR x = 0 TO width - 1
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    lineStr = lineStr + "#"
                    aliveCount = aliveCount + 1
                ELSE
                    lineStr = lineStr + "."
                END IF
            NEXT x
            PRINT lineStr
        NEXT y
        PRINT "Generation " + STR$(gen) + " - Alive: " + STR$(aliveCount)
        PRINT ""
        FOR y = 0 TO height - 1
            FOR x = 0 TO width - 1
                neighbors = 0
                FOR ny = y - 1 TO y + 1
                    FOR nx = x - 1 TO x + 1
                        IF nx = x AND ny = y THEN
                            GOTO skip_neighbor
                        END IF
                        IF nx >= 0 AND nx < width AND ny >= 0 AND ny < height THEN
                            idxN = ny * width + nx
                            IF grid(idxN) = 1 THEN
                                neighbors = neighbors + 1
                            END IF
                        END IF
skip_neighbor:
                    NEXT nx
                NEXT ny
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    IF neighbors < 2 THEN
                        nextGrid(idx) = 0
                    ELSE
                        IF neighbors > 3 THEN
                            nextGrid(idx) = 0
                        ELSE
                            nextGrid(idx) = 1
                        END IF
                    END IF
                ELSE
                    IF neighbors = 3 THEN
                        nextGrid(idx) = 1
                    ELSE
                        nextGrid(idx) = 0
                    END IF
                END IF
            NEXT x
        NEXT y
        FOR i = 0 TO width * height - 1
            grid(i) = nextGrid(i)
        NEXT i
        IF aliveCount = 0 THEN
            EXIT FOR
        END IF
    NEXT gen
    PRINT "============================================"
    PRINT "     BLINKER (period 2 oscillator)"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    idx = 8 * width + 20
    grid(idx) = 1
    grid(idx + 1) = 1
    grid(idx + 2) = 1
    FOR gen = 0 TO 8
        PRINT "Gen " + STR$(gen) + ":"
        FOR y = 6 TO 10
            lineStr = ""
            FOR x = 18 TO 24
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    lineStr = lineStr + "#"
                ELSE
                    lineStr = lineStr + "."
                END IF
            NEXT x
            PRINT " " + lineStr
        NEXT y
        PRINT ""
        FOR y = 0 TO height - 1
            FOR x = 0 TO width - 1
                neighbors = 0
                FOR ny = y - 1 TO y + 1
                    FOR nx = x - 1 TO x + 1
                        IF nx = x AND ny = y THEN
                            GOTO skip2
                        END IF
                        IF nx >= 0 AND nx < width AND ny >= 0 AND ny < height THEN
                            idxN = ny * width + nx
                            IF grid(idxN) = 1 THEN
                                neighbors = neighbors + 1
                            END IF
                        END IF
skip2:
                    NEXT nx
                NEXT ny
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    IF neighbors < 2 THEN
                        nextGrid(idx) = 0
                    ELSE
                        IF neighbors > 3 THEN
                            nextGrid(idx) = 0
                        ELSE
                            nextGrid(idx) = 1
                        END IF
                    END IF
                ELSE
                    IF neighbors = 3 THEN
                        nextGrid(idx) = 1
                    ELSE
                        nextGrid(idx) = 0
                    END IF
                END IF
            NEXT x
        NEXT y
        FOR i = 0 TO width * height - 1
            grid(i) = nextGrid(i)
        NEXT i
    NEXT gen
    PRINT "============================================"
    PRINT "     BLOCK (still life)"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    idx = 10 * width + 25
    grid(idx) = 1
    grid(idx + 1) = 1
    grid(idx + width) = 1
    grid(idx + width + 1) = 1
    PRINT "Block pattern (should stay stable):"
    PRINT ""
    FOR gen = 0 TO 5
        PRINT "Gen " + STR$(gen) + ":"
        FOR y = 9 TO 12
            lineStr = ""
            FOR x = 24 TO 27
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    lineStr = lineStr + "#"
                ELSE
                    lineStr = lineStr + "."
                END IF
            NEXT x
            PRINT " " + lineStr
        NEXT y
        PRINT ""
        FOR y = 0 TO height - 1
            FOR x = 0 TO width - 1
                neighbors = 0
                FOR ny = y - 1 TO y + 1
                    FOR nx = x - 1 TO x + 1
                        IF nx = x AND ny = y THEN
                            GOTO skip3
                        END IF
                        IF nx >= 0 AND nx < width AND ny >= 0 AND ny < height THEN
                            idxN = ny * width + nx
                            IF grid(idxN) = 1 THEN
                                neighbors = neighbors + 1
                            END IF
                        END IF
skip3:
                    NEXT nx
                NEXT ny
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    IF neighbors < 2 THEN
                        nextGrid(idx) = 0
                    ELSE
                        IF neighbors > 3 THEN
                            nextGrid(idx) = 0
                        ELSE
                            nextGrid(idx) = 1
                        END IF
                    END IF
                ELSE
                    IF neighbors = 3 THEN
                        nextGrid(idx) = 1
                    ELSE
                        nextGrid(idx) = 0
                    END IF
                END IF
            NEXT x
        NEXT y
        FOR i = 0 TO width * height - 1
            grid(i) = nextGrid(i)
        NEXT i
    NEXT gen
    PRINT "============================================"
    PRINT "     TOAD (period 2 oscillator)"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    idx = 12 * width + 30
    grid(idx) = 1
    grid(idx + 1) = 1
    grid(idx + 2) = 1
    grid(idx + width + 1) = 1
    grid(idx + width + 2) = 1
    grid(idx + width + 3) = 1
    PRINT "Toad pattern:"
    FOR gen = 0 TO 6
        FOR y = 11 TO 14
            lineStr = ""
            FOR x = 29 TO 34
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    lineStr = lineStr + "#"
                ELSE
                    lineStr = lineStr + "."
                END IF
            NEXT x
            PRINT " " + lineStr
        NEXT y
        PRINT ""
        FOR y = 0 TO height - 1
            FOR x = 0 TO width - 1
                neighbors = 0
                FOR ny = y - 1 TO y + 1
                    FOR nx = x - 1 TO x + 1
                        IF nx = x AND ny = y THEN
                            GOTO skip4
                        END IF
                        IF nx >= 0 AND nx < width AND ny >= 0 AND ny < height THEN
                            idxN = ny * width + nx
                            IF grid(idxN) = 1 THEN
                                neighbors = neighbors + 1
                            END IF
                        END IF
skip4:
                    NEXT nx
                NEXT ny
                idx = y * width + x
                IF grid(idx) = 1 THEN
                    IF neighbors < 2 THEN
                        nextGrid(idx) = 0
                    ELSE
                        IF neighbors > 3 THEN
                            nextGrid(idx) = 0
                        ELSE
                            nextGrid(idx) = 1
                        END IF
                    END IF
                ELSE
                    IF neighbors = 3 THEN
                        nextGrid(idx) = 1
                    ELSE
                        nextGrid(idx) = 0
                    END IF
                END IF
            NEXT x
        NEXT y
        FOR i = 0 TO width * height - 1
            grid(i) = nextGrid(i)
        NEXT i
    NEXT gen
    PRINT ""
    PRINT "Conway's Game of Life complete"
    FUNCTION = 0
END FUNCTION
