Logitech G105 keyboard start script - logitech

How can I start the script with a normal key, not a G-key?
Like SHIFT+K or just K.
local function interruptable_sleep(delay)
local tm = GetRunningTime() + delay
repeat
if IsKeyLockOn("scrolllock") then return true end
local t = tm - GetRunningTime()
if t > 0 then Sleep(math.min(t, 100)) end
until t <= 0
end
function OnEvent(event, arg)
if event=="G_PRESSED" and arg==3 then --This change for "K" or something not a G-Key

Related

Why Does A For Loop Return "attempt to get length of a Vector3 value"

I have no clue what is wrong with this code, it is literally saying that a for loop that is perfectly fine, is attempting to get a vector3 value.
local locations = {}
local Players = game:GetService("Players")
local function SplitString(String)
local CurrentString = ""
local x = 1
for i = 1, #String do
local FullString = string.sub(String,1,i)
local Character = string.sub(String,i,i)
local CurrentString = string.sub(String, x, i)
print(locations[1])
if Character == "," then
CurrentString = string.sub(String,x,i-1)
table.insert(locations,CurrentString)
x = i + 1
CurrentString = string.sub(String, x , i)
print(locations)
end
--Add the character to the string.
if Character == " " then
x = i + 1
CurrentString = string.sub(String, x, i + 1)
end
if #FullString + 1 == #String then
table.insert(locations, CurrentString)
end
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
local humanoidrootpart = char:WaitForChild("HumanoidRootPart")
wait(5)
while humanoidrootpart do
local location = humanoidrootpart.position
print(location)
SplitString(location)
print(locations[1])
local RoundLocatX = math.floor(locations[1]*50)/50
local RoundLocatZ = math.floor(locations[3]*50)/50
local RoundLocatXLength = RoundLocatX.length
local RoundLocatZLength = RoundLocatZ.length
if RoundLocatX > 50 then
print('hi')
end
wait(1)
end
end)
end)
This is the error:
ServerScriptService.Terrain Generation:9: attempt to get length of a Vector3 value
I would post this on the roblox forum but they are stupid and require some dumb amount of reading time to be able to post on it.
Your error is pointing at this line :
for i = 1, #String do
and saying that you are trying to get the length of a Vector3 object. That means that #String is not working as expected. So looking at the object you passed into the SplitString function...
local location = humanoidrootpart.position
print(location)
SplitString(location)
Your location variable is a Vector3, not a string, and it doesn't support the length operator, #.
But you don't have to parse it as a string to get the values out of it. Since it is a Vector3, you can simply index the different values in it.
local location = humanoidrootpart.Position
local RoundLocatX = math.floor(location.X * 50) / 50
local RoundLocatZ = math.floor(location.Z * 50) / 50

Stopwatch in Roblox Lua using a while loop

I am making a Roblox game and I want it to have a stopwatch. The stopwatch works, but it counts very slowly for some reason.
Here's my ScreenGui in StarterGui:
Here's the code inside the LocalScript:
local timer = script.Parent.Timer
local tms = 00
local ts = 00
local tm = 00
local tt
local tts
local y = 0
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
while true do
wait(0.01)
if whichtower.Value == "" then
tms = 00
ts = 00
tm = 00
tts = 0
else
tms = tms + 1
if tms == 100 then
ts = ts + 1
tms = 0
tts = tts + 1
if ts == 60 then
tm = tm + 1
ts = 0
end
end
tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
timer.Text = tt
game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
end
end
The arbitrary wait() and loop is a possible cause of timing issues, although I can't see anything specific that might be slowing it down. Are you sure that :FindFirstChild on WHichTower is always returning results? Add a print statement there, so your debug window has a constant stream of values, and you can confirm if it's finding a suitable tower.
Also, you are only updating the text if there's a Tower; for the code where you set the values to 0, there's no timer.Text update.
But if you don't think that's the issue:
I'd try put your code in a Heartbeat function, called regularly and tied to the refresh rate (I think). Then you don't need the while loop, nor the wait() commands. The Heartbeat only runs as fast as the refresh rate, therefore, there's no point trying to running anything quicker than that because the screen won't update.
local lPlayers = game:GetService("Players")
local lRunSvc = game:GetService("RunService")
local function onPlayerAdded(pPlayer) -- pPlayer (variable name is up to you) is the ref to the joined player.
print(pPlayer.Name .. " joined the game.")
lRunSvc.Heartbeat:Connect(function()
print("whichtower.value is:" .. whichtower.Value) -- View prints in the Output console
if whichtower.Value == "" then
tms = 00
ts = 00
tm = 00
tts = 0
else
tms = tms + 1
if tms == 100 then
ts = ts + 1
tms = 0
tts = tts + 1
if ts == 60 then
tm = tm + 1
ts = 0
end
end
tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
timer.Text = tt
game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
end
end)
end
lPlayers.PlayerAdded:Connect(onPlayerAdded) -- This is called when a player joins
Just as Vexen Crabtree has pointed out, the time that wait() will actually pause a script is based on a system clock's best guess of how much time has passed. Rather than counting up the milliseconds, a more reliable method for calculating passed time is to use the tick() function.
tick() will give you the current epoch time, which is the number of milliseconds that have passed since January 1st, 1970.
So, if you know a starting time, you can subtract it from the current time and get the number of milliseconds that have passed. This method doesn't rely on loop timings and will give a more accurate measure of the actual time that has passed. The amount of time that you chose with wait() will only reflect the speed at which the value will be updated.
local timer = script.Parent.Timer
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
local playerTime = game.Players.LocalPlayer:FindFirstChild("Time")
local startingTime = 0
local isTiming = false
-- attach a listener to know when to start the clock
whichTower.Changed:Connect(function(newValue)
-- reset the clock to zero when the value is empty
isTiming = newValue ~= ""
if not isTiming then
startingTime = 0
else
-- start the clock!
startingTime = tick()
end
end)
local refreshTime = 0.01
while true do
wait(refreshTime)
if isTiming then
-- calculate the time that has passed
local ms = tick() - startingTime
-- calculate how many minutes have passed
local tm = ms - (ms % (60 * 1000))
ms = ms - tm
tm = tm / 1000
-- calculate how many seconds have passed
local ts = ms - (ms % 1000)
ms = ms - ts
ts = ts / 1000
-- format the remainder
local tms = ms / 1000
if #tostring(tms) > 2 then
tms = string.sub(tostring(tms), 3)
else
tms = "0"
end
-- format the time into mm:ss.ss ex) 123:01.123
local tt = string.format("%.2d:%.2d.%s", tm, ts, tms)
timer.Text = tt
playerTime.Value = tt
end
end
I have figured it out using a different set of code. Roblox limits the wait parameters to a minimum of 0.03 seconds, so that is why my previous code was not working.

Redis interval query

I have data in the form of a tuple (S, T), where S is string and T is integer. Neither S nor T is unique, while their combination is unique. I need to get all tuples where S1 == S2 and |T1 - T2| <= C. Is is possible to do efficiently with Redis?
One way would be to store the data in a list and do the retrieval with a Lua script. First, for tuples of the form (Sn,Tn), insert it like this:
LPUSH myKey S1:T1
LPUSH myKey S2:T2
... and so on
Then, use the Lua script below:
local function split(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1))
pos = sp + 1
end
table.insert(arr,string.sub(str,pos))
return arr
end
local key = KEYS[1]
local sVal = ARGV[1]
local tVal = tonumber(ARGV[2])
local cVal = tonumber(ARGV[3])
local length = redis.call("LLEN", key)
if (tonumber(length) == 0) then
return nil
end
local data = redis.call("LRANGE", key, 0, tonumber(length))
local retval = {}
for index,val in pairs(data) do
local parts = split(":", val)
if (parts[1] == sVal and math.abs(tonumber(parts[2]) - tVal) <= cVal) then
table.insert(retval, val)
end
end
return retval
Save it as script.lua and execute it with:
$ redis-cli "$(cat script.lua)" 1 myKey sValue tValue cValue
This will return all tuples (in Sn:Tn form) that matches S1 == S2 and |T1 - T2| <= C.

generating TTT game tree in lua

I am attempting to write a tic-tac-toe game in lua, and plan on using the minimax algorithm to decide non-human moves. The first step in this involves generating a tree of all possible board states from a single input state. I am trying to recursively do this, but cannot seem to figure out how. (I think) I understand conceptually how this should be done, but am having trouble implementing it in lua.
I am trying to structure my tree in the following manner. Each node is a list with two fields.
{ config = {}, children = {} }
Config is a list of integers (0,1,2) that represent empty, X, and O and defines a TTT board state. Children is a list nodes which are all possible board states one move away from the current node.
Here is my function that I currently have to build the game tree
function tree_builder(board, player)
supertemp = {}
for i in ipairs(board.config) do
--iterate through the current board state.
--for each empty location create a new node
--representing a possible board state
if board.config[i] == 0 then
temp = {config = {}, children = {}}
for j in ipairs(board.config) do
temp.config[j] = board.config[j]
end
temp.config[i] = player
temp.children = tree_builder(temp, opposite(player))
supertemp[i] = temp
end
end
return supertemp
end
The function is called in the following manner:
start_board = {config = {1,0,0,0}, children = {} }
start_board.children = tree_builder(start_board, 1)
When I comment out the recursive element of the function (the line "temp.children = builder(temp, opposite(player))") and only generate the first level of children. the output is correct. When called via code that is conceptually identical to (I am using love2D so formatting is different):
for i in pairs(start_board.children) do
print (start_board.children[i].config)
The three children are:
1,1,0,0
1,0,1,0
1,0,0,1
However, once I add the recursive element, the following is output for the same three children
1,1,2,1
1,1,2,1
1,1,2,1
I have been searching online for help and most of what I have found is conceptual in nature or involves implementation in different languages. I believe I have implemented the recursive element wrongly, but cannot wrap my head around the reasons why.
Don't understand what opposite(player) means in temp.children = tree_builder(temp, opposite(player)).
Notice that a recursion need an end condition.
This is my solution under your structure:
local COL = 3
local ROW = 3
local function printBoard( b )
local output = ""
local i = 1
for _,v in ipairs(b.config) do
output = output .. v .. ( (i % COL == 0) and '\n' or ',' )
i = i + 1
end
print( output )
end
local function shallowCopy( t )
local t2 = {}
for k,v in pairs(t) do
t2[k] = v
end
return t2
end
local MAX_STEP = COL * ROW
local ING = 0
local P1 = 1
local P2 = 2
local TIE = 3
local STATUS = { [P1] = "P1 Win", [P2] = "P2 Win", [TIE] = "Tied" }
local start_board = { config = {P1,0,0,0,0,0,0,0,0}, children = {} }
local function checkIfOver( board, step )
local config = board.config
local over = false
--check rows
for i=0,ROW-1 do
over = true
for j=1,COL do
if 0 == config[i*COL+1] or config[i*COL+j] ~= config[i*COL+1] then
over = false
end
end
if over then
return config[i*COL+1]
end
end
--check cols
for i=1,COL do
over = true
for j=0,ROW-1 do
if 0 == config[i] or config[i] ~= config[i+COL*j] then
over = false
end
end
if over then
return config[i]
end
end
--check diagonals
if config[1] ~= 0 and config[1] == config[5] and config[5] == config[9] then
return config[1]
end
if config[3] ~=0 and config[3] == config[5] and config[5] == config[7] then
return config[3]
end
if step >= MAX_STEP then
return TIE
else
return ING
end
end
local function treeBuilder( board, step )
--check the game is over
local over = checkIfOver( board, step )
if over ~= ING then
printBoard( board )
print( STATUS[over], '\n---------\n' )
return
end
local child
local childCfg
for i,v in ipairs(board.config) do
if 0 == v then
child = { config = {}, children = {} }
childCfg = shallowCopy( board.config )
childCfg[i] = (step % 2 == 0) and P1 or P2
child.config = childCfg
table.insert( board.children, child )
treeBuilder( child, step + 1 )
end
end
end
treeBuilder( start_board, 1 )

Bracket finding algorithm lua?

I'm making a JSON parser and I am looking for an algorithm that can find all of the matching brackets ([]) and braces ({}) and put them into a table with the positions of the pair.
Examples of returned values:
table[x][firstPos][secondPos] = type
table[x] = {firstPos, secondPos, bracketType}
EDIT: Let parse() be the function that returns the bracket pairs. Let table be the value returned by the parse() function. Let codeString be the string containing the brackets that I want to detect. Let firstPos be the position of the first bracket in the Nth pair of brackets. Let secondPos be the position of the second bracket in the Nth pair of brackets. Let bracketType be the type of the bracket pair ("bracket" or "brace").
Example:
If you called:
table = parse(codeString)
table[N][firstPos][secondPos] would be equal to type.
Well, In plain Lua, you could do something like this, also taking into account nested brackets:
function bm(s)
local res ={}
if not s:match('%[') then
return s
end
for k in s:gmatch('%b[]') do
res[#res+1] = bm(k:sub(2,-2))
end
return res
end
Of course you can generalize this easy enough to braces, parentheses, whatever (do keep in mind the necessary escaping of [] in patterns , except behind the %b pattern).
If you're not restricted to plain Lua, you could use LPeg for more flexibility
If you are not looking for the contents of the brackets, but the locations, the recursive approach is harder to implement, since you should keep track of where you are. Easier is just walking through the string and match them while going:
function bm(s,i)
local res={}
res.par=res -- Root
local lev = 0
for loc=1,#s do
if s:sub(loc,loc) == '[' then
lev = lev+1
local t={par=res,start=loc,lev=lev} -- keep track of the parent
res[#res+1] = t -- Add to the parent
res = t -- make this the current working table
print('[',lev,loc)
elseif s:sub(loc,loc) == ']' then
lev = lev-1
if lev<0 then error('too many ]') end -- more closing than opening.
print(']',lev,loc)
res.stop=loc -- save bracket closing position
res = res.par -- revert to the parent.
end
end
return res
end
Now that you have all matched brackets, you can loop through the table, extracting all locations.
I figured out my own algorithm.
function string:findAll(query)
local firstSub = 1
local lastSub = #query
local result = {}
while lastSub <= #self do
if self:sub(firstSub, lastSub) == query then
result[#result + 1] = firstSub
end
firstSub = firstSub + 1
lastSub = lastSub + 1
end
return result
end
function string:findPair(openPos, openChar, closeChar)
local counter = 1
local closePos = openPos
while closePos <= #self do
closePos = closePos + 1
if self:sub(closePos, closePos) == openChar then
counter = counter + 1
elseif self:sub(closePos, closePos) == closeChar then
counter = counter - 1
end
if counter == 0 then
return closePos
end
end
return -1
end
function string:findBrackets(bracketType)
local openBracket = ""
local closeBracket = ""
local openBrackets = {}
local result = {}
if bracketType == "[]" then
openBracket = "["
closeBracket = "]"
elseif bracketType == "{}" then
openBracket = "{"
closeBracket = "}"
elseif bracketType == "()" then
openBracket = "("
closeBracket = ")"
elseif bracketType == "<>" then
openBracket = "<"
closeBracket = ">"
else
error("IllegalArgumentException: Invalid or unrecognized bracket type "..bracketType.."\nFunction: findBrackets()")
end
local openBrackets = self:findAll(openBracket)
if not openBrackets[1] then
return {}
end
for i, j in pairs(openBrackets) do
result[#result + 1] = {j, self:findPair(j, openBracket, closeBracket)}
end
return result
end
Will output:
5 14
6 13
7 12
8 11
9 10

Resources