Using "for" to generate large table.

Posted by Chyort on Wed 16 Jan 2013 12:46 PM — 4 posts, 19,105 views.

USA #0
I am trying to use for loops, to generate a large(ish) table with 65 odd values.


<aliases>
  <alias
   match="Generate_Table"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>for i=9,18 do
  ("stat.str_" .. i)=0
end</send>
  </alias>
</aliases>


I will also need to make stat.dex, stat.con, and so on, but that should be easy enough if i can get this to work at all.

Plan B is to just brute force the list manually.
ie
stat.str_1 = 0
stat.str_2 = 0
and so on for all 65 odd variables.

Why i am doing this is simple, i would like to make some statistics related to how often stats reroll.
(The reroller script i have works quite well so no, I'm not asking for a reroller :P just trying to learn lua and make a interesting feature in the process)


reroll output

Your character's base stats have been rerolled...
                     New             Previous
Strength              15                   14
Dexterity             14                   15
Intelligence          18                   13
Wisdom                11                   12
Charisma              11                    9
Constitution          13                   16
Luck                  13                   16

<triggers>
  <trigger
   keep_evaluating="y"
   match="^(Strength|Dexterity|Intelligence|Wisdom|Charisma|Constitution|Luck)[ ]+([\d]+)[ ]+([\d]+)"
   name="Stats"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>stat = (stat or {})

if "%1" == "Strength" then
  stat.str_%2 = (stat.str_%2 or 0) + 1
elseif "%1" == "Dexterity" then
  stat.dex_%2 = (stat.dex_%2 or 0) + 1
elseif "%1" == "Intelligence" then
  stat.int_%2 = (stat.int_%2 or 0) + 1
elseif "%1" == "Wisdom" then
  stat.wis_%2 = (stat.wis_%2 or 0) + 1
elseif "%1" == "Charisma" then
  stat.cha_%2 = (stat.cha_%2 or 0) + 1
elseif "%1" == "Constitution" then
  stat.con_%2 = (stat.con_%2 or 0) + 1
elseif "%1" == "Luck" then
  stat.lck_%2 = (stat.lck_%2 or 0) + 1
  EnableTrigger("Stats", false)
end</send>
  </trigger>
  <trigger
   enabled="y"
   expand_variables="y"
   keep_evaluating="y"
   match="Your character\'s base stats have been rerolled\.\.\.$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>rolls = (rolls or 0) + 1
Note ("I have rerolled ", rolls, " times.")
EnableTrigger("Stats", true)</send>
  </trigger>
</triggers>


These are the 2 triggers i have to count how often stats appear, as well as how many rerolls there have been total.

Using "tprint (stat)" it appears to be working.
But eventually i will need to put it into a chart format, and crunch the numbers a bit, and nil values could be problematic. I would prefer to start everything out at 0 instead of doing (stat or 0) everywhere in my triggers.

Amended on Wed 16 Jan 2013 12:47 PM by Chyort
USA #1
I'm not 100% sure what your question is.

If I understand you right, what you're looking for is something like this:


stat = {}
for _, v in pairs({'str', 'dex', 'int', 'wis', 'cha', 'con', 'lck'}) do
  stat[v] = {}
  for n=9,18 do
    stat[v][n] = 0
  end
end


That will create a nested table for the stat name and value.

You can also make a table to reference for the stats, as such


statname = {
  Strength = "str",
  Dexterity = "dex",
  }


And so on, then just reference that table to convert the stat name to a stat, as such:


stat[statname["%1"]][%2] = stat[statname["%1"]][%2] + 1


To increment the necessary stat.


edit: Looking over your post, if you were asking why your script generates an error, you need to change
("stat.str_" .. i)=0

to
stat["str_"..i]=0

The top part is a much more efficient way to handle that data, though!
Amended on Fri 18 Jan 2013 11:58 PM by Fadedparadox
USA #2
Hmmm, interesting...

Thanks for the tips. I already got it working using my brute force approach, but i will have to upgrade it now and figure out how/why it works :P

Thanks for the help upgrading my project :)
USA #3
Not a problem! As to how/why it works...

When using a.b=x form for a table, it works for simpler variables, but the key name 'b' can't have say, spaces, and can't be manipulated. I just used the longer form, a["b"]=x. Since in this form, 'b' is text, you can manipulate (in this case, concat with ..) or even use another variable name such as:

b="test"
a[b]=x

would translate to:

a["test"]=x

which is the same as:

a.test=x

As to nested tables, it's relatively simple. In a.b=x, a is the variable, which is a table. That's what a={} does. Then you make a new variable, the name of which (b) is called the 'key', and set the value. A nested table is setting the value to a table, like... a.b={}.

The longer for statement...
for _, v in pairs({'str', 'dex', 'int', 'wis', 'cha', 'con', 'lck'}) do

Several things happening here. A generic for statement is used like...


for k, v in pairs (t) do
-- do stuff
end

What it does is iterate over the key/values of the table t, with one iteration for each key. the {'str'...} in pairs() was just me putting a table directly into pairs, instead of a variable. You could also have done...

t={'str', 'dex', 'int', 'wis', 'cha', 'con', 'lck'}
for _, v in pairs(t) do

And have the same result!

Also, the form:

t={'str', 'dex', 'int', 'wis', 'cha', 'con', 'lck'}

is just a way to set the key/values when you make the table. It's the same as...

t={[1]='str', [2]='dex', [3]='int', [4]='wis', [5]='cha', [6]='con', [7]='lck'}

Which is the same as

t={}
t[1]='str'
t[2]='dex'
t[3]='int'

etc etc.

If you have any questions, feel free to ask.