Игра жизни Конвея: почему паттерны ведут себя неправильно?

Я пытаюсь создать реализацию игры жизни Конвея в Lua.

Игровое поле представляет собой двумерную круглую таблицу со 100 строками и 47 столбцами (всего 4700 ячеек), где ячейка может иметь значение 1 (живой) или 0 (мертвый).

Проблема в том, что когда я пытаюсь создать мерцатель и сделать шаблон из 3 живых клеток рядом друг с другом, обе боковые клетки умирают в следующем поколении, и никакие другие не становятся живыми. Я также пытался создать планер, но в следующем поколении верхняя средняя ячейка и нижняя левая умерли, а затем рисунок стал неподвижным.

Когда я пытался отладить, все переменные, казалось, имели правильные значения, поэтому я думаю, что проблема где-то в присвоении значения в функции nextGen() из таблицы field в nfield и наоборот. Что я могу делать неправильно?

-- Game window's width and height. 
-- Rows 48, 49, and 50 are used for control tips and program information
local width = 100
local height = 50

-- Current generation field
local field = {}
-- Next generation field
local nfield = {}

-- UI Color codes
local black = 0x000000
local white = 0xFFFFFF

-- Field clearing/generation
local function clearField()
  -- Making the field array circular (code from https://stackoverflow.com/a/63169007/12696005)
  setmetatable(field, {
  __index = function(t,i)
    local index = i%width
    index = index == 0 and width or index
    return t[index] end
  })
  --
  for gx=1,width do
    field[gx] = {}
    nfield[gx] = {}
    -- Making the field array circular pt.2
    setmetatable(field[gx], {
    __index = function(t,i)
      local index = i%height-3
      index = index == 0 and height-3 or index
      return t[index] end
    })
    --
    for gy=1,height-3 do
      field[gx][gy] = 0
    end
  end
end

--Field redraw
local function drawField(data)
  for x=1, width do
    for y=1,height-3 do
      if data[x][y]==1 then
        -- Alive cell
        display.setBackgroundColor(white)
        display.setForegroundColor(black)
      else
        -- Dead cell
        display.setBackgroundColor(black)
        display.setForegroundColor(white)
      end
      -- Drawing the cell
      display.fillRectangle(x, y, 1, 1, " ")
    end
  end
end

--- Calculating next generation field
local function nextGen()
  -- Going through all the table
  for x=1,width do
    for y=1,height-3 do
      local livingCells = 0
      -- Calculation of living cells around x:y
      for i=x-1,x+1 do
        for j=y-1,y+1 do
          livingCells = livingCells + field[i][j]
        end
      end
      -- Substracting the x:y cell from the overall amount
      livingCells = livingCells - field[x][y]
      -- Cell spawns
      if field[x][y]==0 and livivngCells==3 then
        nfield[x][y] = 1
      -- Cell dies
      elseif field[x][y]==1 and (livingCells < 2 or livingCells > 3) then
        nfield[x][y] = 0
      -- Remains the same
      else
        nfield[x][y] = field[x][y]
      end
    end
  end
end

-- Game loop
clearField()
while true do
  local lastEvent = {events.listenFilter(filter)}
  -- Cell creation/deletion
  if lastEvent[1] == "mouseClicked" and lastEvent[5] == "lmb" then
    --State invertion and cell redrawing
    if field[lastEvent[3]][lastEvent[4]]==1 then
      field[lastEvent[3]][lastEvent[4]] = 0
      display.setBackgroundColor(black)
      display.setForegroundColor(white)
    else
      field[lastEvent[3]][lastEvent[4]] = 1
      display.setBackgroundColor(white)
      display.setForegroundColor(black)
    end
    display.fillRectangle(lastEvent[3], lastEvent[4], 1, 1, " ")
  elseif lastEvent[1] == "key_pressed" then
    -- Previous generation
    if lastEvent[4] == keyboard.lbracket then
      drawField(field)
    -- Next generation
    elseif lastEvent[4] == keyboard.rbracket then
      display.setBackgroundColor(blue)
      display.fillRectangle(1, height-2, width, 1, " ")
      nextGen()
      drawField(nfield)
      for i=1,width do
        for j=1,height-3 do
          field[i][j] = nfield[i][j]
        end
      end
    elseif lastEvent[4] == keyboard.backslash then
      -- more code --
    end
  end
end

Переменные display, keyboard и events являются библиотеками.


person Vlad Gorsky    schedule 31.07.2020    source источник
comment
У вас опечатка livivngCells   -  person Egor Skriptunoff    schedule 01.08.2020
comment
Ага, понятно. Оказывается, это была единственная проблема с кодом, спасибо   -  person Vlad Gorsky    schedule 01.08.2020


Ответы (1)


Оказывается, единственной проблемой была ошибка livingCells в строке if field[x][y]==0 and livivngCells==3 then.

person Vlad Gorsky    schedule 31.07.2020