Wondering if I could get some help with this:
function setupRound()
local gameModes = {'mode 1','mode 2','mode 3'} -- Game modes
local maps = {'map1','map2','map3'}
--local newMap = maps[math.random(1,#maps)]
local mapData = {maps[math.random(#maps)],gameModes[math.random(#gameModes)]}
local mapData = mapData
return mapData
end
a = setupRound()
print(a[1],a[2]) --Fix from Egor
What the problem is:
`
When trying to get the info from setupRound() I get table: 0x18b7b20
How I am trying to get mapData:
a = setupRound()
print(a)
Edit:
Output Issues
With the current script I will always the the following output: map3 mode 2.
What is the cause of this?
Efficiency; is this the best way to do it?
While this really isn't a question, I just wanted to know if this method that I am using is truly the most efficient way of doing this.
First of all
this line does nothing useful and can be removed (it does something, just not something you'd want)
local mapData = mapData
Output Issues
The problem is math.random. Write a script that's just print(math.random(1,100)) and run it 100 times. It will print the same number each time. This is because Lua, by default, does not set its random seed on startup. The easiest way is to call math.randomseed(os.time()) at the beginning of your program.
Efficiency; is this the best way to do it?
Depends. For what you seem to want, yes, it's definitely efficient enough. If anything, I'd change it to the following to avoid magic numbers which will make it harder to understand the code in the future.
--- etc.
local mapData = {
map = maps[math.random(#maps)],
mode = gameModes[math.random(#gameModes)]
}
-- etc.
print(a.map, a.mode)
And remember:
Premature optimization is the root of all evil.
— Donald Knuth
You did very good by creating a separate function for generating your modes and maps. This separates code and is modular and neat.
Now, you have your game modes in a table modes = {} (=which is basically a list of strings).
And you have your maps in another table maps = {}.
Each of the table items has a key, that, when omitted, becomes a number counted upwards. In your case, there are 3 items in modes and 3 items in maps, so keys would be 1, 2, 3. The key is used to grab a certain item in that table (=list). E.g. maps[2] would grab the second item in the maps table, whose value is map 2. Same applies to the modes table. Hence your output you asked about.
To get a random game mode, you just call math.random(#mode). math.random can accept up to two parameters. With these you define your range, to pick the random number from. You can also pass a single parameter, then Lua assumes to you want to start at 1. So math.random(3) becomes actually math.random(1, 3). #mode in this case stand for "count all game modes in that table and give me that count" which is 3.
To return your chosen map and game mode from that function we could use another table, just to hold both values. This time however the table would have different keys to access the values inside it; namely "map" and "mode".
Complete example would be:
local function setupRound()
local modes = {"mode 1", "mode 2", "mode 3"} -- different game modes
local maps = {"map 1", "map 2", "map 3"} -- different maps
return {map = maps[math.random(#maps)], mode = modes[math.random(#modes)]}
end
for i = 1, 10 do
local freshRound = setupRound()
print(freshRound.map, freshRound.mode)
end
Related
enter image description here
I just started working on lua scripting since a week. I have a lua file where in the logic needs to be written for a certain condition.
The condition when gets triggered
it does an iteration on one of the fields to change value from
(ABC123-XYZ) to this value
(ABC123#1-XYZ) and it keeps increasing whenever iterations happens (ABC123#2-XYZ)
I need to run a function that removes the # followed by number to change it back to (ABC123-XYZ). Looking for any advice!
Edit 1:
Below is the updated code that is written Thanks to #Piglet
I have another scenario if therr are two hashes in the variable.
local x = 'BUS144611111-PNB_00#80901#1555-122TRNHUBUS'
local b = x:gsub("#%d+","")
function remove_char(a) a=a:gsub("#%d+","")
return a;
end if string.match(x,"#")
then print('function')
print(remove_char(x));
else print(x);
end
Expected output should be
x = 'BUS144611111-PNB_00#80901-122TRNHUBUS' for the aforesaid variable
local a = "ABC123#1-XYZ"
local b = a:gsub("#%d+", "")
this will remove any # followed by or one more digits from your string.
I am pretty new to this, so I hope you can give me a hand.
I am programming lights, and what I like to do is take a variable from my lighting desk (a text string called "4 Mythos Stage") and split is into different variables.
to get the variables from the desk I use:
return function ()
local Layer1 = gma.user.getvar("Layer1") -- I placed "4 Mythos Stage" variable in Layer1
gma.feedback(Layer1) -- gives feedback 4 Mythos Stage
end
Now I would like to split the string into 3 new local variables named:
local number -- should produce 4
local fixturetype -- should produce Mythos
local location -- should produce Stage
i tried the following:
local number = string.match('Layer1', '%d+')
local fixturetype = string.match('Layer1', '%a+')
local location = string.match('Layer1', '%a+')
this didn't work, so can somebody please help me in the right direction. I would be really greatful.
with kind regards,
Martijn
You can assign all three variables at the same time, because Lua has multiple returns and multiple assignment. Put parentheses around each of your patterns in order to return them as captures, and combine them into a single pattern with spaces between them:
local number, fixturetype, location = string.match(Layer1, '(%d+) (%a+) (%a+)')
In case you will be using multiple spaces or tabs between the items, this pattern would be better:
local number, fixturetype, location = string.match(Layer1, '(%d+)[ \t]+(%a+)[ \t]+(%a+)')
The reason why your attempt didn't work is because string.match('Layer1', '%d+') is searching inside 'Layer1' (a string) instead of Layer1 (a variable).
But even if you corrected that, you would get 'Mythos' every time you called string.match(Layer1, '%a+') (where Layer1 == '4 Mythos Stage'). string.match always starts from the beginning of the string, unless you supply an index in the third parameter: string.match(Layer1, '%a+', 9) --> 'Stage'.
A robust solution for this task is to split the string into three "words", a word being a sequence of non-whitespace characters:
local number, fixturetype, location = string.match(Layer1, '(%S+)%s+(%S+)%s+(%S+)')
I'm currently writing an Addon for World of Warcraft, but I've run a bit of a basic lua problem. The gist of it is, I want to reduce the following elements inside this for loop into a single line.
Currently, I am using WoW's api command of "SetAlpha(0)" (which just hides the frame in game) on a list of frames that share the same name except for the number at the end. ActionButton1Name, ActionButton2Name, ActionButton3Name, etc.
I also have to do the same thing to four other lists, each also having 12 different versions of themselves MultiBarBottomRightButton1Name, MultiBarBottomRightButton2Name, etc.
Essentially, I'd like to take what I currently have:
for i=1, 12 do
["ActionButton"..i.."Name"]:SetAlpha(0)
["MultiBarBottomRightButton"..i.."Name"]:SetAlpha(0)
["MultiBarBottomLeftButton"..i.."Name"]:SetAlpha(0)
["MultiBarRightButton"..i.."Name"]:SetAlpha(0)
["MultiBarLeftButton"..i.."Name"]:SetAlpha(0)
end
SetAlpha is specific to World of Warcraft's API, so disregard that as needed.
And transform it into something where I have all the [ ] elements in their own table somewhere else, and then later use that index
local buttonNameIndex = function()
for i=1, 12 do
["ActionButton"..i.."Name"]
["MultiBarBottomRightButton"..i.."Name"]
["MultiBarBottomLeftButton"..i.."Name"]
["MultiBarRightButton"..i.."Name"]
["MultiBarLeftButton"..i.."Name"]
end
end
for i,v in ipairs(buttonNameIndex) do
v:SetAlpha(0) end
However, the above function didn't seem to work, in that the terminal was spitting out an error of having an unexpected symbol near the do of the 2nd line.
As to why I'd like to do this: I'll be doing a lot more with that list of frames later on, so it'd be nice to have them all combined into a single table.
If these are global variables, use expressions like this:
_G["ActionButton"..i.."Name"]:SetAlpha(0)
which access a global variable from a dynamically created name.
I want to intersect multiple sets (2 or more). The number of sets to be intersected are passed as ARGV from command line. As number of sets are being passed from command-line. So the number of arguments in redis.call() function are uncertain.
How can I do so using redis.call() function in Lua script.
However, I have written a script which has algo like:
Accepting the number of sets to be intersected in the KEYS[1].
Intersecting the first two sets by using setIntersected = redis.call(ARGV[1], ARGV[2]).
Running a loop and using setIntersected = redis.call("sinter", tostring(setIntersected), set[i])
Then finally I should get the intersected set.
The code for the above algorithm is :
local noOfArgs = KEYS[1] -- storing the number of arguments that will get passed from cli
--[[
run a loop noOfArgs time and initialize table elements, since we don't know the number of sets to be intersected so we will use Table (arrays)
--]]
local setsTable = {}
for i = 1, noOfArgs, 1 do
setsTable[i] = tostring(ARGV[i])
end
-- now find intersection
local intersectedVal = redis.call("sinter", setsTable[1], setsTable[2]) -- finding first intersection because atleast we will have two sets
local new_updated_set = ""
for i = 3, noOfArgs, 1 do
new_updated_set = tostring(intersectedVal)
intersectedVal = redis.call("sinter", new_updated_set, setsTable[i])
end
return intersectedVal
This script works fine when I pass two sets using command-line.
EG:
redic-cli --eval scriptfile.lua 2 , points:Above20 points:Above30
output:-
1) "playerid:1"
2) "playerid:2"
3) "playerid:7"
Where points:Above20 and points:Above30 are sets. This time it doesn't go through the for loop which starts from i = 3.
But when I pass 3 sets then I always get the output as:
(empty list or set)
So there is some problem with the loop I have written to find intersection of sets.
Where am I going wrong? Is there any optimized way using which I can find the intersection of multiple sets directly?
What you're probably looking for is the elusive unpack() Lua command, which is equivalent to what is known as the "Splat" operator in other languages.
In your code, use the following:
local intersectedVal = redis.call("sinter", unpack(setsTable))
That said, SINTER is variadic and can accept multiple keys as arguments. Unless your script does something in addition to just intesects, you'd be better use that instead.
I asked a question similar to this the other day, but another bug popped up "attempt to concatenate table and string"
local questions={
EN={
Q2={"Who is the lead developer of Transformice?","Tigrounette"},
Q4={"What is Eminem's most viewed song on youtube?","I love the way you lie"},
Q6={"What is the cubic root of 27?","3"},
Q8={"What are the first 3 digits of Pi","3.141"},
Q10={"What is the most populated country?","China"},
Q12={"What is the plural of the word 'Person'?","People"},
Q14={"Entomology is the science that studies ...?","Insects"},
Q16={"Who was the creator of the (bot ran) minigame fight?","Cptp"},
Q18={"The ozone layer restricts ... radiation","Ultraviolet"},
Q20={"Filaria is caused by ...","Mosquitos"}
}
local main = questions.EN["Q"..math.random(1,20)].."%s" -- bug here
local current_answer_en = string.gsub(current_question_en,1,2)
What type of object is questions.EN["Q"..math.random(1,20)]? Say random is 15, what type of object is questions.EN["Q6"]? It is a {"What is the cubic root of 27?","3"}, which is a table, which Lua doesn't know how to concatenate with a string ("%s" in your case). If you want to concatenate with the first item of this table, then
local main = questions.EN["Q"..math.random(1,20)][1] .. "%s"
Note however that you will need the "random with step" function that I posted in math.random function with step option?, otherwise you could get that the table EN["Q"..something] is nil (if the random number is an odd number, in the code you posted).
Note sure what you are trying to do with current_question_en but if you are trying to extract the question and answer you could do something like this:
local QA = questions.EN["Q"..math.random(1,20)] -- this is a table
local question, answer = QA[1], QA[2]
The other option is that you build your table like this:
local questions={
EN={
Q2={q="Who is ..?", a="Tigrounette"},
Q4={q="What is ...?", a="I love the way you lie"},
...
}
}
Then you could use
local QA = questions.EN["Q"..math.random(1,20)] -- this is a table
print("The question:", QA.q)
print("The answer:", QA.a)
Not sure what you're trying to do with string.gsub but it does not take integers as 2nd and 3rd args.