Need help with Tables!!!

I have an undo button in my program, that, when touched, undoes the scoring for the last score. Every button in my program adds a score of some kind, but they all get saved different places, and it becomes very hectic. My best thought yet was to put all the score updates from pressing buttons into a table, storing what variable needs to be changed, and by what increment, and then the undo button would simply change that value. Each ‘score’ consists of a table consisting of two mini tables, each consisting of a variable to change and by what value. This has to be set up this way because when I add a score, it changes two different variables, but different scoring buttons have different variables to change.

–Here’s what I have so far:

–This is the undo function that I’m trying to get to change the value of each variable by the given increment. (The name of the table is game.undoList):

function Undo:touched(touch)

 length = table.maxn(game.undoList)

 if length > 0 then

      game.undoList[length][1][1] = game.undoList[length][1][1] + game.undoList[length][1][2]

      game.undoList[length][2][1] = game.undoList[length][2][1] + game.undoList[length][2][2]

      table.remove(game.undoList, length)

 end

end

–Here is an example of what I am adding to game.undoList:

table.insert(game.undoList, {{variable1, value1}, {variable2, value2}})

–Any suggestions? Or do I need to explain what I need a little better?

What about this idea that uses closures, it’s quite universal:


undolist = {}
score0 = 0
score1 = 0

function addscore(value)
    -- remember old values
    local oldscore0 = score0
    local oldscore1 = score1
    -- this will restore the old values when called
    local f = function()
        score0 = oldscore0
        score1 = oldscore1
    end
    table.insert(undolist, f)
    -- modify
    score0 = score0 + value
    score1 = score1 + value
end

function undo()
    undofunc = table.remove(undolist)
    if undofunc then undofunc() end
end

Anyway, if you want to use the variable idea (or the concept of closures is a bit too much for you right now) you will have to store variable names and use the special table _G. Example without tables, just for the concept:


score = 10

name_of_var = "score"
value_of_var = 0
_G[name_of_var] = value_of_var

More elaborate usage with tables and variable names, just in case your question really focuses on tables and not about undoing in general:


undolist = {}
score1 = 0
score2 = 0

function addscore(value1, value2)
    local undocontext = {}
    undocontext["name1"] = "score1"
    undocontext["value1"] = score1
    undocontext["name2"] = "score2"
    undocontext["value2"] = score2
    table.insert(undolist, undocontext)
    score1 = value1
    score2 = value2
end

function undo()
    local undocontext = table.remove(undolist)
    if undocontext ~= nil then
        _G[undocontext["name1"]] = undocontext["value1"]
        _G[undocontext["name2"]] = undocontext["value2"]
    end
end

Some hints if you are not proficient with tables:

table.insert(t, item) inserts an item at the end of the table.

item = table.remove(t) removes the last item from the table and returns it (nil in case the table is empty).

Important advice (and maybe homework for you):

undolist will fill up with every addscore action. Before adding an entry, make sure to keep the size of the table down to a reasonable value.

NeverMind! I found a much simpler solution. I just put one item into the game.undoList each time I added a score. I just put ‘self,’ and then just called that object: undo function when I press the undo button. It works perfectly.