From e57b5011781f982fb392392518155ad150060129 Mon Sep 17 00:00:00 2001 From: Baipyrus Date: Sun, 14 Apr 2024 21:20:26 +0200 Subject: [PATCH] implement conways game of life --- conway.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/conway.go b/conway.go index 189371a..2c5c05a 100644 --- a/conway.go +++ b/conway.go @@ -1,7 +1,8 @@ package main import ( - "github.com/go-resty/resty/v2" + "errors" + "time" ) type Cell struct { @@ -10,20 +11,96 @@ type Cell struct { live bool } -func (c *Cell) NeighborCount() int { - +func (c *Cell) NeighborCount(arr [][]Cell) int { + count := 0 + // Iterate through 3x3 neighboring grid + for i := -1; i <= 1; i++ { + for j := -1; j <= 1; j++ { + // Ignore own position + if i == 0 && j == 0 { + continue + } + // Get neighbor coordinates + nx, ny := c.x+i, c.y+j + // Check if neighbor is within bounds + if nx < 0 || nx >= len(arr) || ny < 0 || ny >= len(arr[0]) { + continue + } + // Count if neighbor is alive + if arr[nx][ny].live { + count++ + } + } + } + return count } -func coordinatesToIndex(x int, y int) int { - return x + y*width +func initGrid(width, height int, parent ...[][]Cell) ([][]Cell, error) { + exists := len(parent) == 1 + if exists && len(parent) > 1 { + return nil, errors.New("Too many parents specified") + } + + // Make first dimension + cells := make([][]Cell, width) + for i := 0; i < width; i++ { + // Make second dimension + cells[i] = make([]Cell, height) + for j := 0; j < height; j++ { + // Make cells + cells[i][j].x = i + cells[i][j].y = j + // If specified, copy state from parent + if exists { + cells[i][j].live = parent[0][i][j].live + } + } + } + return cells, nil } -var grid []Cell +const FPS = 10 -func setup(client *resty.Client, url, width int, height int) { +var grid [][]Cell +func setup(callback func([][]Cell), width, height int) { + grid, _ = initGrid(width, height) + + // Prepare + ticker := time.NewTicker(time.Second / FPS) + done := make(chan bool) + + go func() { + for { + select { + case <-done: + return + case <-ticker.C: + draw(callback) + } + } + }() } -func draw() { - +func draw(callback func([][]Cell)) { + generation, _ := initGrid(len(grid), len(grid[0]), grid) + // Iterate through grid + for i := 0; i < len(grid); i++ { + for j := 0; j < len(grid[0]); j++ { + // Count neighbors + cout := grid[i][j].NeighborCount(grid) + // Get state + curr := grid[i][j].live + // Apply rules + died := curr && (cout < 2 || cout > 3) + born := !curr && cout == 3 + next := curr && !died || born + // Set state + generation[i][j].live = next + // A * !(A * (B + C)) + !A * D + // = A * !B * !C + !A * D + // curr && cout >= 2 && cout <= 3 || !curr && cout == 3 + } + } + callback(generation) }