Is there an easier way than an "elseif marathon"? - lua

How do I optimize this code?
variable = 1
moveLine = function ()
if variable == 1 then
first = color_1.color
second = color_2.color
elseif variable == 2 then
first = color_2.color
second = color_3.color
end
variable = variable + 1
end
The function is alot longer and that is why I could use an easier way :)

You should be storing your colors in an array:
colors = { all your colors }
moveLine = function()
first = colors[variable]
second = colors[variable + 1]
variable = variable + 1
end

Related

How can I shift all of the tables down after removing a table?

In this code:
t = {
num = '',
}
t[0].num = '0'
t[1].num = '1'
t[2].num = '2'
Is there a way for me to delete t[0], then shift all of the table's values down, so that afterword it looks like this:
t[0].num = '1'
t[1].num = '2'
Example with imaginary functions:
t = {
num = '',
}
t[0].num = '0'
t[1].num = '1'
t[2].num = '2'
for i=0,tableLength(t) do
print(t[i])
end
--Output: 012
remove(t[0])
for i=0,tableLength(t) do
print(t[i])
end
--Output: 12
t = {
num = '',
}
t[0].num = '0'
t[1].num = '1'
t[2].num = '2'
This code will cause errors for indexing t[0], a nil value.
t only has one field and that is t.num
You need to do something like this:
t = {}
for i = 0, 2 do
t[i] = {num = tostring(i)}
end
if you want to create the desired demo table.
As there are many useful functions in Lua that assume 1-based indexing you I'd recommend starting at index 1.
local t = {1,2,3,4,5}
Option 1:
table.remove(t, 1)
Option 2:
t = {table.unpack(t, 2, #t)}
Option 3:
t = table.move(t, 2, #t, 1, t)
t[#t] = nil
Option 4:
for i = 1, #t-1 do
t[i] = t[i+1]
end
t[#t] = nil
There are more options. I won't list them all. Some do it in place, some result in new table objects.
As stated in this answer, by creating a new table using the result of table.unpack:
t = {table.unpack(t, 1, #t)}

What are _UPVALUE0_ keywords in decompiled Lua?

I have decompiled a few lua codes, was able to understand most of them.
But there are these UPVALUE0, UPVALUE1, etc... keywords I see in the code that are not defined anywhere as far as I've looked.
Here's an example:
local L0_0
L0_0 = module
L0_0((...), package.seeall)
function L0_0(A0_1)
if A0_1 - math.floor(A0_1) > 0 then
error("trying to use bitwise operation on non-integer!")
end
end
bit = {
bxor = function(A0_17, A1_18)
local L2_19, L3_20, L4_21, L5_22
L2_19 = _UPVALUE0_
L3_20 = A0_17
L2_19 = L2_19(L3_20)
L3_20 = _UPVALUE0_
L4_21 = A1_18
L3_20 = L3_20(L4_21)
L4_21 = _UPVALUE1_
L5_22 = L2_19
L4_21(L5_22, L3_20)
L4_21 = {}
L5_22 = math
L5_22 = L5_22.max
L5_22 = L5_22(table.getn(L2_19), table.getn(L3_20))
for _FORV_9_ = 1, L5_22 do
if L2_19[_FORV_9_] ~= L3_20[_FORV_9_] then
L4_21[_FORV_9_] = 1
else
L4_21[_FORV_9_] = 0
end
end
return _UPVALUE2_(L4_21)
end
}
What do they mean?
From https://www.lua.org/pil/6.1.html:
.. is neither a global variable nor a local variable. We call it an
external local variable, or an upvalue. (The term "upvalue" is a
little misleading, because it is a variable, not a value. However,
this term has historical roots in Lua and it is shorter than "external
local variable".)
local i = 0
function inc()
i = i + 1
return i
end
Variable i in function inc is upvalue, as it is not local variable in this function and not global variable.

Lua, is this possible?

I am working on a game using love2d and i haven't quite programmed in lua. Not sure on technical wording so i'll post my code and explain what i'm trying to do:
item = {}
item.stat = {}
player.x = 100
player.y = 100
--
item[0].stat.damage = 10
What i'm trying to do is make an inventory system and an item database. I want to be able to make the item database with the code above so i could add an item like so:
item[1].stat.damage = 10
item[1].stat.speed = 10
item[2].stat.damage = 20
item[2].stat.speed = 5
--
player.inventory[0] = item[1]
player.inventory[1] = item[2]
can someone tell me what coding principle this may so i can research it? I basically want to make a matrix that i can access like above while having the convenience of named arrays instead of saying item[1,"damage"] = 10
Edit:
I realise now i can do item.stat.damage[1] = 10 but i have to setup an array for each one, is there an easier way?
Simply use tables:
player = {}
player.x = 100
print(player.x) -- prints 100
Note that player.x is simply syntactic sugar for player["x"], so the following lines are equivalent:
print(player.x) -- prints 100
print(player["x"]) -- also prints 100
With that in mind, you could construct your game data like this for example:
item = {}
item[1] = {}
item[1].stat = {}
item[1].stat.damage = 10
item[1].stat.speed = 10
item[2] = {}
item[2].stat = {}
item[2].stat.damage = 20
item[2].stat.speed = 5
player = {}
player.x = 100
player.y = 100
player.inventory = {}
player.inventory[1] = item[1]
player.inventory[2] = item[2]
print(player.inventory[2].stat.damage) -- prints 20
print(player["inventory"][2]["stat"]["damage"]) -- equivalent, also prints 20
It is probably a good idea to define functions that create items or players and automatically set all the required fields.
Eventually, you may want to use actual classes and objects (for example, if you want to define methods on your objects).
EDIT:
Here is the example from above with functions create_item, create_player to create items or players. I've used named parameters for these functions so one doesn't have to remember the order of the function parameters (note the curly braces when calling the functions).
function create_item(arg)
local item = {}
item.stat = {}
item.stat.damage = arg.damage
item.stat.speed = arg.speed
return item
end
function create_player(arg)
local player = {}
player.x = arg.x
player.y = arg.y
player.inventory = {}
return player
end
item = {}
item[1] = create_item{damage=10, speed=10}
item[2] = create_item{damage=20, speed=5}
player = create_player{x=100, y=100}
player.inventory[1] = item[1]
player.inventory[2] = item[2]
print(player.inventory[2].stat.damage) -- prints 20
print(player["inventory"][2]["stat"]["damage"]) -- equivalent, also prints 20
You can always shorten your code:
item = {
stat = {},
[0] = { stat = { damage = 10 } },
[1] = { stat = { damage = 10, speed = 10 } },
[2] = { stat = { damage = 20, speed = 5 } },
}
player = { x = 100, y = 100, inventory = { [0] = item[1], [1] = item[2] } }
You can access that code in matrix way like
function item:getstat(index, param)
return self[index] and self[index].stat and self[index].stat[param];
end
function item:setstat(index, param, value)
local t1 = self[index]
if (t1 == nil) then
t1 = {}
self[index] = t1
end
local t2 = t1.stat
if (t2 == nil) then
t2 = {}
t1.stat = t2
end
t2[param] = value
end
print(item:getstat(0, "damage"))
item:setstat(1, "speed", 20)

Lua error making 16x16 grid

The following code gives me the following error:
attempt to index a nil value
-- Making grid
grid = {}
local i = 1
local ii = 1
mainx, mainy = love.graphics.getDimensions()
while(i<=mainx) do
if(i%16==0) then
while(ii<=mainy) do
if(ii%16==0) then
grid[i][ii] = nil
end
ii = ii + 1
end
end
i = i+1
end
I know lua is 1-based, but i dont really know what goes wrong here.
A fix will be gladly appericated :)
NOTE: mainx, mainy should be 800 and 600.
You forgot to assign grid[i] to {} before doing grid[i][ii] = nil. Second dereferencing [ii] fails because grid[i] == nil
I refactored your code below a little.
-- Making grid
local grid = {}
local mainx, mainy = love.graphics.getDimensions()
for i = 16,mainx,16 do -- syntax: for i = <start_value>, <max value (included)> [, <step>]
grid[i] = {};
for ii = 16,mainy,16 do
grid[i][ii] = i*ii -- some value
end
end

corona multi dimensional tables

I am trying to create a multi dimensional table like so
answers = {}
for i = 1, #answers do
answers[i] = { wrong = t[i], wrong2 = t2[i], right = t3[i]}
end
print(answers[1].wrong)
But when I try to access answers[1].wrong, I get error: attempt to index field '?' (nil value)
But when I do it this way it prints it for me
answers = {
{wrong = t[1], wrong2 = t2[1],right = t3[1]},
{wrong = t[2], wrong2 = t2[2],right = t3[2]}
}
print("----------")
print(answers[1].wrong)
print(answers[1].wrong2)
Why is the first method not working?
answers = {}
for i = 1, #answers do
#answers is 0. So the loop won't execute. You probably meant #t or something.

Resources