Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Gridv2

import random
from collections import Optional
from memory import UnsafePointer, memcpy, memset_zero
from gridv1 import Grid as GridV1

struct Grid(Stringable, Writable):
    var data: UnsafePointer[UInt8]
    var rows: Int
    var cols: Int

    def __init__(out self, rows: Int, cols: Int):
        self.rows = rows
        self.cols = cols
        self.data = UnsafePointer[UInt8].alloc(rows * cols)

    def __init__(out self, source: GridV1):
        rows = len(source.data)
        cols = len(source.data[0])
        self = Self(rows, cols)
        for row in range(rows):
            for col in range(cols):
                value = UInt8(source[row, col])
                (self.data + row * cols + col)[] = value

    def __copyinit__(out self, existing: Self):
        self.rows = existing.rows
        self.cols = existing.cols
        count = self.rows * self.cols
        self.data = UnsafePointer[UInt8].alloc(count)
        memcpy(dest=self.data, src=existing.data, count=count)

    def __moveinit__(out self, owned existing: Self):
        self.data = existing.data
        self.rows = existing.rows
        self.cols = existing.cols
    
    def __del__(owned self):
        self.data.free()    

    def __str__(self) -> String:
        capacity = self.rows * self.cols
        if capacity == 0:
            return String()
        s = String(capacity=capacity)
        for row in range(self.rows):
            for col in range(self.cols):
                # if (self.data + row * self.cols + col)[] == 1:
                if self[row, col] == 1:
                    s += "*"  # Alive cell represented by '*'
                else:
                    s += " "  # Dead cell is blank
            if row != self.rows - 1:
                s += "\n"  # Line break between rows
        return s

    def write_to[W: Writer](self, mut writer: W) -> None:
        writer.write(self.__str__())

    def __getitem__(self, row: Int, col: Int) -> UInt8:
        return (self.data + row * self.cols + col)[]

    def __setitem__(mut self, row: Int, col: Int, value: UInt8) -> None:
        (self.data + row * self.cols + col)[] = value

    @staticmethod
    def new(seed: Optional[Int], rows: Int, cols: Int) -> Self:
        if seed:
            random.seed(seed.value())
        else:
            random.seed()
        grid = Self(rows, cols)
        random.randint(grid.data, rows * cols, 0, 1)
        return grid

    def mutate(mut self) -> None:
        rows = self.rows
        cols = self.cols
        for row in range(rows):
            above = (row - 1) % rows
            below = (row + 1) % rows
            for col in range(cols):
                left = (col - 1) % cols
                right = (col + 1) % cols
                alive_neighbours = (
                    self[above, left]
                    + self[above, col]
                    + self[above, right]
                    + self[row, right]
                    + self[below, right]
                    + self[below, col]
                    + self[below, left]
                    + self[row, left]
                )
                if self[row, col] == 1:
                    if alive_neighbours < 2:
                        self[row, col] = 0
                    if alive_neighbours == 2 or alive_neighbours == 3:
                        continue
                    if alive_neighbours > 3:
                        self[row, col] = 0
                else:
                    if alive_neighbours == 3:
                        self[row, col] = 1


def run(owned grid: Grid) raises -> None:
    while True:
        print("Current mutation:\n\n")
        print(grid)
        print()
        print()
        if input("Enter 'q' to quit or press <Enter> to continue: ") == "q":
            break
        grid.mutate()


def main() raises -> None:
    grid_1 = GridV1.new(16, 16)
    # run(grid_1)
    print(grid_1)
    print("Implicit conversion\n\n")
    grid_2 = Grid(grid_1)
    print(grid_2)

View source on GitHub