Hi guys,
i'm doing a project for my thesis and i'm pretty new to LUA Scripting. My problem is the following: i am trying to track unit-to-unit combat statistics, and i want to obtain a nested table structured this way:
my unit type -> enemy unit type -> distance -> and then the distance table is something like { [100] = 2, [200] = 5, etc} , where indexes 100 200 are different ranges at which my unit has killed enemy unit, and values 2, 5 counts the number of kills have been made at that distance.
The result is intended to give me a statistic on how many times a certain unit type killed that other unit type at different distances, so it is like:
- unit1 x unit2 x 100m = 3
- unit1 x unit2 x 200m = 4
- unit1 x unit4 x 100m = 2
etc
My problem is i can't figure out how to structure this table:
- is there a way to make the "distance" table different for every "my unit x enemy unit" combination? or creating a table "distance" returns always the same table so every kill made at 100m writes on the same "distance" table indipendently of my and enemy unit type?
- the process should be as automatic as possible, meaning i don't want to declare previously all unit types and enemy types as table names or indexes (i can extract "unitDefID" and "attackerDefID" from a .UnitDestroyed call in, so i would like to being able to use that values for defining table values)
Thank you in advance! :)
Fil
Nesting tables in LUA
Moderator: Moderators
Re: Nesting tables in LUA
Code: Select all
table = {
childTable = {},
2ndChildTable = {
variableA = "waffles",
variableB = "doughnut",
}
},
Re: Nesting tables in LUA
Could do like this:my unit type -> enemy unit type -> distance -> and then the distance table is something like { [100] = 2, [200] = 5, etc} , where indexes 100 200 are different ranges at which my unit has killed enemy unit, and values 2, 5 counts the number of kills have been made at that distance.
Code: Select all
distanceHistogram[attackerID][victimID][distanceBin] = killCount
If you want to increase count of unittype "X" killed by unittype "Y" at distance "D" you would do:
Code: Select all
distanceHistogram[X][Y][D] = distanceHistogram[X][Y][D] +1
Code: Select all
distanceHistogram = {}
Code: Select all
distanceHistogram[X] = bla --this works, new entry is created and filled with value
distanceHistogram[X][Y] = bla --this does not work
distanceHistogram[X][Y][D] = bla --this works even less
So you can either:
1) At inintinitatlistion create those subtables fill all entries with zeros.
or
2) Create new entries as they become needed.
I think for this case (2) is better.
(There are ways to write that shorter&nice but then it explains less clear imo.)
Code: Select all
function addToHistogram (attackerID, victimID, distance)
--decide into which "bin" this distance goes (0,100,200,300,..)
Dbin = (math.floor(distance / 100))*100
--if there is no table for this attacker, then create one:
if not distanceHistogram[attackerID] then distanceHistogram[attackerID] = {} end
--if there is no table for this type of victim of type of attacker yet, then create one:
if not distanceHistogram[attackerID][victimID] then distanceHistogram[attackerID][victimID] = {} end
--if there is no table for the kill-distance for this type of victim of this type attacker yet, then starting counting at zero:
if not distanceHistogram[attackerID][victimID][Dbin] then distanceHistogram[attackerID][victimID][Dbin] = 0 end
--now we have an entry of the killcount at this distance, of this victim, by this attacker...
--...and can increase it by 1:
distanceHistogram[attackerID][victimID][Dbin] = distanceHistogram[attackerID][victimID][Dbin] +1
end
Code: Select all
function printHistogram ()
Spring.Echo ("----printHistogram---")
for attackerID,a in pairs (distanceHistogram) do
Spring.Echo ("attacker=",unitName(attackerID))
for victimID,v in pairs (distanceHistogram[attackerID]) do
Spring.Echo ("\tvictim="..unitName(victimID))
for dBin=0,maxD, binSize do
count = distanceHistogram[attackerID][victimID][dBin] or 0
if count > 0 then Spring.Echo ("\t\tdBin=",dBin, "count=",count) end
end
end
end
end
Code: Select all
function gadget:UnitDestroyed(unitID, unitDefID, unitTeam, attackerID, attackerDefID, attackerTeam) --add some checks if units are valid etc
distance = Spring.GetUnitSeparation (attackerID, unitID) or 0
addToHistogram (attackerDefID, unitDefID, distance)
end
example output:
Code: Select all
----printHistogram---
attacker=, Raven
victim=Light Laser Tower
dBin=, 800, count=, 2
victim=Peewee
dBin=, 1000, count=, 1
attacker=, Peewee
victim=Light Laser Tower
dBin=, 100, count=, 2
attacker=, Light Laser Tower
victim=Peewee
dBin=, 100, count=, 1
dBin=, 200, count=, 3
dBin=, 400, count=, 5
attacker=, Guardian
victim=Peewee
dBin=, 100, count=, 2
dBin=, 200, count=, 1
dBin=, 300, count=, 3
dBin=, 400, count=, 2
dBin=, 500, count=, 4
dBin=, 600, count=, 10
dBin=, 700, count=, 4
Re: Nesting tables in LUA
Not sure if I interpreted correctly;Fil wrote:... nested table structured this way:
my unit type -> enemy unit type -> distance -> and then the distance table is something like { [100] = 2, [200] = 5, etc} , where indexes 100 200 are different ranges at which my unit has killed enemy unit, and values 2, 5 counts the number of kills have been made at that distance.
The result is intended to give me a statistic on how many times a certain unit type killed that other unit type at different distances, so it is like:
- unit1 x unit2 x 100m = 3
- unit1 x unit2 x 200m = 4
- unit1 x unit4 x 100m = 2
etc
...
Code: Select all
statsTable = {friendlyDefID1 = {enemyDefID1 = {[100] = 2, [200] = 5, ...}, enemyDefID2 = {...}, ...}, friendlyDefID2 = {...}, ...}
Code: Select all
statsTable[friendlyUnitDefID][enemydefID][range]
edit: knorke got there first
Re: Nesting tables in LUA
Hi guys! thanks for everything, you've been so kind :)
I managed to create a
killsTable[unitDefID][attackerDefID]["distance"][distance]=kills
(- the string "distance" identifies the table section scoring kills by distance, since i'm planning to score them even by angle, etc.,
- the variable distance holds the different distance ranges like 100 200 etc)
My initial confusion was due to the fact of declaring previously the subtables (because i needed them to be created) and then nesting them, but was a plain wrong approach, having only 1 table is woooow far more easy. Btw i check for missing table sections everytime i'm scoring a new entry.
Thank you!
I managed to create a
killsTable[unitDefID][attackerDefID]["distance"][distance]=kills
(- the string "distance" identifies the table section scoring kills by distance, since i'm planning to score them even by angle, etc.,
- the variable distance holds the different distance ranges like 100 200 etc)
My initial confusion was due to the fact of declaring previously the subtables (because i needed them to be created) and then nesting them, but was a plain wrong approach, having only 1 table is woooow far more easy. Btw i check for missing table sections everytime i'm scoring a new entry.
Thank you!
- Silentwings
- Posts: 3720
- Joined: 25 Oct 2008, 00:23
Re: Nesting tables in LUA
Working with subtables does often produce easier to read code though, you just have to remember that in lua all tables are accessed by reference, regardless of whether its a table or a subtable.