Seems like I can’t modify a table in certain cases

Hello all,
I’ve been working on a small project recently, which I hope to eventually turn into a cellular automata simulation. Right now it’s just a grid of squares that you can turn on or off by touching and I’d like to be able to change their values in the code too, but I can’t. Only the touched function seems to have this permission.

I tried changing it directly in the console, and then i tried making a function to do it, which works fine when called by touched, but nothing’s working and it’s really frustrating.

My code is below:

-- cells

local gridWidth = 10
local gridHeight = 10
local cellSize = 50/1080
local margin = 10
local startX = (WIDTH - (gridWidth * (cellSize + margin) - margin)) / 2
local startY = (HEIGHT - (gridHeight * (cellSize + margin) - margin)) / 2
local onColour = color(0, 255, 0)
local offColour = color(255)
local bgColour = color(40, 40, 50)

grid = {}
for i = 1, gridWidth do
    grid[i] = {}
    for j = 1, gridHeight do
        grid[i][j] = false
    end
end

-- Use this function to perform your initial setup
function setup()
    print("Hello Automata!")
    viewer.mode = OVERLAY
    noSmooth()
end

function touched(touch)
    if touch.state == BEGAN then
        local i = math.floor((touch.x - startX) / (cellSize + margin)) + 1
        local j = math.floor((touch.y - startY) / (cellSize + margin)) + 1
        
        if i >= 1 and i <= gridWidth and j >= 1 and j <= gridHeight then
            cell(i,j)
        end
    end
end

-- This function gets called once every frame
function draw()
    background(bgColour)
    
    for i = 1, gridWidth do
        for j = 1, gridHeight do
            if grid[i][j] then
                fill(onColour)
            else
                fill(offColour)
            end
            rect(startX + (i - 1) * (cellSize + margin), startY + (j - 1) * (cellSize + margin), cellSize, cellSize)
        end
    end
end

function cell(xIndex,yIndex)
    grid[xIndex][yIndex] = not grid[xIndex][yIndex]
    print(xIndex,yIndex)
end 

Any help at all would be much appreciated.

@DJMoffinz @sim - modified your code to define variables from within setup() and a number of errors fired up. Added some definitions to the draw() function, but still errors.

Looks like all definitions outside the draw() function are ignored.

What version of Codea are you running in?


-- Template2

-- Use this function to perform your initial setup
function setup()
    print("Hello Automata!")
    viewer.mode = OVERLAY
    noSmooth()
    init()
end

function touched(touch)
    if touch.state == BEGAN then
        local i = math.floor((touch.x - startX) / (cellSize + margin)) + 1
        local j = math.floor((touch.y - startY) / (cellSize + margin)) + 1
        
        if i >= 1 and i <= gridWidth and j >= 1 and j <= gridHeight then
            cell(i,j)
        end
    end
end

-- This function gets called once every frame
function draw()
    background(0)
    gridWidth, gridHeight = 10, 10
    for i = 1, gridWidth do
        for j = 1, gridHeight do
            if grid[i][j] then
                fill(onColour)
            else
                fill(offColour)
            end
            rect(startX + (i - 1) * (cellSize + margin), startY + (j - 1) * (cellSize + margin), cellSize, cellSize)
        end
    end
end

function cell(xIndex,yIndex)
    grid[xIndex][yIndex] = not grid[xIndex][yIndex]
    print(xIndex,yIndex)
end 

function init()
    --
    gridWidth = 10
    gridHeight = 10
    cellSize = 50/1080
    margin = 10
    startX = (WIDTH - (gridWidth * (cellSize + margin) - margin)) / 2
    local startY = (HEIGHT - (gridHeight * (cellSize + margin) - margin)) / 2
    onColour = color(0, 255, 0)
    offColour = color(255)
    bgColour = color(40, 40, 50)
    
    grid = {}
    for i = 1, gridWidth do
        grid[i] = {}
        for j = 1, gridHeight do
            grid[i][j] = false
        end
    end
end

Edit: oops not had my brain switched on today. Removed local refs from init() and ran as per your initial project but no display. Also, can you have Local defs in global space?

1 Like

Thanks for the reply Bri_G, that is strange indeed. My Codea version is 3.7.1.

@DJMoffinz Heres something I threw together that might show what you’re trying to do. It was easier to start from scratch then try to get yours to work. Tap a white cell to show a red dot there. If you tap the green cell, it will show a red dot above, below, right, left of it to show that you can update any cell you want besides the one you touch. When you update cells, they should be done either in draw() or a function called from draw().

viewer.mode=FULLSCREEN

function setup()
    gridSize=20
    cellSize=30
    startX=100
    startY=100
    xx,yy=0,0
    center=gridSize//2
end

function draw()
    background(0)
    -- draw grid
    for x=1,gridSize do
        for y=1,gridSize do
            fill(255)
            -- draw green grid at center
            if x==center and y==center then
                fill(0,255,0)
            end
            rect(x*cellSize+startX,y*cellSize+startY,cellSize)
        end
    end

    -- draw ellipse up / down / sideways from center if selected
    fill(255,0,0)
    if xx+yy>0 then
        ellipse(xx*cellSize+startX+cellSize/2,yy*cellSize+startY+cellSize/2,10)
        if xx==center and yy==center then
            drawExtra()
        end
    end
end

function touched(t)
    if t.state==BEGAN then
        for x=1,gridSize do
            for y=1,gridSize do
                x1=x*cellSize+startX
                y1=y*cellSize+startY
                if t.x>x1 and t.x<x1+cellSize and t.y>y1 and t.y<y1+cellSize then
                    xx,yy=x,y   -- cell touched
                end
            end
        end
    end
end

function drawExtra()
    for x=1,gridSize do
        ellipse(x*cellSize+startX+cellSize/2,center*cellSize+startY+cellSize/2,10)
    end   
    for y=1,gridSize do
        ellipse(center*cellSize+startX+cellSize/2,y*cellSize+startY+cellSize/2,10)
    end   
end

@dave1707 - do you know what was wrong with the original code. I think it could be in the colour defs

@Bri_G Just looked at it again and the problem is the local cellSize = 50/1080. 50/1080 is .0463 which is really, really small. Change the cellSize to 40 or so and the cells show.

@DJMoffinz Here’s an example for saving info in a table for each cell when touched and it wasn’t already touched.

viewer.mode=FULLSCREEN

function setup()
    gridSize=20
    cellSize=30
    startX=100
    startY=100
    count=0
    tab={}  -- table to save each cell info
    for x=1,gridSize do
        tab[x]={}
        for y=1,gridSize do
            tab[x][y]=0 -- init to 0, no info
        end
    end

end

function draw()
    background(0)
    for x=1,gridSize do
        for y=1,gridSize do
            fill(255)
            rect(x*cellSize+startX,y*cellSize+startY,cellSize)
            if tab[x][y]>0 then
                fill(255,0,0)
                x1=x*cellSize+startX+cellSize/2 -- center x of cell 
                y1=y*cellSize+startY+cellSize/2 -- center y of cell
                text(tab[x][y],x1,y1)
            end
        end
    end
end

function touched(t)
    if t.state==BEGAN then
        for x=1,gridSize do
            for y=1,gridSize do
                x1=x*cellSize+startX
                y1=y*cellSize+startY
                if t.x>x1 and t.x<x1+cellSize and t.y>y1 and t.y<y1+cellSize then
                    if tab[x][y]==0 then    -- update only if cell is blank
                        count=count+1
                        tab[x][y]=count -- set cell to count
                    end
                end
            end
        end
    end
end

@dave1707 oh crap! i was gonna implement something where it resized the grid based on the screen width and i forgot about it :sweat_smile:

@Bri_G @dave1707 thanks for your help both of you! I’ve now diagnosed the problem, and it is simply that I was defining all my variables as local. Force of habit ig.