about summary refs log tree commit diff stats
path: root/lua/life.lua
blob: f4d5a0d525d677407f3ebc69ded7c1aee97bd3bd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
local initialBoard = {
  {0, 1, 0},
  {0, 0, 1},
  {1, 1, 1},
  {0, 0, 0}
}

local function deepcopy(orig)
  local orig_type = type(orig)
  local copy
  if orig_type == 'table' then
    copy = {}
    for orig_key, orig_value in next, orig, nil do
      copy[deepcopy(orig_key)] = deepcopy(orig_value)
    end
    setmetatable(copy, deepcopy(getmetatable(orig)))
  else -- number, string, boolean, etc
    copy = orig
  end
  return copy
end

local function getNextState(board)
  local rows = #board
  local cols = #board[1]

  local function countLiveNeighbors(board, x, y)
    local count = 0
    for dx = -1, 1 do
      for dy = -1, 1 do
        if not (dx == 0 and dy == 0) then
          local nx, ny = x + dx, y + dy
          if nx >= 1 and nx <= rows and ny >= 1 and ny <= cols then
            count = count + board[nx][ny]
          end
        end
      end
    end
    return count
  end

  local nextBoard = deepcopy(board)

  for x = 1, rows do
    for y = 1, cols do
      local liveNeighbors = countLiveNeighbors(board, x, y)
      if board[x][y] == 1 and (liveNeighbors < 2 or liveNeighbors > 3) then
        nextBoard[x][y] = 0
      elseif board[x][y] == 0 and liveNeighbors == 3 then
        nextBoard[x][y] = 1
      end
    end
  end

  return nextBoard
end

local function printBoard(board)
  io.write("\27[2J\27[H") -- clear console
  for _, row in ipairs(board) do
    for _, cell in ipairs(row) do
      io.write(cell == 1 and "1 " or "0 ")
    end
    io.write("\n")
  end
end

local function runGame(initialBoard, generations)
  local board = initialBoard
  for i = 1, generations do
    printBoard(board)
    board = getNextState(board)
    os.execute("sleep 0.5") -- Wait 0.5 seconds between generations
  end
end

runGame(initialBoard, 10)